00001 00002 // MathCore = a WYSIWYG equation editor + a powerful math engine // 00003 // Copyright (C) 2003 by Francesco Montorsi // 00004 // // 00005 // This library is free software; you can redistribute it and/or // 00006 // modify it under the terms of the GNU Lesser General Public // 00007 // License as published by the Free Software Foundation; either // 00008 // version 2.1 of the License, or (at your option) any later // 00009 // version. // 00010 // // 00011 // This library is distributed in the hope that it will be useful, // 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of // 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // 00014 // GNU Lesser General Public License for more details. // 00015 // // 00016 // You should have received a copy of the GNU Lesser General Public // 00017 // License along with this program; if not, write to the Free // 00018 // Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, // 00019 // MA 02111-1307, USA. // 00020 // // 00021 // For any comment, suggestion or feature request, please contact // 00022 // the administrator of the project at frm@users.sourceforge.net // 00023 // // 00031 00032 00033 00034 #ifndef EXPELEMENT_H 00035 #define EXPELEMENT_H 00036 00037 // optimization for GCC compiler 00038 #ifdef __GNUG__ 00039 #pragma interface "ExpElement.h" 00040 #endif 00041 00042 // required includes 00043 #include "mc/Element.h" 00044 #include "mc/Polynomial.h" 00045 #include "mc/Text.h" 00046 00047 00048 // this defines all the classes declared in this header file 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: // DATA variables 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: // GUI variables 00193 00198 bool mgui_bExpRight; 00199 00202 bool mgui_bSubRight; 00203 00207 wxSize mgui_szBase; 00208 00212 //int mgui_nCursorPos; 00213 mcExpElemCursorLocation mgui_nCursorLoc; 00214 00215 #endif 00216 00217 00218 #ifdef mcENABLE_MATH 00219 public: // customizable variables 00220 00224 static bool smath_bConvertToRadicalWhenPossible; 00225 00226 #endif 00227 00228 00229 public: 00230 00231 mcExpElementHelpers() : mdata_pExp(NULL), mdata_pSub(NULL) { 00232 // exponent & subscribt do not exist yet... 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 // this value can be changed by derived classes' constructors 00247 mgui_nCursorLoc = mcECL_INSIDEBASE; // default: not inside exponent nor subscript 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 //bool gui_isSubEndKey(const mcKey &) const; //!< See #gui_isExpEndKey 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 //int gui_DrawSub(wxDC &, int, int, long flags, const wxPoint &) const; //!< See #gui_DrawExp. 00370 00373 /*wxSize gui_GetExpSize(); 00374 wxSize gui_GetSubSize(); //!< See #gui_GetExpSize. 00375 wxSize gui_GetExpSize() const; 00376 wxSize gui_GetSubSize() const;*/ 00377 wxSize gui_GetExpSubSize(bool); 00378 wxSize gui_GetExpSubSize(bool) const; 00379 00381 void gui_RecalcExpSubSize(bool); 00382 //void gui_RecalcSubSize(); //!< See #gui_RecalcExpSize. 00383 00385 virtual int gui_GetExpSubOffsety(bool) const; 00386 00389 //virtual int gui_GetSubOffsety() const; 00390 00395 virtual int gui_GetExpSubOffsetx(bool) const; 00396 //virtual int gui_GetSubOffsetx() const; //!< See #gui_GetExpOffsetx. 00397 00401 virtual int gui_GetExpSubRelCursorPos(bool, wxDC &, wxPoint *) const; 00402 //virtual int gui_GetSubRelCursorPos(wxDC &, wxPoint *) const; //!< See #gui_GetExpRelCursorPos. 00403 00407 virtual mcMoveCursorRes gui_ExpSubMoveCursor(bool, mcMoveCursorFlag, long); 00408 //virtual mcMoveCursorRes gui_SubMoveCursor(mcMoveCursorFlag, long); //!< See #gui_ExpMoveCursor. 00409 00410 int gui_ExpSubMoveCursorUsingPoint(bool, wxDC &dc, const wxPoint &p); 00411 //int gui_SubMoveCursorUsingPoint(wxDC &dc, const wxPoint &p); 00412 00415 void gui_GetExpSubCursorPos(bool, mcCursorPos &) const; 00416 //void gui_GetSubCursorPos(mcCursorPos &) const; //!< See #gui_GetExpCursorPos. 00417 00421 void gui_SetExpSubCursorPos(bool, const mcCursorPos &code); 00422 00424 //void gui_SetSubCursorPos(mcCursorPos code); 00425 00429 virtual mcInputRes gui_ExpSubInput(bool, const mcKey &ev, mcElement *pnew); 00430 //virtual mcInputRes gui_SubInput(const mcKey &ev, mcElement *pnew); //!< See #gui_ExpInput. 00431 00437 void gui_EditExpSub(bool); 00438 //void gui_EditSub(); //!< See #gui_EditExp(). 00439 00441 void gui_DeleteExpSub(bool); 00442 //void gui_DeleteSub(); //!< See #gui_DeleteExp. 00443 00448 virtual void gui_CheckExpSub(bool); 00449 //virtual void gui_CheckSub(); //!< See #gui_CheckExp. 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 //bool gui_isCursorInSub(bool bCheckBeginEndExp = TRUE) const; 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 //virtual //bool hasSameContentOf(const mcElement &) const; 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 /*virtual void GetContentMathML(wxXml2Node *pTag) { 00854 00855 // if an exponent is present, create a POWER section 00856 if (data_mdata_pExp != NULL && this->data_hasProperty(mcEP_HASEXPONENT)) { 00857 00858 wxXml2Node *base = new wxXml2Node(), *exp = new wxXml2Node(); 00859 00860 // save base and exponent Math ML 00861 GetBaseContentMathML(base); 00862 data_mdata_pExp.io_GetMathML(exp); 00863 00864 // concatenate all the string 00865 dest += wxString(wxT(' '), indent) + wxT("<apply>\n") + wxString(wxT(' '), indent+mcMathCore::Get()->m_nIndentationStep) + 00866 wxT("<power/>\n") + base + exp + wxString(wxT(' '), indent) + wxT("</apply>\n"); 00867 00868 return dest; 00869 } 00870 00871 // we don't need to create a MSUP tag 00872 return GetBaseContentMathML(indent); 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
[ Top ] |