/* * MathPlanner 3.0.1 - 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. * */ // *************************************** // Function defination object // *************************************** #include "Operators.h" #include "AppControl.h" #include "Error.h" #include "Function_object.h" #include "ConfigReader.h" #include "Datastore.h" #include "Object_string.h" #include "ServerHeaders.h" #include "Datasymbol.h" string_object **function_defination_object::ArgumentPointer(int i) { return(&pointer_to_string[i%3]); } void function_defination_object::SetArgumentPointer(int i,string_object *s) { pointer_to_string[i]=s; } void function_defination_object::SetArgumentValue(int i,math_node m) { if (arg_int[i]) *arg_int[i]=m; } int function_defination_object::ArgumentType(int i) { return(arg_type[i%3]); } bool function_defination_object::IsOK() { return(argument_pass); } QString function_defination_object::GetArgumentName(int i) { function_header_object *pointer_function; integer_object *io; int type; if (Inner[i]) { type=Inner[i]->ObjectTypeAt(0); if (type==OT_FUNCTION_HEADER_OBJECT) { pointer_function=(class function_header_object *)Inner[i]->ObjectAt(0); if (pointer_function) return(pointer_function->GetName()); else ErrorReport("fdo:GetArgument","Critical Error A"); } else if (type==OT_INTEGER_OBJECT) { io=(integer_object *)Inner[i]->ObjectAt(0); if (io) return(io->GetName()); else ErrorReport("fdo:GetArgument","Critical Error B"); } } return(QString("")); } QString function_defination_object::ArgumentByInteger(int i) { integer_object *io; function_header_object *pointer_function; if (Inner[i]) { if (Inner[i]->ObjectTypeAt(0)==OT_FUNCTION_HEADER_OBJECT) { pointer_function=(class function_header_object *)Inner[i]->ObjectAt(0); if (pointer_function) { io=(integer_object *)pointer_function->Inner[0]->ObjectAt(0); if (io) return(io->GetName()); else Error_flag=true,AppControl->AddError(QObject::tr("Modifier is required")); } else ErrorReport("fdo:GetArgument","Critical Error C"); } } return(QString("")); } math_node **function_defination_object::ByInteger(int i) { return(&by_int[i%3]); } void function_defination_object::SetByInteger(int i,math_node *p) { by_int[i%3]=p; } void function_defination_object::CheckPointersAndTypes() { int i; function_header_object *pointer_function; argument_pass=true; for(i=0;iObjectTypeAt(0)==OT_FUNCTION_HEADER_OBJECT) { arg_type[i]=ARG_TYPE_FUNCTION; pointer_function=(class function_header_object *)Inner[i]->ObjectAt(0); if (pointer_function) { AppControl->function_server->SetPointer(pointer_function->GetName(),true); } else ErrorReport("fdo:GetArgument","Critical Error D"); } else if (Inner[i]->ObjectTypeAt(0)==OT_INTEGER_OBJECT) { arg_type[i]=ARG_TYPE_INTEGER; QString name=GetArgumentName(i); arg_int[i]=AppControl->integer_server->FindInteger(name,function); } else { arg_type[i]=ARG_TYPE_UNDEFINED; Inner[i]->Error_flag=true; AppControl->AddError(QObject::tr("Argument is not defined correctly")); argument_pass=false; } } } void function_defination_object::Build() { int fno=-1; int i; for (i=0;i<3;i++) { arg_type[i]=ARG_TYPE_UNDEFINED; by_int[i]=NULL; pointer_to_string[i]=NULL; arg_int[i]=NULL; } function->fdo=this; if (AppControl->function_server) fno=AppControl->function_server->AddFunction(fname,Outer,this,count); if (fno!=(-1)) { CheckPointersAndTypes(); if (IsOK()) { if (Inner[0]) Inner[0]->Build(); if (count>1 && Inner[1]) Inner[1]->Build(); if (count>2 && Inner[2]) Inner[2]->Build(); Outer->Build(); // Build Inner first } } else ErrorReport("fdo:Build","Unable to add function"); } void function_defination_object::SeekObject(QPoint p) { int i; for(i=0;iBounds().Rect().contains(p)) { Inner[i]->SeekObject(p); return; } } if (Outer->Bounds().Rect().contains(p)) { Outer->SeekObject(p); return; } SetFocus(); } math_node function_defination_object::Calculate() { value.mpl.m.R=0; value.type=MN_REAL; return(value); } void function_defination_object::Reset() { int i; m_base_object::Reset(); fname=""; Inner[0]=Inner[1]=Inner[2]=Outer=NULL; Error_flag=false; StrLo.Init(AppControl); StrLoB.Init(AppControl); PoLoA.Init(AppControl); PoLoB.Init(AppControl); ParLo.Init(AppControl); AssignLo.Init(AppControl); math_node zero; zero.mpl.m.R=0; zero.type=MN_REAL; pointer=false; for(i=0;i<3;i++) { arg_type[i]=ARG_TYPE_UNDEFINED; } } void function_defination_object::SetFontSize(int i) { Outer->SetFontSize(i); if (Inner[0]) Inner[0]->SetFontSize(i); if (Inner[1]) Inner[1]->SetFontSize(i); if (Inner[2]) Inner[2]->SetFontSize(i); } bool function_defination_object::AutoDeletion() { if (HasFocus()==false && fname.isEmpty()) return(true); return(false); } /* void function_defination_object::SetFocus() { m_base_object::SetFocus(); let->focus=true; } */ function_defination_object::function_defination_object(DataStorage *msg) :m_base_object(msg) { int i; Reset(); Type=OT_FUNCTION_DEFINATION_OBJECT; MainType=OMT_OPERATOR; Priority=PRIORITY_NONE; SubObject=SUB_NONE; DataStorage *ar; fname=msg->ReadQString("fdo:Name"); count=msg->ReadInt("fdo:count"); Bug("fdo:count",count); if (msg->Contains("fdo:Inner")) { ar=new DataStorage(); msg->ReadDataStorage("fdo:Inner",ar); Inner[0]=new string_object(ar,AppControl,function); delete ar; } if (msg->Contains("fdo:Inner2")) { ar=new DataStorage(); msg->ReadDataStorage("fdo:Inner2",ar); Inner[1]=new string_object(ar,AppControl,function); delete ar; } if (msg->Contains("fdo:Inner3")) { ar=new DataStorage(); msg->ReadDataStorage("fdo:Inner3",ar); Inner[2]=new string_object(ar,AppControl,function); delete ar; } ar=new DataStorage(); msg->ReadDataStorage("fdo:Outer",ar); Outer=new string_object(ar,AppControl,function); delete ar; let=new m_display_box(bounds,&fname,20); let->SetParent(this); let->c_mode=0; let->CalculateBounds(); let->focus=true; for(i=0;iAddString(Inner[i]); Inner[i]->SetParent(this); } function->AddString(Outer); Outer->SetParent(this); Bug("function_defination unarchived"); } DataStorage *function_defination_object::BuildStorage() { DataStorage *ar; DataStorage *msg=m_base_object::BuildStorage(); msg->AddQString("fdo:Name",fname); msg->AddInt("fdo:count",count); if (Inner[0]) { ar=Inner[0]->BuildStorage(); msg->AddDataStorage("fdo:Inner",ar); delete ar; } if (Inner[1]) { ar=Inner[1]->BuildStorage(); msg->AddDataStorage("fdo:Inner2",ar); delete ar; } if (Inner[2]) { ar=Inner[2]->BuildStorage(); msg->AddDataStorage("fdo:Inner3",ar); delete ar; } ar=Outer->BuildStorage(); msg->AddDataStorage("fdo:Outer",ar); delete ar; return(msg); } function_defination_object::function_defination_object(int c,ApplicationControl *a,m_function_object *o,class string_object *str) :m_base_object(a,o,str) { int i; Reset(); Type=OT_FUNCTION_DEFINATION_OBJECT; MainType=OMT_OPERATOR; Priority=PRIORITY_NONE; SubObject=SUB_NONE; count=c; if (count>0) Inner[0]=new string_object(10,AppControl,function); if (count>1) Inner[1]=new string_object(10,AppControl,function); if (count>2) Inner[2]=new string_object(10,AppControl,function); Outer=new string_object(10,AppControl,function); let=new m_display_box(bounds,&fname,20); let->SetParent(this); let->CalculateBounds(); let->focus=true; for(i=0;iAddString(Inner[i]); Inner[i]->SetParent(this); } function->AddString(Outer); Outer->SetParent(this); } void function_defination_object::SendCall(int call) // Pass Calls to sub strings { if (Inner[0]) Inner[0]->SendCall(call); if (Inner[1]) Inner[1]->SendCall(call); if (Inner[2]) Inner[2]->SendCall(call); Outer->SendCall(call); } function_defination_object::~function_defination_object() { if (Inner[0]) delete Inner[0]; if (Inner[1]) delete Inner[1]; if (Inner[2]) delete Inner[2]; delete Outer; delete let; } QFont function_defination_object::GetFont(int id) { return(string->GetFont(FONT_TYPE_FUNCTION)); } QColor function_defination_object::GetColor(int id) { return(AppControl->GetColor(FONT_TYPE_FUNCTION)); } void function_defination_object::CalculateBounds() { int i,cl; old_bounds=bounds; Bug("fdo:CB"); let->CalculateBounds(); Outer->CalculateBounds(); for(i=0;iCalculateBounds(); } cl=AppControl->CenterLine(string); StrLo.SetSize(0,Inner[0]->Bounds()); if (count>1 && Inner[1]) { StrLo.SetSize(1,PoLoA.GetOuterRect(string->GetFont(FONT_TYPE_NORMAL),",")); StrLo.SetSize(2,Inner[1]->Bounds()); } if (count>2 && Inner[2]) { StrLo.SetSize(3,PoLoB.GetOuterRect(string->GetFont(FONT_TYPE_NORMAL),",")); StrLo.SetSize(4,Inner[2]->Bounds()); } ParLo.SetSize(StrLo.GetOuterRect(1+((count-1)*2)),0); StrLoB.SetSize(0,let->bounds); StrLoB.SetSize(1,ParLo.GetOuterRect(cl,0)); StrLoB.SetSize(2,AssignLo.GetOuterRect(string->GetFont(FONT_TYPE_NORMAL),"=")); StrLoB.SetSize(3,Outer->Bounds()); bounds=StrLoB.GetOuterRect(4); Bug("fdo:CB pass"); } void function_defination_object::MoveTo(QPoint p) { bounds.SetPosition(p); StrLoB.SetPosition(p); ParLo.SetPosition(StrLoB.GetPosition(1)); StrLo.SetPosition(ParLo.GetPosition()); if (Inner[0]) Inner[0]->MoveTo(StrLo.GetPosition(0)); if (count>1 && Inner[1]) { PoLoA.SetPosition(StrLo.GetPosition(1)); Inner[1]->MoveTo(StrLo.GetPosition(2)); } if (count>2 && Inner[2]) { PoLoB.SetPosition(StrLo.GetPosition(3)); Inner[2]->MoveTo(StrLo.GetPosition(4)); } AssignLo.SetPosition(StrLoB.GetPosition(2)); let->MoveTo(StrLoB.GetPosition(0)); Outer->MoveTo(StrLoB.GetPosition(3)); } void function_defination_object::Draw(QPainter *paint) { int i; bool foc; let->Draw(paint,HasFocus(),false); for(i=0;iDraw(paint); } Outer->Draw(paint); paint->setPen(AppControl->GetColor(FONT_TYPE_NORMAL)); paint->setFont(string->GetFont(FONT_TYPE_NORMAL)); ParLo.Draw(paint); AssignLo.Draw(paint); if (count>1) PoLoA.Draw(paint); if (count>2) PoLoB.Draw(paint); if (HasFocus() && function->HasFocus()) { paint->setPen(focus_pen); paint->drawRect(bounds.Rect()); } foc=(HasFocus() | Outer->HasFocus()) & function->HasFocus(); if (Error_flag && !foc) { paint->setPen(error_pen); paint->drawRect(bounds.Rect()); } } void function_defination_object::FocusNextObject() { if (curr<=0) Inner[0]->SetFocus(),curr=1; else if (curr==1 && Inner[1]) Inner[1]->SetFocus(),curr=2; else if (curr==2 && Inner[2]) Inner[2]->SetFocus(),curr=3; else Outer->SetFocus(),curr=0; } void function_defination_object::KeyReceived(key_code key) { // *********************** // KEY DELIVERY HANDLER // *********************** if (let->focus && (key.edit || key.spec==false)) { let->KeyReceived(key); } else KeyFeedback(key); } void function_defination_object::KeyFeedback(key_code key) { key.insert_mode=MODE_AUTO; if (let->focus) { if (let->cursor==0) key.insert_mode=MODE_ADD_LEFT; else key.insert_mode=MODE_ADD_RIGHT; } KeyOutput(key); } // *************************************** // Function header object // *************************************** QString function_header_object::GetName() { return(fname); } void function_header_object::SendCall(int call) { if (Inner[0]) Inner[0]->SendCall(call); if (Inner[1]) Inner[1]->SendCall(call); if (Inner[2]) Inner[2]->SendCall(call); } void function_header_object::SeekObject(QPoint p) { int i; for(i=0;iBounds().Rect().contains(p)) { Inner[i]->SeekObject(p); return; } } SetFocus(); } void function_header_object::Build() { int i; int_ptr=NULL; by_int[0]=by_int[1]=by_int[2]=NULL; Bug("fho:Call Build for Inner"); if (Inner[0]) Inner[0]->Build(); if (count>1 && Inner[1]) Inner[1]->Build(); if (count>2 && Inner[2]) Inner[2]->Build(); def_fdo=AppControl->function_server->GetFDO(fname); def_string=AppControl->function_server->GetString(fname); // This is a double pointer ** pointer=AppControl->function_server->GetPointer(fname); if (def_fdo==NULL) { defined=false; // if fdo is NULL this function is not yet defined AppControl->AddError(QObject::tr("Function is not defined in here")); Error_flag=true; // Do not try to calculate anything } else defined=true; if (!pointer && defined) { for(i=0;iArgumentType(i)==ARG_TYPE_FUNCTION) { QString nam=def_fdo->ArgumentByInteger(i); by_int[i]=AppControl->integer_server->GetIntegerPointer(nam,function); } } } ok=false; if (pointer && defined) { Bug("This Is a Pointer"); def_fdo=function->fdo; if (def_fdo) if (def_fdo->IsOK()) { for(i=0;iArgumentType(i)==ARG_TYPE_FUNCTION) { int_ptr=def_fdo->ByInteger(i); ok=true; } } for (i=0;iArgumentType(i)==ARG_TYPE_FUNCTION) if (def_fdo->GetArgumentName(i).compare(fname)==0) def_string=def_fdo->ArgumentPointer(i); } } Bug("Done"); } math_node function_header_object::Calculate() { int i; Bug("fho:Calculate"); if (defined && def_fdo && def_fdo->IsOK()) { if (!pointer) { Bug("fho:Calculate non pointer"); for(i=0;iArgumentType(i)==ARG_TYPE_INTEGER) { def_fdo->SetArgumentValue(i,Inner[i]->Calculate()); } else { def_fdo->SetArgumentPointer(i,Inner[i]); def_fdo->SetByInteger(i,by_int[i]); } } value=(*def_string)->Calculate(); } else if (ok && int_ptr && *int_ptr) { **int_ptr=Inner[0]->Calculate(); value=(*def_string)->Calculate(); } Bug("fho:Cal pass"); } return(value); } void function_header_object::Reset() { m_base_object::Reset(); fname=""; Inner[0]=Inner[1]=Inner[2]=NULL; Error_flag=false; curr=0; StrLo.Init(AppControl); StrLoB.Init(AppControl); PoLoA.Init(AppControl); PoLoB.Init(AppControl); ParLo.Init(AppControl); AssignLo.Init(AppControl); pointer=ok=false; def_fdo=NULL; def_string=NULL; int_no=count=(-1); int_ptr=NULL; } bool function_header_object::AutoDeletion() { if (HasFocus()==false && fname.isEmpty()) return(true); return(false); } function_header_object::function_header_object(DataStorage *msg) :m_base_object(msg) { int i; Reset(); Type=OT_FUNCTION_HEADER_OBJECT; MainType=OMT_OPERATOR; Priority=PRIORITY_NONE; SubObject=SUB_NONE; DataStorage *ar; fname=msg->ReadQString("fho:Name"); count=msg->ReadInt("fho:count"); Bug("fho:count",count); if (msg->Contains("fho:Inner")) { ar=new DataStorage(); msg->ReadDataStorage("fho:Inner",ar); Inner[0]=new string_object(ar,AppControl,function); delete ar; } if (msg->Contains("fho:Inner2")) { ar=new DataStorage(); msg->ReadDataStorage("fho:Inner2",ar); Inner[1]=new string_object(ar,AppControl,function); delete ar; } if (msg->Contains("fho:Inner3")) { ar=new DataStorage(); msg->ReadDataStorage("fho:Inner3",ar); Inner[2]=new string_object(ar,AppControl,function); delete ar; } for(i=0;iAddString(Inner[i]); Inner[i]->SetParent(this); } Bug("function_header unarchived"); } DataStorage *function_header_object::BuildStorage() { DataStorage *ar; DataStorage *msg=m_base_object::BuildStorage(); msg->AddQString("fho:Name",fname); msg->AddInt("fho:count",count); if (Inner[0]) { ar=Inner[0]->BuildStorage(); msg->AddDataStorage("fho:Inner",ar); delete ar; } if (Inner[1]) { ar=Inner[1]->BuildStorage(); msg->AddDataStorage("fho:Inner2",ar); delete ar; } if (Inner[2]) { ar=Inner[2]->BuildStorage(); msg->AddDataStorage("fho:Inner3",ar); delete ar; } return(msg); } function_header_object::function_header_object(QString na,ApplicationControl *a,m_function_object *o,class string_object *str) :m_base_object(a,o,str) { int i; Reset(); fname=na; Type=OT_FUNCTION_HEADER_OBJECT; MainType=OMT_OPERATOR; Priority=PRIORITY_NONE; SubObject=SUB_NONE; count=1; if (AppControl->function_server) { count=AppControl->function_server->GetCount(fname); } if (count>0) Inner[0]=new string_object(10,AppControl,function); if (count>1) Inner[1]=new string_object(10,AppControl,function); if (count>2) Inner[2]=new string_object(10,AppControl,function); for(i=0;iAddString(Inner[i]); Inner[i]->SetParent(this); } } void function_header_object::SetFontSize(int i) { if (Inner[0]) Inner[0]->SetFontSize(i); if (Inner[1]) Inner[1]->SetFontSize(i); if (Inner[2]) Inner[2]->SetFontSize(i); } function_header_object::~function_header_object() { if (Inner[0]) delete Inner[0]; if (Inner[1]) delete Inner[1]; if (Inner[2]) delete Inner[2]; } void function_header_object::CalculateBounds() { int i,cl; old_bounds=bounds; Bug("fho:CB"); for(i=0;iCalculateBounds(); } cl=AppControl->CenterLine(string); StrLo.SetSize(0,Inner[0]->Bounds()); if (count>1 && Inner[1]) { StrLo.SetSize(1,PoLoA.GetOuterRect(string->GetFont(FONT_TYPE_NORMAL),",")); StrLo.SetSize(2,Inner[1]->Bounds()); } if (count>2 && Inner[2]) { StrLo.SetSize(3,PoLoB.GetOuterRect(string->GetFont(FONT_TYPE_NORMAL),",")); StrLo.SetSize(4,Inner[2]->Bounds()); } ParLo.SetSize(StrLo.GetOuterRect(1+((count-1)*2)),0); StrLoB.SetSize(0,AssignLo.GetOuterRect(string->GetFont(FONT_TYPE_FUNCTION),fname)); StrLoB.SetSize(1,ParLo.GetOuterRect(cl,0)); bounds=StrLoB.GetOuterRect(2); Bug("fho:CB pass"); } void function_header_object::MoveTo(QPoint p) { bounds.SetPosition(p); StrLoB.SetPosition(p); ParLo.SetPosition(StrLoB.GetPosition(1)); StrLo.SetPosition(ParLo.GetPosition()); if (Inner[0]) Inner[0]->MoveTo(StrLo.GetPosition(0)); if (count>1 && Inner[1]) { PoLoA.SetPosition(StrLo.GetPosition(1)); Inner[1]->MoveTo(StrLo.GetPosition(2)); } if (count>2 && Inner[2]) { PoLoB.SetPosition(StrLo.GetPosition(3)); Inner[2]->MoveTo(StrLo.GetPosition(4)); } AssignLo.SetPosition(StrLoB.GetPosition(0)); } void function_header_object::Draw(QPainter *paint) { int i; bool foc; for(i=0;iDraw(paint); } paint->setPen(AppControl->GetColor(FONT_TYPE_FUNCTION)); paint->setFont(string->GetFont(FONT_TYPE_FUNCTION)); ParLo.Draw(paint); AssignLo.Draw(paint); paint->setPen(AppControl->GetColor(FONT_TYPE_NORMAL)); paint->setFont(string->GetFont(FONT_TYPE_NORMAL)); if (count>1) PoLoA.Draw(paint); if (count>2) PoLoB.Draw(paint); if (HasFocus() && function->HasFocus()) { paint->setPen(focus_pen); paint->drawRect(bounds.Rect()); } foc=HasFocus(); if (Error_flag && !foc) { paint->setPen(error_pen); paint->drawRect(bounds.Rect()); } } void function_header_object::FocusNextObject() { if (curr<=0) Inner[0]->SetFocus(),curr=1; else if (curr==1 && Inner[1]) Inner[1]->SetFocus(),curr=2; else if (Inner[2]) Inner[2]->SetFocus(),curr=0; } void function_header_object::KeyReceived(key_code key) { // *********************** // KEY DELIVERY HANDLER // *********************** if (key.code==Qt::Key_Down && key.modifiers==0 && curr==0) Inner[0]->SetFocus(),curr=1; else if (key.code==Qt::Key_Down && key.modifiers==0 && curr==1) Inner[1]->SetFocus(),curr=2; else if (key.code==Qt::Key_Down && key.modifiers==0 && curr==2) Inner[2]->SetFocus(),curr=0; else KeyFeedback(key); } void function_header_object::KeyFeedback(key_code key) { key.insert_mode=MODE_AUTO; KeyOutput(key); }