00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00030
00031
00032
00033
00034 #ifdef __GNUG__
00035 #pragma implementation "MathMng.h"
00036 #endif
00037
00038
00039 #include "mc/mcprec.h"
00040 #ifdef __BORLANDC__
00041 #pragma hdrstop
00042 #endif
00043
00044 #ifndef mcPRECOMP
00045 #include <wx/dcscreen.h>
00046 #include "mc/MathMng.h"
00047 #include "mc/Monomial.h"
00048 #include "mc/Number.h"
00049 #include "mc/Symbol.h"
00050 #endif
00051
00052
00053
00054
00055 int mcMathMngHelpers::sgui_nSpaceLeftRight = 1;
00056 int mcMathMngHelpers::sgui_nSpaceAroundSeparator = 5;
00057 mcStyleArray *mcMathMngHelpers::sgui_pNormalStyles = NULL;
00058 mcStyleArray *mcMathMngHelpers::sgui_pSmallStyles = NULL;
00059 mcStyleArray *mcMathMngHelpers::sgui_pBigStyles = NULL;
00060
00061 mcMathMngCmd mcMathMngHelpers::sgui_cmd[] =
00062 {
00063 mcMathMngCmd(mcMMC_MOVE_SEL, wxT("Move the selection")),
00064 mcMathMngCmd(mcMMC_MULT_SEL, wxT("Multiply everything by this")),
00065 mcMathMngCmd(mcMMC_DIV_SEL, wxT("Divide everything by this")),
00066 mcMathMngCmd(mcMMC_ADDSUB_SEL, wxT("Add this")),
00067
00068 mcMathMngCmd(mcMMC_SIMPLIFY, wxT("Simplify selection")),
00069 mcMathMngCmd(mcMMC_EXPAND, wxT("Expand selection"))
00070 };
00071
00072
00073
00074
00075
00076
00077
00078
00079 #ifdef __MCDEBUG__
00080
00081 void mcMathMngHelpers::data_Check() const
00082 {
00083 bool leftempty = data_GetLeftMem().data_isArrayEmpty();
00084
00085
00086
00087
00088 mcASSERT(mdata_nDataType != mcMMT_EXPRESSION ||
00089 !data_GetRightMem().data_isArrayEmpty() ||
00090 leftempty,
00091 wxT("The second member is empty while it should not be"));
00092 mcUNUSED(leftempty);
00093
00094
00095 mcElementHelpers::data_Check();
00096 }
00097
00098 wxString mcMathMngHelpers::data_Debug(long flags) const
00099 {
00100 int n = mcMathCore::Get()->m_nIndentationStep;
00101 wxString str = wxT("mcMathMng [\n") + wxString(wxT(' '), n) + wxT("LEFT MEMBER - ") +
00102 data_GetLeftMem().data_GetDebug(n, flags) +
00103 wxT("\n\n") + wxString(wxT(' '), n) + wxT("RIGHT MEMBER - ") +
00104 data_GetRightMem().data_GetDebug(n, flags) +
00105 wxT("mcMathMng ]\n");
00106 return str;
00107 }
00108
00109 #endif // __MCDEBUG__
00110
00111 void mcMathMngHelpers::data_DeepCopy(const mcElementHelpers *p)
00112 {
00113 const mcMathMngHelpers *mm = (const mcMathMngHelpers *)p;
00114
00115
00116 mdata_nDataType = mm->mdata_nDataType;
00117 mgui_nCursorPos = mm->mgui_nCursorPos;
00118
00119
00120 mgui_pStyleArray = mm->mgui_pStyleArray;
00121
00122
00123 if (mm->mdata_eLMember != mcEmptyElement)
00124 mdata_eLMember.data_DeepCopy(mm->mdata_eLMember);
00125
00126 if (mm->mdata_eRMember != mcEmptyElement)
00127 mdata_eRMember.data_DeepCopy(mm->mdata_eRMember);
00128 }
00129
00130 void mcMathMngHelpers::data_SetFilter(const mcFilter *p)
00131 {
00132 mdata_eLMember.data_SetFilter(p);
00133 mdata_eRMember.data_SetFilter(p);
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 void mcMathMngHelpers::data_GetConstSourceDest(const mcPolynomialHelpers **s,
00145 const mcPolynomialHelpers **d, bool toleft) const
00146 {
00147 if (!toleft) {
00148
00149
00150 if (s) *s = mdata_eLMember.hlp();
00151 if (d) *d = mdata_eRMember.hlp();
00152
00153 } else {
00154
00155
00156 if (d) *d = mdata_eLMember.hlp();
00157 if (s) *s = mdata_eRMember.hlp();
00158 }
00159 }
00160
00161 void mcMathMngHelpers::data_SetMember(bool left, const mcPolynomial &p, mcMathMngType newtype)
00162 {
00163 if (p == mcEmptyPolynomial)
00164 return;
00165
00166
00167 if (left)
00168 data_GetLeftMem().data_DeepCopy(p.hlp());
00169 else
00170 data_GetRightMem().data_DeepCopy(p.hlp());
00171
00172
00173 mdata_nDataType = newtype;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 int mcMathMngHelpers::gui_GetXOfLeftMem() const
00185 {
00186
00187 return sgui_nSpaceLeftRight;
00188 }
00189
00190 int mcMathMngHelpers::gui_GetXOfSeparator(int yoff) const
00191 {
00192 mcUNUSED(yoff);
00193 return gui_GetXOfLeftMem()+data_GetLeftMem().gui_GetWidth()+sgui_nSpaceAroundSeparator;
00194 }
00195
00196 int mcMathMngHelpers::gui_GetXOfRightMem() const
00197 {
00198 return gui_GetXOfLeftMem()+data_GetLeftMem().gui_GetWidth()+sgui_nSpaceAroundSeparator+
00199 gui_GetSeparatorSize().GetWidth()+sgui_nSpaceAroundSeparator;
00200 }
00201
00202
00203 int mcMathMngHelpers::gui_GetYOfLeftMem() const
00204 {
00205
00206 return 0;
00207 }
00208
00209 int mcMathMngHelpers::gui_GetYOfSeparator(int yoff) const
00210 {
00211 if (yoff < 0) yoff = gui_GetYAnchor();
00212 return yoff-(gui_GetSeparatorSize().GetHeight()/2);
00213 }
00214
00215 int mcMathMngHelpers::gui_GetYOfRightMem() const
00216 {
00217 return 0;
00218 }
00219
00220 wxRect mcMathMngHelpers::gui_GetRectOfLeftMem() const
00221 {
00222 return wxRect(gui_GetXOfLeftMem(), gui_GetYOfLeftMem(),
00223 data_GetLeftMem().gui_GetWidth(), data_GetLeftMem().gui_GetHeight());
00224 }
00225
00226 wxRect mcMathMngHelpers::gui_GetRectOfRightMem() const
00227 {
00228 return wxRect(gui_GetXOfRightMem(), gui_GetYOfRightMem(),
00229 data_GetRightMem().gui_GetWidth(), data_GetRightMem().gui_GetHeight());
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 void mcMathMngHelpers::gui_InitStyles()
00249 {
00250 gui_DeleteStyles();
00251
00252
00253 sgui_pNormalStyles = new mcStyleArray(mcElementHelpers::sgui_pDefaultStyles);
00254 sgui_pSmallStyles = new mcStyleArray(sgui_pNormalStyles);
00255 sgui_pBigStyles = new mcStyleArray(sgui_pNormalStyles);
00256
00257
00258 sgui_pSmallStyles->ScaleSize(0.7f);
00259 sgui_pBigStyles->ScaleSize(2.0f);
00260 }
00261
00262 void mcMathMngHelpers::gui_DeleteStyles()
00263 {
00264 mcSAFE_DELETE(sgui_pSmallStyles);
00265 mcSAFE_DELETE(sgui_pNormalStyles);
00266 mcSAFE_DELETE(sgui_pBigStyles);
00267 }
00268
00269 int mcMathMngHelpers::gui_GetYAnchor() const
00270 {
00271 return mcMAX(data_GetLeftMem().gui_GetCenterLine(),
00272 data_GetRightMem().gui_GetCenterLine());
00273 }
00274
00275 void mcMathMngHelpers::gui_DoRecalcSize()
00276 {
00277
00278 gui_RecalcSeparatorSize();
00279
00280
00281 mgui_sz.SetHeight(mcMAX(gui_GetYOfLeftMem(), gui_GetYOfRightMem())+
00282 mcMAX(data_GetLeftMem().gui_GetHeight(), data_GetRightMem().gui_GetHeight()));
00283
00284 if (mdata_nDataType == mcMMT_EXPRESSION) {
00285
00286 mgui_sz.SetWidth(gui_GetXOfLeftMem()+data_GetLeftMem().gui_GetWidth()+
00287 sgui_nSpaceLeftRight);
00288
00289 } else {
00290
00291 mgui_sz.SetWidth(gui_GetXOfRightMem()+data_GetRightMem().gui_GetWidth()+
00292 sgui_nSpaceLeftRight);
00293 }
00294 }
00295
00296 void mcMathMngHelpers::gui_SelectSeparatorStyle(wxDC &dc) const
00297 {
00298
00299 gui_GetStyle(0)->GetSpecialTextSettings()->gui_Select(dc);
00300 }
00301
00302 void mcMathMngHelpers::gui_RecalcSeparatorSize()
00303 {
00304
00305 if (mdata_nDataType == mcMMT_EXPRESSION)
00306 return;
00307
00308
00309 wxScreenDC dc;
00310 gui_SelectSeparatorStyle(dc);
00311 mgui_szSeparator = mcElementHelpers::gui_GetSizeOf(&dc, io_GetSeparatorSymbol());
00312 }
00313
00314 void mcMathMngHelpers::gui_GetConstSelectionSourceDest(const mcPolynomialHelpers **s,
00315 const mcPolynomialHelpers **d) const
00316 {
00317
00318 if (data_GetLeftMem().gui_GetSelElemCount() > 0) {
00319
00320
00321 if (s) *s = mdata_eLMember.hlp();
00322 if (d) *d = mdata_eRMember.hlp();
00323
00324 } else {
00325
00326
00327 if (d) *d = mdata_eLMember.hlp();
00328 if (s) *s = mdata_eRMember.hlp();
00329 }
00330 }
00331
00332 int mcMathMngHelpers::gui_Draw(wxDC &hDC, int x, int y, long flags, const wxPoint &pt) const
00333 {
00334 mcGUILOG(wxT("mcMathMngHelpers::gui_Draw [%s]"), mcTXTTHIS);
00335
00336 long f1=mcDRW_ALLOW_TOTAL_SELECTION, f2=mcDRW_ALLOW_TOTAL_SELECTION;
00337 int n=-1, m, yoff;
00338
00339 flags |= mcDRW_ALLOW_TOTAL_SELECTION;
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 switch (mdata_nDataType) {
00352 case mcMMT_EXPRESSION:
00353
00354
00355 n = data_GetLeftMem().gui_Draw(hDC, x+gui_GetXOfLeftMem(),
00356 y+gui_GetYOfLeftMem(), flags, pt);
00357 break;
00358
00359 case mcMMT_EQUATION:
00360 case mcMMT_INEQUALITY_NE:
00361 case mcMMT_INEQUALITY_G:
00362 case mcMMT_INEQUALITY_GE:
00363 case mcMMT_INEQUALITY_L:
00364 case mcMMT_INEQUALITY_LE:
00365
00366
00367 if (flags & mcDRW_USEPOINT) {
00368 wxRect rc(gui_GetRectOfLeftMem());
00369 rc.Offset(x, y);
00370
00371 if (rc.Inside(pt)) {
00372 f1 |= mcDRW_USEPOINT;
00373 f2 |= mcDRW_NONACTIVE;
00374 } else {
00375 f1 |= mcDRW_NONACTIVE;
00376 f2 |= mcDRW_USEPOINT;
00377 }
00378 }
00379
00380
00381 yoff = gui_GetYAnchor();
00382
00383
00384 n = data_GetLeftMem().gui_ExDraw(hDC, x+gui_GetXOfLeftMem(),
00385 y+gui_GetYOfLeftMem(), f1, pt, yoff);
00386
00387
00388
00389 gui_SelectSeparatorStyle(hDC);
00390 hDC.DrawText(io_GetSeparatorSymbol(),
00391 x+gui_GetXOfSeparator(yoff),
00392 y+gui_GetYOfSeparator(yoff));
00393
00394
00395 m = data_GetRightMem().gui_ExDraw(hDC, x+gui_GetXOfRightMem(),
00396 y+gui_GetYOfRightMem(), f2, pt, yoff);
00397
00398
00399 if (n == -1) n = m;
00400 break;
00401
00402 default:
00403 mcASSERT(0, wxT("Invalid datatype value"));
00404 }
00405
00406 return n;
00407 }
00408
00409 mcElement &mcMathMngHelpers::gui_GetActiveElem(int x, int y, const wxPoint &pt)
00410 {
00411 wxRect rc(gui_GetRectOfLeftMem());
00412 rc.Offset(x, y);
00413 int yoff = gui_GetYAnchor();
00414
00415
00416 if (rc.Inside(pt))
00417 return data_GetLeftMem().gui_ExGetActiveElem(rc.x, rc.y, pt, yoff);
00418
00419
00420 return data_GetRightMem().gui_ExGetActiveElem(x+gui_GetXOfRightMem(),
00421 y+gui_GetYOfRightMem(), pt, yoff);
00422 }
00423
00424 mcMoveCursorRes mcMathMngHelpers::gui_MoveCursor(mcMoveCursorFlag flag, long modifiers)
00425 {
00426 mcMoveCursorRes code;
00427
00428
00429 if (mgui_nCursorPos == mcMATHMNG_LEFT)
00430 code = data_GetLeftMem().gui_MoveCursor(flag, modifiers);
00431 else
00432 code = data_GetRightMem().gui_MoveCursor(flag, modifiers);
00433
00434
00435 if (code == mcMCR_SETFOCUS_PREVIOUS) {
00436
00437 if (mgui_nCursorPos == mcMATHMNG_LEFT || mdata_nDataType == mcMMT_EXPRESSION) {
00438 return mcMCR_SETFOCUS_PREVIOUS;
00439 } else {
00440
00441
00442 data_GetLeftMem().gui_SetCursorPos(mcCP_END);
00443 mgui_nCursorPos = mcMATHMNG_LEFT;
00444 }
00445 }
00446
00447 if (code == mcMCR_SETFOCUS_NEXT) {
00448 if (mgui_nCursorPos == mcMATHMNG_RIGHT || mdata_nDataType == mcMMT_EXPRESSION) {
00449 return mcMCR_SETFOCUS_NEXT;
00450 } else {
00451
00452
00453 data_GetRightMem().gui_SetCursorPos(mcCP_BEGIN);
00454 mgui_nCursorPos = mcMATHMNG_RIGHT;
00455 }
00456 }
00457
00458 if (code == mcMCR_SETFOCUS_ABOVE || code == mcMCR_SETFOCUS_BELOW)
00459 return code;
00460 return mcMCR_OKAY;
00461 }
00462
00463 int mcMathMngHelpers::gui_MoveCursorUsingPoint(wxDC &dc, const wxPoint &p)
00464 {
00465 mcGUILOG(wxT("mcMathMngHelpers::gui_MoveCursorUsingPoint - moving to [%d;%d]"), p.x, p.y);
00466
00467
00468 wxRect rc(gui_GetRectOfLeftMem());
00469 wxPoint pt(p);
00470
00471
00472 if (rc.Inside(p)) {
00473 mgui_nCursorPos = mcMATHMNG_LEFT;
00474
00475 pt.x -= rc.x;
00476 pt.y -= rc.y;
00477 return data_GetLeftMem().gui_MoveCursorUsingPoint(dc, p);
00478 }
00479
00480 if (mdata_nDataType != mcMMT_EXPRESSION) {
00481
00482 rc.x = gui_GetXOfSeparator();
00483 rc.y = gui_GetYOfSeparator();
00484 rc.width = gui_GetSeparatorSize().GetWidth();
00485 rc.height = gui_GetSeparatorSize().GetHeight();
00486
00487
00488 if (rc.Inside(p)) {
00489
00490
00491
00492 rc.width /= 2;
00493 if (rc.Inside(p)) {
00494 mgui_nCursorPos = mcMATHMNG_LEFT;
00495 data_GetLeftMem().gui_SetCursorPos(mcCP_END);
00496 } else {
00497 mgui_nCursorPos = mcMATHMNG_RIGHT;
00498 data_GetRightMem().gui_SetCursorPos(mcCP_BEGIN);
00499 }
00500 }
00501
00502 rc = gui_GetRectOfRightMem();
00503
00504
00505 if (rc.Inside(p)) {
00506 mgui_nCursorPos = mcMATHMNG_RIGHT;
00507
00508 pt.x -= rc.x;
00509 pt.y -= rc.y;
00510 return data_GetRightMem().gui_MoveCursorUsingPoint(dc, pt);
00511 }
00512 }
00513
00514 return mcMCR_CANNOT_SETFOCUS;
00515 }
00516
00517 int mcMathMngHelpers::gui_GetRelCursorPos(wxDC &hDC, wxPoint *ptCursorPos) const
00518 {
00519 int n, yoff = -1;
00520
00521 if (mdata_nDataType != mcMMT_EXPRESSION) {
00522
00523
00524 yoff = gui_GetYAnchor();
00525 }
00526
00527 if (mgui_nCursorPos == mcMATHMNG_LEFT) {
00528
00529 n = data_GetLeftMem().gui_ExGetRelCursorPos(hDC, ptCursorPos, yoff);
00530 ptCursorPos->x += gui_GetXOfLeftMem();
00531 ptCursorPos->y += gui_GetYOfLeftMem();
00532
00533 } else {
00534
00535 n = data_GetRightMem().gui_ExGetRelCursorPos(hDC, ptCursorPos, yoff);
00536 ptCursorPos->x += gui_GetXOfRightMem();
00537 ptCursorPos->y += gui_GetYOfRightMem();
00538 }
00539
00540 return n;
00541 }
00542
00543 void mcMathMngHelpers::gui_OnSelect(wxDC &hDC, wxRect &rc)
00544 {
00545
00546 wxRect leftrc(gui_GetRectOfLeftMem());
00547 wxRect rightrc(gui_GetRectOfRightMem());
00548
00549
00550 if (leftrc.Intersects(rc)) {
00551
00552
00553 rc.Offset(-leftrc.x, -leftrc.y);
00554 data_GetLeftMem().gui_OnSelect(hDC, rc);
00555 data_GetRightMem().gui_DeSelect();
00556
00557 } else if (mdata_nDataType != mcMMT_EXPRESSION &&
00558 rightrc.Intersects(rc)) {
00559
00560
00561 rc.Offset(-rightrc.x, -rightrc.y);
00562 data_GetRightMem().gui_OnSelect(hDC, rc);
00563 data_GetLeftMem().gui_DeSelect();
00564
00565 } else {
00566
00567
00568 gui_DeSelect();
00569 return;
00570 }
00571
00572
00573
00574 if (data_GetLeftMem().gui_isSelected() ||
00575 data_GetRightMem().gui_isSelected())
00576 gui_Select();
00577 }
00578
00579 void mcMathMngHelpers::gui_SetCursorPos(const mcCursorPos &cp)
00580 {
00581 if (cp.isBegin()) {
00582
00583 data_GetLeftMem().gui_SetCursorPos(mcCP_BEGIN);
00584 mgui_nCursorPos = mcMATHMNG_LEFT;
00585
00586 } else if (cp.isEnd()) {
00587
00588
00589
00590 if (mdata_nDataType != mcMMT_EXPRESSION) {
00591 data_GetRightMem().gui_SetCursorPos(mcCP_END);
00592 mgui_nCursorPos = mcMATHMNG_RIGHT;
00593 } else {
00594 data_GetLeftMem().gui_SetCursorPos(mcCP_END);
00595 mgui_nCursorPos = mcMATHMNG_LEFT;
00596 }
00597
00598 } else {
00599
00600 mcASSERT(0, wxT("invalid flag"));
00601 }
00602 }
00603
00604 void mcMathMngHelpers::gui_GetCursorPos(mcCursorPos &cp) const
00605 {
00606 if (mgui_nCursorPos == mcMATHMNG_LEFT &&
00607 data_GetLeftMem().gui_GetCursorPos().isBegin()) {
00608 cp.gui_Push(mcCP_BEGIN);
00609 return;
00610 }
00611
00612 if (mgui_nCursorPos == mcMATHMNG_RIGHT &&
00613 data_GetRightMem().gui_GetCursorPos().isEnd()) {
00614 cp.gui_Push(mcCP_END);
00615 return;
00616 }
00617
00618 cp.gui_Push(mgui_nCursorPos);
00619 if (mgui_nCursorPos == mcMATHMNG_LEFT)
00620 data_GetLeftMem().gui_GetCursorPos(cp);
00621 else
00622 data_GetRightMem().gui_GetCursorPos(cp);
00623 }
00624
00625 mcInputRes mcMathMngHelpers::gui_Input(const mcKey &key, mcElement *)
00626 {
00627 mcMathMngType t = mcMMT_NOT_SET;
00628 mcElement p;
00629 int r;
00630
00631
00632 if (gui_isRelationalOp(key)) {
00633
00634
00635 t = math_GetMathTypeFrom(key);
00636
00637
00638 mcMathMngType old = mdata_nDataType;
00639 bool b = (t == mdata_nDataType);
00640 if (t != mcMMT_NOT_SET) mdata_nDataType = t;
00641
00642
00643 if (b && t != mcMMT_NOT_SET) {
00644
00645
00646 mcMathCore::Get()->SyntaxError(wxT("This data already contains this symbol"));
00647 return mcIR_OKAY;
00648 }
00649
00650
00651 if (old == mcMMT_EXPRESSION) {
00652
00653
00654 mgui_nCursorPos = mcMATHMNG_RIGHT;
00655 data_GetRightMem().gui_SetCursorPos(mcCP_BEGIN);
00656
00657
00658 data_GetRightMem().data_DeleteAll();
00659 data_GetRightMem().gui_AddNewEmptyMonomial();
00660 gui_RecalcSize();
00661 }
00662
00663 return mcIR_OKAY;
00664 }
00665
00666
00667 mcGUILOG(wxT("mcMathMngHelpers::gui_Input - the character to process is [%c]"), key.GetKeyCode());
00668 mcPolynomial &pmem = (mgui_nCursorPos == mcMATHMNG_LEFT) ? data_GetLeftMem() : data_GetRightMem();
00669 r = pmem.gui_Input(key, &p);
00670
00671 switch (r) {
00672 case mcIR_OKAY:
00673 break;
00674
00675 case mcIR_DELETE_PREVIOUS:
00676 case mcIR_DELETE_NEXT:
00677 if ((r == mcIR_DELETE_PREVIOUS && mgui_nCursorPos == mcMATHMNG_LEFT) ||
00678 (r == mcIR_DELETE_NEXT && mgui_nCursorPos == mcMATHMNG_RIGHT)) {
00679
00680
00681 mcMathCore::Get()->SyntaxError(wxT("Cannot delete !!"));
00682 } else {
00683
00684
00685 mdata_nDataType = mcMMT_EXPRESSION;
00686 gui_SetCursorPos(mcCP_END);
00687 }
00688 break;
00689
00690 case mcIR_DELETE_THIS:
00691 if (mgui_nCursorPos == mcMATHMNG_LEFT) {
00692
00693
00694
00695 mcMathCore::Get()->SyntaxError(wxT("Cannot delete this empty box"));
00696
00697
00698 data_GetLeftMem().gui_AddNewEmptyMonomial();
00699
00700 } else {
00701
00702
00703 mdata_nDataType = mcMMT_EXPRESSION;
00704 mgui_nCursorPos = mcMATHMNG_LEFT;
00705 data_GetLeftMem().gui_SetCursorPos(mcCP_END);
00706 }
00707 break;
00708
00709 default:
00710 mcASSERT(0, wxT("Unhandled return flag..."));
00711 }
00712
00713
00714 mcGUILOG(wxT("mcMathMngHelpers::gui_Input - after processing: [%s]"), io_GetInlinedExpr().c_str());
00715 gui_RecalcSize();
00716
00717 return mcIR_OKAY;
00718 }
00719
00720 mcInsertRes mcMathMngHelpers::gui_Insert(const mcElement &toinsert, mcElement *newelem)
00721 {
00722 switch (mgui_nCursorPos) {
00723 case mcMATHMNG_LEFT:
00724 data_GetLeftMem().gui_Insert(toinsert, NULL);
00725 break;
00726
00727 case mcMATHMNG_RIGHT:
00728 data_GetRightMem().gui_Insert(toinsert, NULL);
00729 break;
00730 }
00731
00732 return mcINSR_OKAY;
00733 }
00734
00735 mcElement mcMathMngHelpers::gui_GetSelection() const
00736 {
00737
00738
00739
00740
00741 mcMathMng res;
00742
00743 if (data_GetLeftMem().gui_isSelected()) {
00744 res.data_GetLeftMem() = data_GetLeftMem().gui_GetSelection();
00745 } else {
00746 res.data_GetRightMem() = data_GetRightMem().gui_GetSelection();
00747 }
00748
00749 return res;
00750 }
00751
00752 void mcMathMngHelpers::gui_DeleteSelection()
00753 {
00754 data_GetLeftMem().gui_DeleteSelection();
00755 data_GetRightMem().gui_DeleteSelection();
00756
00757 if (data_GetLeftMem().data_isArrayEmpty())
00758 data_GetLeftMem().gui_AddNewEmptyMonomial();
00759 if (data_GetRightMem().data_isArrayEmpty())
00760 data_GetRightMem().gui_AddNewEmptyMonomial();
00761
00762 gui_SetCursorPos(mcCP_BEGIN);
00763 gui_RecalcSize();
00764 }
00765
00766 bool mcMathMngHelpers::gui_isRelationalOp(const mcKey &key)
00767 {
00768 wxChar c = key.GetKeyCode();
00769
00770 if ((c == mcMMRO_LESS ||
00771 c == mcMMRO_GREATER ||
00772 c == mcMMRO_EQUAL) &&
00773 key.isSpecialKey())
00774 return TRUE;
00775
00776 if ((c == mcMMRO_LESS_OR_EQUAL ||
00777 c == mcMMRO_GREATER_OR_EQUAL ||
00778 c == mcMMRO_NOT_EQUAL) &&
00779 key.isSpecialKey())
00780 return TRUE;
00781
00782 return FALSE;
00783 }
00784
00785 void mcMathMngHelpers::gui_UpdateExpDepth()
00786 {
00787 data_GetLeftMem().gui_SetAtSameLevelOf(this);
00788 data_GetRightMem().gui_SetAtSameLevelOf(this);
00789
00790
00791 mcElementHelpers::gui_UpdateExpDepth();
00792 }
00793
00794
00795
00796
00797
00798
00799
00800
00801 void mcMathMngHelpers::gui_MoveSel()
00802 {
00803 mcPolynomialHelpers *psource, *pdest;
00804
00805
00806 gui_GetSelectionSourceDest(&psource, &pdest);
00807
00808
00809 if (psource->math_GetSelCount() == 1)
00810 psource->math_GetSel(0).gui_SelectAll();
00811
00812
00813 mcPolynomial sel(psource->gui_GetSelection());
00814 psource->gui_DeleteSelection();
00815
00816
00817 sel.math_ChangeAllSigns();
00818
00819
00820 pdest->math_Add(sel, NULL, TRUE);
00821
00822
00823
00824 }
00825
00826 void mcMathMngHelpers::gui_AddSubSel()
00827 {
00828 mcPolynomialHelpers *psource;
00829
00830
00831 gui_GetSelectionSourceDest(&psource, NULL);
00832
00833
00834 if (psource->math_GetSelCount() == 1)
00835 psource->math_GetSel(0).gui_SelectAll();
00836
00837
00838 mcPolynomial sel(psource->gui_GetSelection());
00839 mcPolynomial sel2(sel);
00840
00841
00842 psource->math_SimpleAdd(sel);
00843 psource->math_SimpleSubtract(sel2);
00844
00845
00846
00847 }
00848
00849 void mcMathMngHelpers::gui_MultiplyBySel(bool bDivide)
00850 {
00851 mcElement tmp;
00852
00853
00854 mcASSERT(mdata_nDataType != mcMMT_EXPRESSION, wxT("Invalid data type"));
00855
00856
00857 int n1 = data_GetLeftMem().gui_GetSelElemCount();
00858 int n2 = data_GetRightMem().gui_GetSelElemCount();
00859
00860
00861
00862
00863 if (n1)
00864 tmp = data_GetLeftMem().gui_GetSelection();
00865 else if (n2)
00866 tmp = data_GetRightMem().gui_GetSelection();
00867 else
00868 return;
00869
00870
00871
00872
00873
00874
00875
00876
00877 if (bDivide) {
00878 data_GetLeftMem().math_SimpleDivideBy(tmp);
00879 data_GetRightMem().math_SimpleDivideBy(tmp);
00880 } else {
00881 data_GetLeftMem().math_SimpleMultiplyBy(tmp);
00882 data_GetRightMem().math_SimpleMultiplyBy(tmp);
00883 }
00884
00885
00886 }
00887
00888 void mcMathMngHelpers::gui_GetPossibleOperations(mcMathMngCmdID *pCmdID) const
00889 {
00890 mcASSERT(pCmdID != NULL, wxT("invalid pointer"));
00891 switch (mdata_nDataType) {
00892
00893 case mcMMT_NOT_SET:
00894 case mcMMT_EXPRESSION:
00895
00896
00897
00898
00899 case mcMMT_EQUATION:
00900 case mcMMT_INEQUALITY_NE:
00901 case mcMMT_INEQUALITY_G:
00902 case mcMMT_INEQUALITY_GE:
00903 case mcMMT_INEQUALITY_L:
00904 case mcMMT_INEQUALITY_LE:
00905
00906 pCmdID[0] = mcMMC_SIMPLIFY;
00907 pCmdID[1] = mcMMC_EXPAND;
00908
00909 break;
00910 }
00911 }
00912
00913 wxArrayString mcMathMngHelpers::gui_GetPossibleOpOnSel(mcMathMngCmd *pCmdID) const
00914 {
00915 wxArrayString arr;
00916 wxString str;
00917
00918
00919
00920
00921
00922 mcASSERT(pCmdID != NULL, wxT("invalid pointer"));
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970 return arr;
00971 }
00972
00973 void mcMathMngHelpers::gui_ExecCmdOnSel(mcMathMngCmdID cmdid)
00974 {
00975 long flags = mcEXPSIM_NOFLAGS;
00976
00977 switch (cmdid) {
00978
00979
00980 case mcMMC_MOVE_SEL:
00981 gui_MoveSel();
00982 break;
00983 case mcMMC_MULT_SEL:
00984 gui_MultiplyBySel(FALSE);
00985 break;
00986 case mcMMC_DIV_SEL:
00987 gui_MultiplyBySel(TRUE);
00988 break;
00989 case mcMMC_ADDSUB_SEL:
00990 gui_AddSubSel();
00991 break;
00992
00993
00994 case mcMMC_SIMPLIFY:
00995 math_Simplify(flags, (mcElement *)NULL);
00996 break;
00997 case mcMMC_EXPAND:
00998 math_Expand(flags, (mcElement *)NULL);
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 break;
01010 }
01011 }
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022 wxXml2Node mcMathMngHelpers::io_GetMathML(bool bGetPresentation) const
01023 {
01024 wxString opname;
01025
01026
01027 switch (mdata_nDataType) {
01028 case mcMMT_NOT_SET:
01029 break;
01030
01031 case mcMMT_EXPRESSION:
01032 return data_GetLeftMem().io_GetMathML(bGetPresentation);
01033
01034 case mcMMT_EQUATION:
01035 case mcMMT_INEQUALITY_G:
01036 case mcMMT_INEQUALITY_L:
01037 opname = io_GetSeparatorSymbol();
01038 break;
01039
01040 case mcMMT_INEQUALITY_NE:
01041 opname = wxT("≠");
01042 break;
01043
01044 case mcMMT_INEQUALITY_GE:
01045 opname = wxT("≥");
01046 break;
01047
01048 case mcMMT_INEQUALITY_LE:
01049 opname = wxT("≤");
01050 break;
01051 }
01052
01053 wxXml2Node global, op;
01054 wxXml2Node left(data_GetLeftMem().io_GetMathML(bGetPresentation));
01055 wxXml2Node right(data_GetRightMem().io_GetMathML(bGetPresentation));
01056
01057 if (bGetPresentation) {
01058
01059
01060 global.CreateTemp(wxXML_ELEMENT_NODE, wxXml2EmptyDoc, wxT("mrow"));
01061 op.CreateTemp(wxXML_TEXT_NODE, wxXml2EmptyDoc, wxT("mo"), opname);
01062
01063 } else {
01064
01065
01066 global.CreateTemp(wxXML_ELEMENT_NODE, wxXml2EmptyDoc, wxT("apply"));
01067 op.CreateTemp(wxXML_TEXT_NODE, wxXml2EmptyDoc, wxT("EQ"));
01068 }
01069
01070
01071 global.AddChild(left);
01072 global.AddChild(op);
01073 global.AddChild(right);
01074
01075 return global;
01076 }
01077
01078 wxString mcMathMngHelpers::io_GetSeparatorSymbol(bool bUseSpecialChars) const
01079 {
01080 if (!bUseSpecialChars) {
01081 switch (mdata_nDataType) {
01082 case mcMMT_INEQUALITY_NE:
01083 return wxT("!=");
01084 case mcMMT_INEQUALITY_GE:
01085 return wxT(">=");
01086 case mcMMT_INEQUALITY_LE:
01087 return wxT("<=");
01088
01089 default:
01090 break;
01091 }
01092 }
01093
01094 if (mdata_nDataType == mcMMT_EXPRESSION)
01095 return wxEmptyString;
01096
01097
01098 wxChar sym = (wxChar)math_GetRelationalOpFor(mdata_nDataType);
01099
01100 return wxString(sym);
01101 }
01102
01103
01104
01105
01106
01107 wxString mcMathMngHelpers::io_GetInlinedExpr() const
01108 {
01109
01110 wxString res = data_GetLeftMem().io_GetInlinedExpr();
01111
01112 if (mdata_nDataType != mcMMT_EXPRESSION)
01113 res += io_GetSeparatorSymbol(FALSE) + data_GetRightMem().io_GetInlinedExpr();
01114
01115 return res;
01116 }
01117
01118 bool mcMathMngHelpers::io_ImportPresentationMathML(wxXml2Node maintag, wxString &pErr)
01119 {
01120
01121 if (maintag.GetName() == wxT("semantics"))
01122 maintag = maintag.GetChildren();
01123
01124
01125 if (maintag.GetName() != wxT("mrow")) {
01126 if (pErr) pErr = wxT("Presentation markup should be enclosed in MROW tag");
01127 return FALSE;
01128 }
01129
01130
01131
01132
01133
01134
01135 maintag.MakeLower();
01136
01137 data_GetLeftMem().io_ImportPresentationMathML(maintag, pErr);
01138
01139 return TRUE;
01140 }
01141
01142 bool mcMathMngHelpers::io_ImportInlinedExpr(const wxString &toimport, int *, wxString &perr)
01143 {
01144 wxString lmem, rmem;
01145 wxString err;
01146
01147
01148 data_GetLeftMem().data_DeleteAll();
01149 data_GetRightMem().data_DeleteAll();
01150
01151
01152 wxString str(toimport);
01153 str.Replace(wxT(" "), wxT(""));
01154 if (str.IsEmpty())
01155 return TRUE;
01156
01157
01158 if (str.Contains(wxT(">=")))
01159 mdata_nDataType = mcMMT_INEQUALITY_GE;
01160 else if (str.Contains(wxT("<=")))
01161 mdata_nDataType = mcMMT_INEQUALITY_LE;
01162 else if (str.Contains(wxT(">")))
01163 mdata_nDataType = mcMMT_INEQUALITY_G;
01164 else if (str.Contains(wxT("<")))
01165 mdata_nDataType = mcMMT_INEQUALITY_L;
01166 else if (str.Contains(wxT("!=")))
01167 mdata_nDataType = mcMMT_INEQUALITY_NE;
01168 else if (str.Contains(wxT("=")) || str.Contains(wxT("==")))
01169 mdata_nDataType = mcMMT_EQUATION;
01170 else
01171 mdata_nDataType = mcMMT_EXPRESSION;
01172
01173
01174
01175 int n = str.Len();
01176 if (mdata_nDataType != mcMMT_EXPRESSION) {
01177 int s = str.Find(io_GetSeparatorSymbol(FALSE));
01178
01179 mcASSERT(n != -1, wxT("A separator has been previously detected..."));
01180 lmem = str.Left(s);
01181
01182
01183
01184 rmem = str.Right(n-s-1);
01185
01186 } else {
01187
01188
01189 lmem = str;
01190 }
01191
01192
01193 bool b = data_GetLeftMem().io_ImportInlinedExpr(lmem, &n, err);
01194
01195
01196 if (mdata_nDataType != mcMMT_EXPRESSION) {
01197
01198 if (rmem.IsEmpty())
01199 data_GetRightMem().math_WrapNumber(0);
01200 else
01201 b &= data_GetRightMem().io_ImportInlinedExpr(rmem, &n, err);
01202 }
01203
01204
01205 if (perr) perr = err;
01206
01207 return b;
01208 }
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232 bool mcMathMngHelpers::math_Compare(const mcElement &p, long flags) const
01233 {
01234 if (!math_CompareThisOnly(p, flags))
01235 return FALSE;
01236
01237 const mcMathMng &m = (const mcMathMng &)p;
01238 if (!data_GetLeftMem().math_Compare(m.data_GetLeftMem(), flags))
01239 return FALSE;
01240 if (!data_GetRightMem().math_Compare(m.data_GetRightMem(), flags))
01241 return FALSE;
01242 return TRUE;
01243 }
01244
01245 mcMathMngRelationalOp mcMathMngHelpers::math_GetRelationalOpFor(mcMathMngType type)
01246 {
01247 switch (type) {
01248 case mcMMT_INEQUALITY_L:
01249 return mcMMRO_LESS;
01250 case mcMMT_INEQUALITY_G:
01251 return mcMMRO_GREATER;
01252 case mcMMT_EQUATION:
01253 return mcMMRO_EQUAL;
01254 case mcMMT_INEQUALITY_GE:
01255 return mcMMRO_GREATER_OR_EQUAL;
01256 case mcMMT_INEQUALITY_NE:
01257 return mcMMRO_NOT_EQUAL;
01258 case mcMMT_INEQUALITY_LE:
01259 return mcMMRO_LESS_OR_EQUAL;
01260
01261 case mcMMT_NOT_SET:
01262 case mcMMT_EXPRESSION:
01263 return (mcMathMngRelationalOp)-1;
01264 }
01265
01266 return mcMMRO_EQUAL;
01267 }
01268
01269 mcMathMngType mcMathMngHelpers::math_GetMathTypeFor(mcMathMngRelationalOp type)
01270 {
01271 switch (type) {
01272 case mcMMRO_LESS:
01273 return mcMMT_INEQUALITY_L;
01274 case mcMMRO_GREATER:
01275 return mcMMT_INEQUALITY_G;
01276 case mcMMRO_EQUAL:
01277 return mcMMT_EQUATION;
01278 case mcMMRO_GREATER_OR_EQUAL:
01279 return mcMMT_INEQUALITY_GE;
01280 case mcMMRO_NOT_EQUAL:
01281 return mcMMT_INEQUALITY_NE;
01282 case mcMMRO_LESS_OR_EQUAL:
01283 return mcMMT_INEQUALITY_LE;
01284 }
01285
01286 return mcMMT_NOT_SET;
01287 }
01288
01289 mcMathMngType mcMathMngHelpers::math_GetMathTypeFrom(const mcKey &key)
01290 {
01291
01292
01293 mcMathMngRelationalOp r = (mcMathMngRelationalOp)key.GetKeyCode();
01294
01295
01296
01297 if (!key.isSpecialKey())
01298 return mcMMT_NOT_SET;
01299
01300 return math_GetMathTypeFor(r);
01301 }
01302
01303 bool mcMathMngHelpers::math_CompareThisOnly(const mcElement &e, long flags) const
01304 {
01305 const mcMathMng &p = (const mcMathMng &)e;
01306 bool res = TRUE;
01307
01308 if (!mcElementHelpers::math_CompareThisOnly(p, flags))
01309 return FALSE;
01310
01311
01312 res &= data_GetLeftMem().math_Compare(p.data_GetLeftMem(), flags);
01313 res &= data_GetRightMem().math_Compare(p.data_GetRightMem(), flags);
01314
01315 return res;
01316 }
01317
01318 bool mcMathMngHelpers::math_ContainsInvalidSymbols() const
01319 {
01320
01321 if (data_GetLeftMem().math_ContainsInvalidSymbols() ||
01322 data_GetRightMem().math_ContainsInvalidSymbols())
01323 return TRUE;
01324 return FALSE;
01325 }
01326
01327 mcExpSimRes mcMathMngHelpers::math_Simplify(long lflags, long rflags)
01328 {
01329
01330 mcLOG(wxT("mcMathMngHelpers::math_Simplify [%s] - simplifying the left member"), mcTXT(mdata_eLMember));
01331 mcExpSimRes n1 = data_GetLeftMem().math_Simplify(lflags);
01332
01333 if (mdata_nDataType == mcMMT_EXPRESSION)
01334 return n1;
01335
01336
01337 mcLOG(wxT("mcMathMngHelpers::math_Simplify [%s] - simplifying the right member"), mcTXT(mdata_eRMember));
01338 mcExpSimRes n2 = data_GetRightMem().math_Simplify(rflags);
01339
01340
01341 if (n1 == n2 && n1 == mcESR_DONE) {
01342
01343
01344
01345
01346 }
01347
01348
01349 if (n1 == n2 && n1 == mcESR_DONE)
01350 return mcESR_DONE;
01351 return mcESR_NOTFINISHED;
01352 }
01353
01354 mcExpSimRes mcMathMngHelpers::math_Expand(long lflags, long rflags)
01355 {
01356 mcExpSimRes n1 = data_GetLeftMem().math_Expand(lflags);
01357
01358 if (mdata_nDataType != mcMMT_EXPRESSION)
01359 data_GetRightMem().math_Expand(rflags);
01360
01361
01362 return n1;
01363 }
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384 bool mcMathMngHelpers::math_isMaxSimplified() const
01385 {
01386
01387
01388 return data_GetLeftMem().math_isMaxSimplified(mcEXPSIM_NOFLAGS) &&
01389 data_GetRightMem().math_isMaxSimplified(mcEXPSIM_NOFLAGS);
01390 }
01391
01392 bool mcMathMngHelpers::math_isConstant() const
01393 {
01394 return data_GetLeftMem().math_isConstant() &&
01395 data_GetRightMem().math_isConstant();
01396 }
01397
01398 mcMathType mcMathMngHelpers::math_GetMathType() const
01399 {
01400
01401 mcMathType mt = data_GetLeftMem().math_GetMathType();
01402 switch (mdata_nDataType) {
01403
01404 case mcMMT_NOT_SET:
01405 case mcMMT_EXPRESSION:
01406 return mt;
01407
01408
01409 case mcMMT_EQUATION:
01410 case mcMMT_INEQUALITY_NE:
01411 case mcMMT_INEQUALITY_G:
01412 case mcMMT_INEQUALITY_GE:
01413 case mcMMT_INEQUALITY_L:
01414 case mcMMT_INEQUALITY_LE:
01415 mt.math_Add(data_GetRightMem().math_GetMathType());
01416 return mt;
01417 }
01418
01419
01420 mcMathType invalid(mcMTL1_NOT_RECOGNIZED,
01421 mcMTL2_NOT_RECOGNIZED, mcMTL3_NOT_RECOGNIZED);
01422 return invalid;
01423 }
01424
01425 void mcMathMngHelpers::math_Move(int mathidx, bool toleft)
01426 {
01427 mcPolynomialHelpers *s = NULL, *d = NULL;
01428 data_GetSourceDest(&s, &d, toleft);
01429
01430 mcASSERT(mathidx < s->math_GetCount(), wxT("invalid index"));
01431
01432
01433 if (s->math_Get(mathidx).math_isWrappingOnly(0.0))
01434 return;
01435
01436
01437 int sign = s->math_GetSign(mathidx);
01438
01439
01440 mcMonomial p = s->math_Get(mathidx);
01441 s->math_Remove(mathidx);
01442
01443
01444
01445 d->math_SimpleAdd(p, (sign == -1 ? TRUE : FALSE));
01446 }
01447
01448 void mcMathMngHelpers::math_MoveSymbol(const mcSymbolProperties *sym, bool toleft)
01449 {
01450 int offset = 0;
01451 mcPolynomialHelpers *s = NULL, *d = NULL;
01452 data_GetSourceDest(&s, &d, toleft);
01453
01454
01455
01456
01457
01458
01459
01460 for (int i=s->math_GetCount(); i > 0; i--) {
01461
01462
01463 if (s->math_Get(offset).math_ContainsSymbol(sym))
01464 math_Move(offset, toleft);
01465 else
01466 offset++;
01467 }
01468 }
01469
01470 void mcMathMngHelpers::math_MoveFreeFrom(const mcSymbolProperties *sym, bool toleft)
01471 {
01472 int offset = 0;
01473 mcPolynomialHelpers *s = NULL, *d = NULL;
01474 data_GetSourceDest(&s, &d, toleft);
01475
01476 for (int i=s->math_GetCount(); i > 0; i--) {
01477
01478
01479 if (!s->math_Get(offset).math_ContainsSymbol(sym))
01480 math_Move(offset, toleft);
01481 else
01482 offset++;
01483 }
01484 }
01485
01486 void mcMathMngHelpers::math_MoveSymbols(const mcSymbolArray *arr, bool toleft)
01487 {
01488 int offset = 0;
01489 mcPolynomialHelpers *s = NULL, *d = NULL;
01490 data_GetSourceDest(&s, &d, toleft);
01491
01492 for (int i=s->math_GetCount(); i > 0; i--) {
01493
01494
01495 if (s->math_Get(offset).math_ContainsOneOf(arr))
01496 math_Move(offset, toleft);
01497 else
01498 offset++;
01499 }
01500 }
01501
01502 void mcMathMngHelpers::math_MoveNonSymbol(bool toleft)
01503 {
01504 int offset = 0;
01505 mcPolynomialHelpers *s = NULL, *d = NULL;
01506 data_GetSourceDest(&s, &d, toleft);
01507
01508 for (int i=s->math_GetCount(); i > 0; i--) {
01509
01510
01511 if (!s->math_Get(offset).math_ContainsSymbols())
01512 math_Move(offset, toleft);
01513 else
01514 offset++;
01515 }
01516 }
01517
01518 void mcMathMngHelpers::math_MoveUnknowns(bool toLeft)
01519 { math_MoveSymbols(&mcSymbol::arrUnknowns, toLeft); }
01520
01521 void mcMathMngHelpers::math_MoveConstants(bool toLeft)
01522 { math_MoveSymbols(&mcSymbol::arrConstants, toLeft); }
01523
01524 void mcMathMngHelpers::math_MoveParameters(bool toLeft)
01525 { math_MoveSymbols(&mcSymbol::arrParameters, toLeft); }
01526
01527 void mcMathMngHelpers::math_MoveAll(bool toleft)
01528 {
01529 mcPolynomialHelpers *s = NULL, *d = NULL;
01530 data_GetSourceDest(&s, &d, toleft);
01531
01532
01533 for (int i=s->math_GetCount(); i > 0; i--)
01534 math_Move(0, toleft);
01535 }
01536
01537
01538
01539
01540
01541
01542
01543
01544 mcBasicOpRes mcMathMngHelpers::math_MultiplyBy(const mcElement &pol, mcElement *pp)
01545 {
01546 mcBasicOpRes r = data_GetLeftMem().math_MultiplyBy(pol, pp);
01547
01548 if (mdata_nDataType != mcMMT_EXPRESSION)
01549 data_GetRightMem().math_SimpleMultiplyBy(pol);
01550
01551 return r;
01552 }
01553
01554 mcBasicOpRes mcMathMngHelpers::math_DivideBy(const mcElement &p, mcElement *pp)
01555 {
01556
01557
01558
01559
01560
01561 mcBasicOpRes r2 = data_GetLeftMem().math_DivideBy(p, pp);
01562 r2 = data_GetRightMem().math_DivideBy(p, pp);
01563
01564 return r2;
01565 }
01566
01567 mcBasicOpRes mcMathMngHelpers::math_Add(const mcElement &p, mcElement *pp, bool add)
01568 {
01569 mcBasicOpRes r = data_GetLeftMem().math_Add(p, pp, add);
01570
01571 if (mdata_nDataType != mcMMT_EXPRESSION)
01572 data_GetRightMem().math_SimpleAdd(p, add);
01573
01574 return r;
01575 }
01576
01577 mcBasicOpRes mcMathMngHelpers::math_Subtract(const mcElement &p, mcElement *pp)
01578 {
01579 mcBasicOpRes r = data_GetLeftMem().math_Subtract(p, pp);
01580
01581 if (mdata_nDataType != mcMMT_EXPRESSION)
01582 data_GetRightMem().math_SimpleSubtract(p);
01583
01584 return r;
01585 }
01586
01587
01588
01589
01590
01591
01592
01593
01594 #define WRAP_MONOMIAL(fncname) \
01595 mcPolynomial pol; \
01596 pol.data_AddNewMonomial(mon, -1, TRUE); \
01597 fncname(pol);
01598
01599 void mcMathMngHelpers::math_MultiplyBy(const mcMonomial &mon)
01600 { WRAP_MONOMIAL(math_MultiplyBy); }
01601
01602 void mcMathMngHelpers::math_DivideBy(const mcMonomial &mon)
01603 { WRAP_MONOMIAL(math_DivideBy); }
01604
01605
01606
01607
01608
01609
01610
01611
01612 mcRealValue mcMathMngHelpers::math_Evaluate() const
01613 {
01614 mcRealValue val1 = data_GetLeftMem().math_Evaluate();
01615 if (mdata_nDataType == mcMMT_EXPRESSION) return val1;
01616
01617
01618 mcRealValue val2 = data_GetRightMem().math_Evaluate();
01619 if (val1 == *mcRealValue::pNAN || val2 == *mcRealValue::pNAN)
01620 return *mcRealValue::pNAN;
01621
01622 return val1-val2;
01623 }
01624
01625 mcRealValue mcMathMngHelpers::math_GetLenght() const
01626 {
01627 if (mdata_nDataType == mcMMT_EXPRESSION)
01628 return 0.5;
01629 if (mdata_nDataType == mcMMT_EQUATION)
01630 return 1.0;
01631
01632
01633 return 1.5;
01634 }
01635
01636 mcRealValue mcMathMngHelpers::math_GetTotalLenght() const
01637 {
01638 if (mdata_nDataType == mcMMT_EXPRESSION)
01639 return data_GetLeftMem().math_GetTotalLenght()+math_GetLenght();
01640
01641
01642 return data_GetLeftMem().math_GetTotalLenght()+
01643 data_GetRightMem().math_GetTotalLenght()+math_GetLenght();
01644 }
01645
01646 mcElement mcMathMngHelpers::math_Find(int n, const mcElement &tofind, long flags, int *pos) const
01647 {
01648 int left = data_GetLeftMem().math_GetCountOf(tofind, flags);
01649 if (left <= n) {
01650
01651 n-=left;
01652 } else {
01653
01654
01655 if (pos) *pos = 0;
01656 return data_GetLeftMem().math_Find(n, tofind, flags);
01657 }
01658
01659 if (pos) *pos = 1;
01660 return data_GetRightMem().math_Find(n, tofind, flags);
01661 }
01662
01663 int mcMathMngHelpers::math_GetCountOf(const mcElement &tocount, long flags) const
01664 {
01665 return data_GetLeftMem().math_GetCountOf(tocount, flags) +
01666 data_GetRightMem().math_GetCountOf(tocount, flags);
01667 }
01668
01669 int mcMathMngHelpers::math_Replace(const mcElement &tofind, int occ, long flags,
01670 const mcElement &replacement, bool addchildren)
01671 {
01672 int total = 0;
01673 total += data_GetLeftMem().math_Replace(tofind, occ, flags, replacement, addchildren);
01674 total += data_GetRightMem().math_Replace(tofind, occ, flags, replacement, addchildren);
01675
01676 return total;
01677 }
01678
01679 int mcMathMngHelpers::math_GetSymbolList(mcSymbol **arr, int size, const mcSymbol &tofind,
01680 bool left) const
01681 {
01682 if (left)
01683 return data_GetLeftMem().math_GetSymbolList(arr, size, tofind);
01684 return data_GetRightMem().math_GetSymbolList(arr, size, tofind);
01685 }
01686
01687 mcBasicOpRes mcMathMngHelpers::math_RaiseTo(const mcPolynomial &pol)
01688 {
01689 data_GetLeftMem().math_SimpleRaiseTo(pol);
01690 data_GetRightMem().math_SimpleRaiseTo(pol);
01691 return mcBOR_REMOVE_OPERAND;
01692 }
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718 bool mcMathMngHelpers::math_ContainsSymbol(const mcSymbolProperties *sym) const
01719 {
01720 return data_GetLeftMem().math_ContainsSymbol(sym) ||
01721 data_GetRightMem().math_ContainsSymbol(sym);
01722 }
01723
01724 mcIntegerValue mcMathMngHelpers::math_GetMaxDegreeFor(const mcSymbolProperties *sym) const
01725 {
01726 mcIntegerValue m1, m2;
01727
01728
01729 m1 = data_GetLeftMem().math_GetMaxDegreeFor(sym);
01730 m2 = data_GetRightMem().math_GetMaxDegreeFor(sym);
01731
01732
01733 if (!m1.isValid() || !m2.isValid())
01734 return *mcIntegerValue::pNAN;
01735
01736 return mcMAX(m1, m2);
01737 }
01738
01739 void mcMathMngHelpers::math_FactoreOut(const mcSymbolProperties *sym,
01740 const mcPolynomial &pol,
01741 bool bForceUseless)
01742 {
01743 mcMATHLOG(wxT("mcMathMngHelpers::math_FactoreOut [%s]"), io_GetInlinedExpr().c_str());
01744 data_GetLeftMem().math_FactoreOut(sym, pol, bForceUseless);
01745 data_GetRightMem().math_FactoreOut(sym, pol, bForceUseless);
01746 }
01747
01748 void mcMathMngHelpers::math_FactoreOutFreeOf(const mcSymbolProperties *sym,
01749 const mcPolynomial &pol,
01750 bool bForceUseless)
01751 {
01752 data_GetLeftMem().math_FactoreOutFreeOf(sym, pol, bForceUseless);
01753 data_GetRightMem().math_FactoreOutFreeOf(sym, pol, bForceUseless);
01754 }
01755
01756 void mcMathMngHelpers::math_FactoreOutAll(bool bForceUseless)
01757 {
01758 data_GetLeftMem().math_FactoreOutAll(bForceUseless);
01759 data_GetRightMem().math_FactoreOutAll(bForceUseless);
01760 }
01761
01762 bool mcMathMngHelpers::math_isFactorized() const
01763 {
01764 return data_GetLeftMem().math_isFactorized() &&
01765 data_GetRightMem().math_isFactorized();
01766 }
01767