/* * MathPlanner 3.1.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. * */ #include "Operators.h" #include "AppControl.h" #include "Error.h" #include "Function_object.h" #include "ConfigReader.h" #include "Datastore.h" #include "Object_string.h" #include "Datasymbol.h" #include "ServerHeaders.h" #include "Extern.h" // *************************************** // Sigma object // *************************************** void sigma_object::SeekObject(QPoint p) { if (Inner->Bounds().Rect().contains(p)) { Inner->SeekObject(p); return; } if (Lower->Bounds().Rect().contains(p)) { Lower->SeekObject(p); return; } if (Upper->Bounds().Rect().contains(p)) { Upper->SeekObject(p); return; } SetFocus(); } void sigma_object::Init() { Inner->SetFocus(); } void sigma_object::Build() { int ot; math_node uv; intg=NULL; // If this object is not the last one force the parenthesis on if (string->IsLastObject(this)==false) enable_par=true; Lower->Build(); Upper->Build(); Inner->Build(); ot=Lower->ObjectTypeAt(0); if (ot==OT_INTEGER_OBJECT && Lower->ObjectTypeAt(1)==OT_ASSIGN_OBJECT) { intg=(class integer_object *)Lower->ObjectAt(0); } /* else { if (Opr==0) Error_flag=true,AppControl->AddError(QObject::tr("Sigma: No integer defined")); if (Opr==1) Error_flag=true,AppControl->AddError(QObject::tr("Pii: No integer defined")); } */ uv=Upper->Calculate(); if (uv.type!=MN_REAL && Opr!=2) Error_flag=true,AppControl->AddError("Upper value must be integer"); if (Opr==0 && uv.mpl.m.R>10000) Error_flag=true,AppControl->AddError(QObject::tr("Sigma: Count is too high")); if (Opr==1 && uv.mpl.m.R>10000) Error_flag=true,AppControl->AddError(QObject::tr("Pii: Count is too high")); if (Opr==3 && uv.mpl.m.R>10000) Error_flag=true,AppControl->AddError(QObject::tr("Loop: Count is too high")); } math_node sigma_object::Calculate() { double n,i,lv,uv; math_node zero,sum,val; zero.mpl.m.R=0; zero.type=MN_REAL; integer=NULL; if (intg) { integer=intg->GetIntegerPointer(); int_no=intg->GetIntegerNo(); } else { if (Opr==2) { // If no integer defined for integral... use x integer=AppControl->integer_server->FindInteger("x",function); int_no=AppControl->integer_server->GetIntegerNo("x",function); } } if (integer) AppControl->integer_server->Protect(int_no); lv=Lower->Calculate().mpl.m.R; uv=Upper->Calculate().mpl.m.R; n=floor(uv); if (n>10000) n=10000; if (n<1) return(zero); if (Opr==0) { // SIGMA sum=Inner->Calculate(); for(i=0;i<(n-1);i++) { if (integer) (*integer).mpl.m.R+=1; sum=mpl_add(sum,Inner->Calculate()); } } if (Opr==3) { // LOOP for(i=0;iCalculate(); } } if (Opr==1) { // PII sum=Inner->Calculate(); for(i=0;i<(n-1);i++) { if (integer) (*integer).mpl.m.R+=1; sum=mpl_mul(sum,Inner->Calculate()); } } if (Opr==2) { // Integral double k=1; int count=100; double h=(uv-lv) / ( 2 * (double)count ); (*integer).mpl.m.R=lv; sum=Inner->Calculate(); for(i=0;iCalculate(),val)); (*integer).mpl.m.R=lv+2*k*h; val.SetReal(2.0); sum=mpl_add(sum,mpl_mul(Inner->Calculate(),val)); k=k+1.0; } (*integer).mpl.m.R=uv; sum=mpl_sub(sum,Inner->Calculate()); val.SetReal(h/3.0); sum=mpl_mul(sum,val); } if (integer) AppControl->integer_server->UnProtect(); value=sum; return(value); } void sigma_object::SetFontSize(int id) { Inner->SetFontSize(id); Upper->SetFontSize(id); Lower->SetFontSize(id); } void sigma_object::SendCall(int i) { Inner->SendCall(i); Upper->SendCall(i); Lower->SendCall(i); } void sigma_object::Reset() { m_base_object::Reset(); integer=NULL; int_no=0; Inner=NULL; Lower=NULL; Upper=NULL; enable_par=true; SigmaLo.Init(AppControl); ParLo.Init(AppControl); } bool sigma_object::AutoDeletion() { return(false); } void sigma_object::InsertString(str_range ran,string_object *st) { st->CopyRange(ran,AppControl->Clipboard); st->Cut(ran,true); Inner->PasteSelection(AppControl->Clipboard); SetFocus(); } sigma_object::sigma_object(DataStorage *msg) :m_base_object(msg) { Type=OT_SIGMA_OBJECT; MainType=OMT_OPERATOR; SubObject=SUB_NONE; Priority=PRIORITY_NONE; Reset(); Opr=msg->ReadInt("sio:Opr"); enable_par=(bool)msg->ReadInt("sio:ep"); DataStorage *ar=new DataStorage(); msg->ReadDataStorage("sio:Inner",ar); Inner = new string_object(ar,AppControl,function); delete ar; ar=new DataStorage(); msg->ReadDataStorage("sio:Upper",ar); Upper = new string_object(ar,AppControl,function); delete ar; ar=new DataStorage(); msg->ReadDataStorage("sio:Lower",ar); Lower = new string_object(ar,AppControl,function); delete ar; function->AddString(Inner); Inner->SetParent(this); function->AddString(Lower); Lower->SetParent(this); function->AddString(Upper); Upper->SetParent(this); Bug("function_header unarchived"); } sigma_object::~sigma_object() { delete Upper; delete Lower; delete Inner; } DataStorage *sigma_object::BuildStorage() { DataStorage *ar; DataStorage *msg=m_base_object::BuildStorage(); msg->AddInt("sio:Opr",Opr); msg->AddInt("sio:ep",enable_par); ar=Inner->BuildStorage(); msg->AddDataStorage("sio:Inner",ar); delete ar; ar=Upper->BuildStorage(); msg->AddDataStorage("sio:Upper",ar); delete ar; ar=Lower->BuildStorage(); msg->AddDataStorage("sio:Lower",ar); delete ar; return(msg); } sigma_object::sigma_object(int Op,ApplicationControl *a,m_function_object *o,class string_object *str) :m_base_object(a,o,str) { Reset(); Opr=Op; Type=OT_SIGMA_OBJECT; MainType=OMT_OPERATOR; SubObject=SUB_NONE; Priority=PRIORITY_NONE; Inner=new string_object(10,AppControl,function); Lower=new string_object(10,AppControl,function); Upper=new string_object(10,AppControl,function); function->AddString(Inner); Inner->SetParent(this); function->AddString(Lower); Lower->SetParent(this); function->AddString(Upper); Upper->SetParent(this); } void sigma_object::CalculateBounds() { layout_rect rect; int cl=AppControl->CenterLine(string); Inner->CalculateBounds(); Upper->CalculateBounds(); Lower->CalculateBounds(); if (enable_par) { ParLo.SetSize(Inner->Bounds(),0); rect=ParLo.GetOuterRect(cl,0); } else rect=Inner->Bounds(); SigmaLo.SetSize(0,rect); SigmaLo.SetSize(1,Upper->Bounds()); SigmaLo.SetSize(2,Lower->Bounds()); bounds=SigmaLo.GetOuterRect(Opr,cl); } void sigma_object::MoveTo(QPoint p) { bounds.SetPosition(p); SigmaLo.SetPosition(p); if (enable_par) { ParLo.SetPosition(SigmaLo.GetPosition(0)); Inner->MoveTo(ParLo.GetPosition()); } else Inner->MoveTo(SigmaLo.GetPosition(0)); Lower->MoveTo(SigmaLo.GetPosition(2)); Upper->MoveTo(SigmaLo.GetPosition(1)); } void sigma_object::Draw(QPainter *paint) { bool foc; SigmaLo.Draw(paint); if (enable_par) ParLo.Draw(paint); Inner->Draw(paint); Upper->Draw(paint); Lower->Draw(paint); if (HasFocus() && function->HasFocus()) { paint->setPen(focus_pen); paint->drawRect(bounds.Rect()); } foc=(HasFocus() | Inner->HasFocus() | Upper->HasFocus() | Lower->HasFocus()) & function->HasFocus(); if (Error_flag && !foc) { paint->setPen(error_pen); paint->drawRect(bounds.Rect()); } } void sigma_object::FocusNextObject() { if (curr==1) curr=2,Inner->SetFocus(); else if (curr>=2) curr=0,Upper->SetFocus(); else if (curr<=0) curr=1,Lower->SetFocus(); } void sigma_object::KeyReceived(key_code key) { // *********************** // KEY DELIVERY HANDLER // *********************** if (key.code==Qt::Key_Up && key.modifiers==0) Upper->SetFocus(),curr=0; else if (key.code==Qt::Key_Down && key.modifiers==0) Lower->SetFocus(),curr=1; else KeyFeedback(key); } void sigma_object::KeyFeedback(key_code key) { key.insert_mode=MODE_AUTO; KeyOutput(key); } void sigma_object::MessageReceived(DataStorage *msg,int rec) { if (rec==TO_OPERATOR) { if (ISMSG(MSG_REMOVE)) { Inner->CopyAll(AppControl->Clipboard); string->MarkForDeletion(string->index); string->RemoveFromString(string->index); string->ChangeIndex(-1); string->PasteSelection(AppControl->Clipboard); } if (ISMSG(MSG_DATA)) Opr=msg->ReadInt("Oper"); if (ISMSG(MSG_SIGNAL) && enable_par) enable_par=false; else if (ISMSG(MSG_SIGNAL) && !enable_par) enable_par=true; AppControl->CreateControlMenu(this); } } void sigma_mes::ReadState(m_base_object *x) { class sigma_object *t=(class sigma_object *)x; combo->setCurrentItem(t->Opr); } base_object_message *sigma_object::CreateControlObject() { Bug("########### sigma_mes created"); return(new sigma_mes(AppControl)); } sigma_mes::sigma_mes(ApplicationControl *a) :base_object_message(a) { hbox=new QHBox(); combo=new QComboBox(hbox); combo->insertItem(QString("Sigma")); combo->insertItem(QString("Pii")); combo->insertItem(QString("Integ")); combo->insertItem(QString("Loop")); but1=new QToolButton(hbox); but1->setText(tr("Remove")); but1->setAutoRaise(true); but2=new QToolButton(hbox); but2->setText(tr("Par")); but2->setAutoRaise(true); connect(but1,SIGNAL(clicked()),this,SLOT(Button())); connect(but2,SIGNAL(clicked()),this,SLOT(Button2())); connect(combo,SIGNAL(activated(int)),this,SLOT(Combo(int))); } sigma_mes::~sigma_mes() { delete but1; delete combo; delete hbox; } QWidget *sigma_mes::MainWidget() { return(hbox); } void sigma_mes::Button() { POSTMESSAGE(MSG_REMOVE,TO_OPERATOR); } void sigma_mes::Button2() { POSTMESSAGE(MSG_SIGNAL,TO_OPERATOR); } void sigma_mes::Combo(int index) { DataStorage *msg=MESSAGE(MSG_DATA); msg->AddInt("Oper",index); PostMessage(msg,TO_OPERATOR); }