/* * MathPlanner 3.0.2 - Mathematical design tool. * Copyright(C) 2002 Jarmo Nikkanen * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation. * * You should have received a copy of the GNU General Public License with this program. * */ #include "MathHeaders.h" #include "Function_object.h" #include "Error.h" #include "ConfigReader.h" #include "Object_string.h" #include "Header.h" #include "Memory.h" #include "Paper.h" #include "Datastore.h" #include "AppControl.h" void m_function_object::SetModify() { modify=true; build=true; move=true; SendCall(CALL_MODIFY); AppControl->DocumentChanged(); } bool m_function_object::IsMainString(class string_object *str) { if (string==str) return(true); return(false); } void m_function_object::ShowValue() { show_value=!show_value; DrawRQ(); } // FOCUS CONTROL FOCUS CONTROL FOCUS CONTROL void m_function_object::UnFocusAll() { Focused_string=NULL; DrawRQ(); } void m_function_object::FocusString(string_object *str) { Focused_string=str; DrawRQ(); } string_object *m_function_object::GetFocus() { return(Focused_string); } m_base_object *m_function_object::ObjectFocus() { string_object *str=GetFocus(); if (str) return(str->GetFocus()); return(NULL); } void m_function_object::SendCall(int cal) { int i; for(i=0;iSendCall(cal); } } DataStorage *m_function_object::BuildStorage() { DataStorage *ar; DataStorage *msg=MathFrame::BuildStorage(); msg->AddInt("fo:max",max_list); msg->AddInt("fo:di",digits); msg->AddInt("fo:dim",digit_mode); msg->AddInt("fo:show",(int)show_value); msg->AddInt("fo:rat",(int)rational); msg->AddInt("fo:ans",answer_mode); ar=string->BuildStorage(); if (ar) msg->AddDataStorage("fo:main",ar,false); delete ar; return(msg); } m_function_object::m_function_object(DataStorage *msg,ApplicationControl *Aplc,Paper *pap) : MathFrame(msg,Aplc,pap) { Bug("START FUNCTION CONSTRUCTOR UNARCHIVE"); // Be careful with init. order Reset(); DataStorage *ar; max_list=msg->ReadInt("fo:max"); show_value=msg->ReadInt("fo:show"); digits=msg->ReadInt("fo:di"); digit_mode=msg->ReadInt("fo:dim"); rational=(bool)msg->ReadInt("fo:rat"); answer_mode=msg->ReadInt("fo:ans"); strings_mem=new NMemory(); AllocateSpace(max_list); if (msg->Contains("fo:main")) { Bug("UnArchive main string inside function"); ar=new DataStorage(); msg->ReadDataStorage("fo:main",ar); string=new string_object(ar,AppControl,this); AddString(string); delete ar; } else ErrorReport("FO:Constructor","No Main String"); real_display.Init(AppControl,string); imaginary_display.Init(AppControl,string); vector_display.Init(AppControl,string); MatrixLo.Init(AppControl); AssignChar.Init(AppControl); AngleLo.Init(AppControl); SetModify(); // Intialize object before calling SetModify() Bug("function_object unaschived"); } void m_function_object::Reset() { strings=NULL; Focused_string=NULL; show_value=false; empty=false; fdo=NULL; Enable(false,false,false); SetColor(QColor(0,0,255)); } m_function_object::~m_function_object() { if (paper) if (paper->GetFocus()==this) paper->UnFocusCurrentFunction(); if (string) delete string; // start deletion from main string it will delete rest delete strings_mem; Focused_string=NULL; } m_function_object::m_function_object(QPoint p,ApplicationControl *Aplc,class Paper *pap) :MathFrame(PAPER_OBJECT_FUNCTION,QRect(p.x(),p.y(),10,10),Aplc,pap) { Bug("START FUNCTION CONSTRUCTOR MANUAL"); // Be careful with init. order Reset(); digit_mode=DIGIT_MODE_AUTO; answer_mode=0; rational=Aplc->Prefs->Int("RationalByDefault"); digits=Aplc->Prefs->Int("Digits"); strings_mem=new NMemory(); AllocateSpace(20); strings_mem->Clear(); string=new string_object(10,AppControl,this); // Setup String Object for 10 sub objects AddString(string); string->CalculateBounds(); FocusString(string); real_display.Init(AppControl,string); imaginary_display.Init(AppControl,string); vector_display.Init(AppControl,string); MatrixLo.Init(AppControl); AssignChar.Init(AppControl); AngleLo.Init(AppControl); SetModify(); Bug("function constructor pass"); } void m_function_object::AllocateSpace(int c) { max_list=c; if (strings_mem) { strings_mem->SetSizeTo((c+1)*sizeof(string_object *),true); strings=(string_object **)strings_mem->Address(); if (!strings) ErrorReport("FO:AllocateSpace","Memory Error"); } } int m_function_object::AddString(string_object *obj) { int i; for(i=0;iDrawFunction(this); } void m_function_object::Draw(QPainter *paint) { if (string) { string->Draw(paint); if (show_value) { paint->setPen(AppControl->GetColor(FONT_TYPE_OPERATOR)); AssignChar.Draw(paint); if (real_dp) real_display.Draw(paint); if (complex_dp) imaginary_display.Draw(paint); if (mode!=0) AngleLo.Draw(paint); else if (vector_dp) vector_display.Draw(paint); } } MathFrame::Draw(paint); } math_node m_function_object::Calculate() { Bug("fo:: Calculate Called"); Build(); if (string) { value=string->Calculate(); return(value); } value.Clear(); return(value); } void m_function_object::Build() { Bug("fo:: Build Called"); fdo=NULL; if (build) { build=false; if (string) string->Build(); } } void m_function_object::MoveTo(QPoint p) { int i; QRect old=Bounds(); MathFrame::MoveTo(p); if (old!=Bounds() || move) { // Tarkistetaan onko objektia siirretty tai muutettu move=false; if (string) { string->MoveTo(p); p=p+QPoint(string->Bounds().width,0); } if (mode==0) { MatrixLo.SetPosition(p); i=0; AssignChar.SetPosition(MatrixLo.GetPosition(i++)); if (real_dp) real_display.SetPosition(MatrixLo.GetPosition(i++)); if (complex_dp) imaginary_display.SetPosition(MatrixLo.GetPosition(i++)); if (vector_dp) vector_display.SetPosition(MatrixLo.GetPosition(i++)); } if (mode!=0) { MatrixLo.SetPosition(p); i=0; AssignChar.SetPosition(MatrixLo.GetPosition(i++)); if (real_dp) real_display.SetPosition(MatrixLo.GetPosition(i++)); AngleLo.SetPosition(MatrixLo.GetPosition(i++)); if (complex_dp) imaginary_display.SetPosition(AngleLo.GetPosition()); } Bug("fo:: MoveTo Passed"); } } void m_function_object::CalculateBounds() { int as,de,wi,count=0; layout_rect val; bool ss=false,ok=false,first,may_have_plus; QString img,str; double v=0; if (string) empty=string->IsEmpty(); if (string && modify) { // Onko objektia muutettu modify=false; string->CalculateBounds(); SetBounds(string->Bounds().Rect(),string->Bounds().ascent); if (show_value) { wi=string->Bounds().width; as=string->Bounds().ascent; de=string->Bounds().descent; mode=answer_mode; if (value.type!=MN_COMPLEX) mode=0; if (mpl_cmodul(value.Complex())==0) mode=0; first=true; may_have_plus=true; real_dp=complex_dp=vector_dp=false; if (mode==0) { if (value.type==MN_REAL) real_dp=true; if (value.type==MN_COMPLEX) complex_dp=true,real_dp=true;; if (value.type==MN_VECTOR) vector_dp=true,real_dp=true,complex_dp=true; if (real_dp) { if (value.type==MN_REAL) ss=true,v=value.mpl.m.R,img=QString(""); if (value.type==MN_COMPLEX) ss=false,v=value.mpl.m.R,img=QString(""); if (value.type==MN_VECTOR) ss=false,v=value.mpl.m.I,img=AppControl->Prefs->String("Vector_I"); if (v<0) str=QString("-"); else if (!first && may_have_plus) str=QString("+"); v=fabs(v); if (v!=0 && first) first=false; if (v==1 && value.type==MN_VECTOR) real_display.SetValueOveride(); if (rational) ok=real_display.SetRational(v,str,img,ss); if (!rational || !ok) real_display.SetNumber(v,digits,digit_mode,str,img,ss); } if (complex_dp) { if (value.type==MN_COMPLEX) ss=false,v=value.mpl.m.I,img=AppControl->Prefs->String("ImaginaryUnit"); if (value.type==MN_VECTOR) ss=false,v=value.mpl.m.J,img=AppControl->Prefs->String("Vector_J"); if (first && value.type==MN_COMPLEX) ss=true; if (v<0) str=QString("-"); else if (!first && may_have_plus) str=QString("+"); v=fabs(v); if (v!=0 && first) first=false; if (v==1) imaginary_display.SetValueOveride(); if (rational) ok=imaginary_display.SetRational(v,str,img,ss); if (!rational || !ok) imaginary_display.SetNumber(v,digits,digit_mode,str,img,ss); } if (vector_dp) { if (value.type==MN_VECTOR) ss=false,v=value.mpl.m.K,img=AppControl->Prefs->String("Vector_K"); if (first) ss=true; if (v<0) str=QString("-"); else if (!first && may_have_plus) str=QString("+"); v=fabs(v); if (v!=0 && first) first=false; if (v==1) vector_display.SetValueOveride(); if (rational) ok=vector_display.SetRational(v,str,img,ss); if (!rational || !ok) vector_display.SetNumber(v,digits,digit_mode,str,img,ss); } count=0; MatrixLo.SetSize(count++,AssignChar.GetOuterRect(string->GetFont(FONT_TYPE_NORMAL),QString("="))); if (real_dp) MatrixLo.SetSize(count++,real_display.Bounds()); if (complex_dp) MatrixLo.SetSize(count++,imaginary_display.Bounds()); if (vector_dp) MatrixLo.SetSize(count++,vector_display.Bounds()); } if (mode==1 || mode==2) if (value.type==MN_COMPLEX) { // Do not set this mode if zero img=QString(""); v=mpl_cmodul(value.Complex()); if (v<0) str=QString("-"); else str=QString(""); v=fabs(v); if (v==1.0) real_display.SetValueOveride(); if (rational) ok=real_display.SetRational(v,str,img,true); if (!rational || !ok) real_display.SetNumber(v,digits,digit_mode,str,img,true); v=mpl_cargz(value.Complex()); if (v<0) str=QString("-"); else str=QString(""); v=fabs(v); if (mode==1) v=mpl_deg(v); if (rational) ok=imaginary_display.SetRational(v,str,img,true); if (!rational || !ok) imaginary_display.SetNumber(v,digits,digit_mode,str,img,true); AngleLo.SetSize(imaginary_display.Bounds()); MatrixLo.SetSize(0,AssignChar.GetOuterRect(string->GetFont(FONT_TYPE_NORMAL),QString("="))); MatrixLo.SetSize(1,real_display.Bounds()); MatrixLo.SetSize(2,AngleLo.GetOuterRect()); count=3; real_dp=true; complex_dp=true; } val=MatrixLo.GetOuterRect(count); if (val.ascent>as) as=val.ascent; if (val.descent>de) de=val.descent; wi+=val.width; MathFrame::SetBounds(QRect(0,0,wi,as+de),as); } // show value Bug("Function Bounds calculated"); } } // Receive Keyboard message void m_function_object::KeyReceived(key_code key) { //Pass Key Codes To Object m_base_object *Ob; string_object *string_o; Ob=ObjectFocus(); // Find Focused Object if (Ob) Ob->KeyReceived(key); // First Send It To Object else { string_o=GetFocus(); // Find Focused string if (string_o) string_o->KeyReceived(key); // And Last Send it to string object // there must always be at least one string object.. Alert error if not else ErrorReport("function_object::KeyReceived()","No Focus... NO STRING AVAILABLE"); } AutoDelete(); SetModify(); // Jos funktiolle lähetetään näppis komentoja tulkitaan se muutetuksi DrawRQ(); } void m_function_object::Selected() { DataStorage *msg=MESSAGE(MSG_STATUS); msg->AddInt("digitm",digit_mode); msg->AddInt("digits",digits); msg->AddInt("answer",answer_mode); msg->AddInt("rat",rational); PostMessage(msg,TO_MATHCONTROL); } void m_function_object::MessageReceived(DataStorage *msg,int rec) { if (rec==TO_FRAME) { TRACE if (ISMSG(MSG_STATUS)) { digit_mode=msg->ReadInt("digitm"); digits=msg->ReadInt("digits"); answer_mode=msg->ReadInt("answer"); rational=msg->ReadInt("rat"); SetModify(); DrawRQ(); } // MSG_PASTE Must Be rerouted to Paper (in Frame.cpp) else if (ISMSG(MSG_COPY)) PostMessage(msg,TO_STRING); else if (ISMSG(MSG_CUT)) PostMessage(msg,TO_STRING); else if (ISMSG(MSG_SELECTALL)) PostMessage(msg,TO_STRING); else MathFrame::MessageReceived(msg,rec); } } void m_function_object::PostMessage(DataStorage *msg,int dest) { if (dest==TO_STRING && GetFocus()) { GetFocus()->MessageReceived(msg,dest); SetModify(); DrawRQ(); } else if (dest==TO_OPERATOR && ObjectFocus()) { ObjectFocus()->MessageReceived(msg,dest); SetModify(); DrawRQ(); } else MathFrame::PostMessage(msg,dest); } void m_function_object::AutoDelete() { int i; for(i=0;iAutoOperations(); strings[i]->DeleteMarked(); } } } void m_function_object::MousePressed(QPoint p) { if (string) string->SeekObject(p); AutoDelete(); SetModify(); DrawRQ(); }