00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00031 
00032 
00033 
00034 #ifndef EXPELEMENT_H
00035 #define EXPELEMENT_H
00036 
00037 
00038 #ifdef __GNUG__
00039 #pragma interface "ExpElement.h"
00040 #endif
00041 
00042 
00043 #include "mc/Element.h"
00044 #include "mc/Polynomial.h"
00045 #include "mc/Text.h"
00046 
00047 
00048 
00049 mcDEFINE_HELPER_CLASSES(mcExpElement)
00050 
00051 
00052 
00053 
00054 
00055 enum mcExpElemCursorLocation {
00056 
00063  mcECL_EXPONENTBEGIN,
00064 
00071  mcECL_INSIDEEXPONENT,
00072  
00079  mcECL_EXPONENTEND,
00080 
00087  mcECL_SUBSCRIPTBEGIN,
00088 
00093  mcECL_INSIDESUBSCRIPT,
00094 
00101  mcECL_SUBSCRIPTEND,
00102 
00110  mcECL_INSIDEBASE
00111 };
00112 
00113 
00114 
00118 #define mcECL_NOTINSIDEEXPONENT  0x77777777
00119 
00121 #define mcECL_NOTINSIDESUBSCRIPT 0x88888888
00122 
00123 
00124 
00125 
00129 
00130 inline int mcEP_HAS(bool exp)
00131 { return (exp ? mcEP_HASEXPONENT : mcEP_HASSUBSCRIPT); }
00132 
00133 inline mcExpElemCursorLocation mcECL_BEGIN(bool exp)
00134 { return (exp ? mcECL_EXPONENTBEGIN : mcECL_SUBSCRIPTBEGIN); }
00135 
00136 inline mcExpElemCursorLocation mcECL_INSIDE(bool exp)
00137 { return (exp ? mcECL_INSIDEEXPONENT : mcECL_INSIDESUBSCRIPT); }
00138 
00139 inline mcExpElemCursorLocation mcECL_END(bool exp)
00140 { return (exp ? mcECL_EXPONENTEND : mcECL_SUBSCRIPTEND); }
00141 
00142 inline mcKey *mcGetEditKey(bool exp)
00143 { return (exp ? mcMathCore::Get()->m_pEditExpKey : 
00144    mcMathCore::Get()->m_pEditSubscriptKey); }
00145 
00146 inline int mcNotInside(bool exp)
00147 { return (exp ? mcECL_NOTINSIDEEXPONENT : mcECL_NOTINSIDESUBSCRIPT); }
00148 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00161 class mcExpElementHelpers : public mcElementHelpers
00162 {
00163 #ifdef mcENABLE_DATA
00164 protected:  
00165 
00171  mcElement mdata_pExp;
00172 
00178  mcElement mdata_pSub;
00179 
00182  bool mdata_bExpEnabled;
00183 
00186  bool mdata_bSubEnabled;
00187 
00188 #endif
00189 
00190 
00191 #ifdef mcENABLE_GUI
00192 protected:  
00193 
00198  bool mgui_bExpRight;
00199 
00202  bool mgui_bSubRight;
00203  
00207  wxSize mgui_szBase;
00208 
00212  
00213  mcExpElemCursorLocation mgui_nCursorLoc;
00214 
00215 #endif
00216 
00217 
00218 #ifdef mcENABLE_MATH
00219 public:   
00220 
00224  static bool smath_bConvertToRadicalWhenPossible;
00225 
00226 #endif
00227 
00228 
00229 public:
00230 
00231  mcExpElementHelpers() : mdata_pExp(NULL), mdata_pSub(NULL) {  
00232   
00233   mdata_bExpEnabled = mdata_bSubEnabled = TRUE;
00234  }
00235 
00236  virtual ~mcExpElementHelpers() {
00237   data_DestroyExpSub(TRUE);
00238   data_DestroyExpSub(FALSE);
00239  }
00240 
00241 protected:
00242 
00243  void gui_Init() {
00244   mcElementHelpers::gui_Init();
00245 
00246   
00247   mgui_nCursorLoc = mcECL_INSIDEBASE;  
00248   mgui_bExpRight = mgui_bSubRight = TRUE;
00249  }
00250 
00251 
00252 
00253 
00254 #ifdef mcENABLE_DATA
00255 public:
00256 
00257 #ifdef __MCDEBUG__
00258 
00259  void data_Check() const;
00260 
00263  virtual wxString data_Debug(long flags) const;
00264 
00267  virtual wxString data_BaseDebug(long flags) const  { return wxT("invalid"); }
00268  
00270  wxString data_ExpDebug(long flags) const;
00271 
00273  wxString data_SubDebug(long flags) const;
00274 
00275 #endif
00276 
00277  int data_GetChildrenCount() const {
00278   int b1 = data_GetExp() != NULL;
00279   int b2 = data_GetSub() != NULL;
00280   return mcElementHelpers::data_GetChildrenCount() + b1 + b2;
00281  }
00282 
00283  const mcElement &data_GetConstChild(int n) const {
00284   mcRETURN_ELEMENT_CHILD(n, mcElementHelpers);
00285   bool b1 = data_GetExp() != NULL;
00286   bool b2 = data_GetSub() != NULL;
00287   
00288   if (b1 && n == 0)
00289    return data_GetExp();
00290   if (b2 && (n == 0 || n == 1))
00291    return data_GetSub();
00292 
00293   return mcEmptyElement;
00294  }
00295  
00296  void data_SetChild(int n, const mcElement &newchild) {
00297   mcSET_ELEMENT_CHILD(n, mcElementHelpers, newchild);
00298   bool b1 = data_GetExp() != NULL;
00299   bool b2 = data_GetSub() != NULL;
00300 
00301   if (b1 && n == 0)
00302    data_SetExpSub(TRUE, newchild);
00303   if (b2 && (n == 0 || n == 1))
00304    data_SetExpSub(FALSE, newchild);
00305   }
00306 
00307 
00311  void data_DeepCopy(const mcElementHelpers *p);
00312 
00315  void data_DeepCopyExpSub(bool exp, const mcExpElementHelpers *);
00316  
00321  virtual void data_CreateExpSub(bool exp);
00322  
00325  virtual void data_DestroyExpSub(bool exp);
00326 
00328  mcElement &data_GetExp()        { return mdata_pExp; }
00329  const mcElement &data_GetExp() const     { return mdata_pExp; }
00330 
00332  mcElement &data_GetSub()        { return mdata_pSub; } 
00333  const mcElement &data_GetSub() const     { return mdata_pSub; } 
00334 
00335  mcElement &data_Get(bool bExp)
00336   { return (bExp ? mdata_pExp : mdata_pSub); }
00337  const mcElement &data_Get(bool bExp) const
00338   { return (bExp ? mdata_pExp : mdata_pSub); }
00339 
00341  virtual void data_SetExpSub(bool exp, const mcElement &p);
00342 
00343 #endif  // mcENABLE_DATA
00344 
00345 
00346 
00347 
00348 
00349 #ifdef mcENABLE_GUI
00350 public:
00351 
00357 
00361  bool gui_isExpSubEndKey(bool, const mcKey &) const;
00362  
00363 
00364  bool gui_isExpSubEndKeyHelper(bool exp, const mcKey &ev) const;
00365  
00368  int gui_ExpSubDraw(bool, wxDC &, int, int, long flags, const wxPoint &) const;
00369  
00370  
00373  
00374 
00375 
00376 
00377  wxSize gui_GetExpSubSize(bool);
00378  wxSize gui_GetExpSubSize(bool) const;
00379  
00381  void gui_RecalcExpSubSize(bool);
00382  
00383  
00385  virtual int gui_GetExpSubOffsety(bool) const;
00386  
00389  
00390 
00395  virtual int gui_GetExpSubOffsetx(bool) const;
00396  
00397  
00401  virtual int gui_GetExpSubRelCursorPos(bool, wxDC &, wxPoint *) const;
00402  
00403  
00407  virtual mcMoveCursorRes gui_ExpSubMoveCursor(bool, mcMoveCursorFlag, long);
00408  
00409 
00410  int gui_ExpSubMoveCursorUsingPoint(bool, wxDC &dc, const wxPoint &p);
00411  
00412  
00415  void gui_GetExpSubCursorPos(bool, mcCursorPos &) const; 
00416  
00417  
00421  void gui_SetExpSubCursorPos(bool, const mcCursorPos &code);
00422 
00424  
00425  
00429  virtual mcInputRes gui_ExpSubInput(bool, const mcKey &ev, mcElement *pnew);
00430  
00431  
00437  void gui_EditExpSub(bool);
00438  
00439  
00441  void gui_DeleteExpSub(bool);
00442  
00443  
00448  virtual void gui_CheckExpSub(bool);
00449  
00450 
00452  virtual void gui_CreateExpSub(bool);
00454  
00456 
00457 
00458 
00459 
00467  
00475  virtual bool gui_isBaseEndKey(const mcKey &ev) const = 0;
00476  
00493  virtual int gui_DrawBase(wxDC &dc, int x, int y, long flags, 
00494         const wxPoint &pt) const = 0;
00495  
00499  virtual void gui_DoRecalcBaseSize() = 0;
00500  
00507  virtual void gui_SetBaseCursorPos(const mcCursorPos &) = 0;
00508  
00512  virtual void gui_EditBase() = 0;
00513  
00516  virtual void gui_EditBaseAndSetPos(const mcCursorPos &cp);
00517  
00520  virtual void gui_GetBaseCursorPos(mcCursorPos &) const = 0;
00521 
00522  virtual mcCursorPos gui_GetBaseCursorPos() const
00523   { mcCursorPos ret; gui_GetBaseCursorPos(ret); return ret; }
00524  
00528  virtual mcInputRes gui_BaseInput(const mcKey &ev, mcElement *pnew) = 0;
00529  
00530  virtual mcInsertRes gui_BaseInsert(const mcElement &, mcElement *) = 0;
00531 
00540  virtual mcMoveCursorRes gui_BaseMoveCursor(mcMoveCursorFlag, long modifiers) = 0; 
00541 
00544  virtual int gui_BaseMoveCursorUsingPoint(wxDC &, const wxPoint &) = 0;
00545  
00549  virtual int gui_GetBaseRelCursorPos(wxDC &, wxPoint *) const = 0;
00550 
00566  virtual bool gui_DrawAsActiveOverBase() const = 0;
00567 
00570  virtual int gui_GetBaseOffsety() const;
00571 
00574  virtual int gui_GetBaseOffsetx() const;
00575   
00579  virtual wxSize gui_GetBaseSize() { 
00580   if (mgui_szBase.GetWidth() == 0)
00581    gui_DoRecalcBaseSize();
00582   return mgui_szBase;
00583  }
00584 
00587  virtual wxSize gui_GetBaseSize() const  { return mgui_szBase; }
00588 
00595  virtual void gui_OnBaseSelect(wxDC &dc, wxRect &rc) {
00596   gui_SelectAll();
00597  }
00598 
00603  virtual bool gui_hasBaseSthOnRightSide() const;
00604 
00608  virtual bool gui_hasBaseSthOnLeftSide() const;
00609 
00611  virtual bool gui_isOnRight(bool exp) const
00612   { return (exp ? mgui_bExpRight : mgui_bSubRight); }
00613 
00615  virtual mcElement gui_GetBaseSelection() const
00616   { return mcEmptyElement; }
00617 
00619  
00620 
00621 
00622 
00623 
00628 
00633  int gui_HandleSubExpEditKeys(const mcKey &ev);
00634 
00638  wxSize gui_GetBaseAndSubSize() const;
00639  
00641  virtual void gui_DrawNonActive(wxDC &dc, wxPoint &base, 
00642          wxPoint &exp, wxPoint &sub) const;
00643  
00647  virtual void gui_DrawActivationRect(wxDC &dc, int x, int y) const;
00648 
00656  virtual void gui_DrawAllActive(wxDC &dc, wxPoint &orig, wxPoint &base, 
00657   wxPoint &exp, wxPoint &sub) const;
00658  
00664  bool gui_isCursorInExpSub(bool, bool bCheckBeginEndExp = TRUE) const;
00665 
00667  
00668 
00670  bool gui_isCursorInBase() const;
00671 
00673 
00674 
00675 
00676 
00677 
00685 
00686  virtual mcMoveCursorRes gui_MoveCursor(mcMoveCursorFlag flag, long modifiers);
00687  virtual mcInputRes gui_Input(const mcKey &ev, mcElement *newelem);
00688  virtual mcInsertRes gui_Insert(const mcElement &, mcElement *);
00689  virtual void gui_GetCursorPos(mcCursorPos &) const;
00690 
00691  virtual void gui_OnSelect(wxDC &dc, wxRect &rc); 
00692  virtual void gui_SetCursorPos(const mcCursorPos &code);
00693  virtual void gui_DoRecalcSize();
00694  virtual void gui_UpdateExpDepth();
00695 
00696  virtual int gui_Draw(wxDC &dc, int x, int y, long flags, const wxPoint &pt) const;
00697  virtual int gui_GetRelCursorPos(wxDC &dc, wxPoint *pt) const;
00698  virtual int gui_MoveCursorUsingPoint(wxDC &dc, const wxPoint &p);
00699  virtual int gui_GetYAnchor() const;
00700 
00701  virtual bool gui_isEndKey(const mcKey &ev) const;
00702  virtual mcElement gui_GetSelection() const;
00703 
00705 
00706 #endif  // mcENABLE_GUI
00707 
00708 
00709 
00710 
00711 
00712 #ifdef mcENABLE_MATH
00713 protected:
00714 
00721  mcExpSimRes math_SimplifyExp(long flags, mcElement *);
00722 
00723 public:
00724 
00726  bool math_hasExp() const;
00727  bool math_hasSub() const;
00728 
00734 
00735 
00743  const mcPolynomial &math_GetConstExp() const;
00744  mcPolynomial &math_GetExp();
00745  const mcPolynomial &math_GetExp() const
00746   { return math_GetConstExp(); } 
00747 
00748  
00750  mcText &math_GetSub() const
00751   { return (mcText &)(data_GetSub()); }
00752  const mcText &math_GetConstSub() const;  
00753 
00754 
00755  void math_SetExp(const mcPolynomial &pol)
00756   { data_SetExpSub(TRUE, pol); }
00757 
00758  mcBasicOpRes math_RaiseTo(const mcPolynomial &p);
00759 
00760  mcRealValue math_EvaluateExp() const;
00761  bool math_CompareExp(const mcExpElement &, long flags) const;
00762  bool math_CompareSub(const mcExpElement &, long flags) const;
00763  mcBasicOpRes math_MultOrDiv(const mcElement &, mcElement *, bool mult);
00764  
00765  
00766 
00770 
00771  
00772  virtual bool math_Compare(const mcElement &p, long flags) const;
00773  
00782  mcRealValue math_GetLenght() const 
00783   { mcRealValue l=math_GetBaseLenght(); return (math_hasExp() ? l+0.5 : l); }
00784  
00785  virtual mcRealValue math_Evaluate() const;
00786  virtual mcBasicOpRes math_MakeReciprocal(mcElement *);
00787 
00788  virtual mcBasicOpRes math_MultiplyBy(const mcElement &, mcElement *);
00789  virtual mcBasicOpRes math_DivideBy(const mcElement &, mcElement *);
00790  
00791  virtual mcExpSimRes math_Simplify(long flags, mcElement *newelem);
00792  virtual mcExpSimRes math_Expand(long flags, mcElement *newelem);
00793 
00794  virtual mcMathType math_GetMathType() const;
00795 
00797 
00798 
00799 
00803  
00804  virtual mcMathType math_GetBaseMathType() const = 0;
00805 
00806  virtual mcRealValue math_GetBaseLenght() const { return 0; }
00807  virtual mcRealValue math_EvaluateBase() const = 0;
00808 
00809  virtual mcExpSimRes math_ExpandBase(long flags, mcElement *newelem) = 0;
00810 
00811  virtual mcExpSimRes math_SimplifyBase(long flags, mcElement *newelem) = 0;
00812  virtual mcExpSimRes math_SimplifyBaseExp(long flags, mcElement *pnew) { return mcESR_DONE; }
00813 
00814  virtual mcBasicOpRes math_MultiplyBaseOnlyBy(const mcElement &, mcElement *) = 0;
00815  virtual mcBasicOpRes math_DivideBaseOnlyBy(const mcElement &, mcElement *) = 0;
00816 
00817  virtual mcBasicOpRes math_MultiplyBaseBy(const mcElement &, mcElement *)
00818   { return mcBOR_REMOVE_OPERAND; }
00819  virtual mcBasicOpRes math_DivideBaseBy(const mcElement &, mcElement *) 
00820   { return mcBOR_REMOVE_OPERAND; }
00821 
00822  mcMonomial math_GetLCM(const mcElement &) const;
00823  mcMonomial math_GetGCD(const mcElement &) const;
00824 
00825  virtual mcMonomial math_GetBaseLCM(const mcElement &p) const;
00826  virtual mcMonomial math_GetBaseGCD(const mcElement &p) const;
00827 
00829 
00830 
00831 #endif  // mcENABLE_MATH
00832 
00833 
00834 
00835 
00836 #ifdef mcENABLE_IO
00837 public:
00838 
00844  virtual wxXml2Node io_GetBaseMathML(bool bGetPresentation) const = 0;
00845 
00848  virtual wxXml2Node io_GetMathML(bool bGetPresentation) const;
00849 
00850  virtual wxString io_GetInlinedExpr() const;
00851  virtual wxString io_GetBaseInlinedExpr() const = 0;
00852  
00853  
00854 
00855 
00856 
00857 
00858 
00859 
00860 
00861 
00862 
00863 
00864 
00865 
00866 
00867 
00868 
00869 
00870 
00871 
00872 
00873 
00874  static bool io_ImportExpSub(const wxString &str, int *count, wxString &pErr);
00875 
00876  virtual bool io_ImportInlinedExpr(const wxString &str, int *count, wxString &pErr);
00877  virtual bool io_ImportBaseInlinedExpr(const wxString &, int *, wxString &) = 0;
00878 
00881  static void io_GetExpSubInlinedToken(wxString &subexp);
00882 
00883 #endif  // mcENABLE_IO
00884 };
00885 
00886 
00893 class mcExpElement : public mcElement
00894 {
00895  mcDEFINE_ABSTRACT_CLASS(ExpElement, mcElement);
00896 
00897 public:
00898 
00899  bool data_isValidContainerFor(mcElementType t) const
00900   { return t == mcET_SYMBOL || t == mcET_NUMBER ||
00901     t == mcET_FUNCTION || t == mcET_BRACKET ||
00902     t == mcET_RADICAL; }
00903 
00904 #ifdef mcENABLE_DATA
00905 public:
00906 
00907  mcWRAPPER mcElement &data_GetExp()     { return hlp()->data_GetExp(); }
00908  mcWRAPPER const mcElement &data_GetExp() const  { return hlp()->data_GetExp(); }
00909 
00910  mcWRAPPER mcElement &data_GetSub()     { return hlp()->data_GetSub(); } 
00911  mcWRAPPER const mcElement &data_GetSub() const  { return hlp()->data_GetSub(); } 
00912  
00913  mcWRAPPER void data_SetExpSub(bool exp, const mcElement &p)
00914   { hlp()->data_SetExpSub(exp, p); }
00915  mcWRAPPER void data_DestroyExpSub(bool exp)
00916   { hlp()->data_DestroyExpSub(exp); }
00917  mcWRAPPER void data_CreateExpSub(bool exp)
00918   { hlp()->data_CreateExpSub(exp); }
00919 
00920 #endif
00921 
00922 
00923 #ifdef mcENABLE_MATH
00924 public:
00925 
00926  mcWRAPPER bool math_hasExp() const
00927   { return hlp()->math_hasExp(); }
00928  mcWRAPPER bool math_hasSub() const
00929   { return hlp()->math_hasSub(); }
00930 
00931  mcWRAPPER mcPolynomial &math_GetExp()
00932   { return hlp()->math_GetExp(); }
00933  mcWRAPPER const mcPolynomial &math_GetConstExp() const
00934   { return hlp()->math_GetConstExp(); }
00935 
00936  mcWRAPPER mcText &math_GetSub() 
00937   { return hlp()->math_GetSub(); }
00938  mcWRAPPER const mcText &math_GetSub() const 
00939   { return hlp()->math_GetSub(); }
00940 #endif
00941 };
00942 
00943 
00944 #endif // EXPELEMENT_H
00945