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 SYMBOL_H 00035 #define SYMBOL_H 00036 00037 // optimization for GCC compiler 00038 #ifdef __GNUG__ 00039 #pragma interface "Symbol.h" 00040 #endif 00041 00042 // required includes 00043 #include "mc/ExpElement.h" 00044 00045 00046 00047 mcDEFINE_HELPER_CLASSES(mcSymbol) 00048 00049 00050 00051 00052 00053 00054 00055 00056 00057 00058 00059 00060 00061 00062 class mcSymbolHelpers : public mcExpElementHelpers 00063 { 00064 mcDEFINE_REFERENCE_DATA(mcSymbol, mcET_SYMBOL); 00065 00066 #ifdef mcENABLE_DATA 00067 protected: // DATA variables 00068 00071 mcSymbolProperties *mdata_pEntry; 00072 00073 #endif 00074 00075 00076 00077 #ifdef mcENABLE_GUI 00078 protected: // GUI variables 00079 00080 // mcSymbol uses the mcExpElementGUI cursor positions + 00081 // cursor positions defined here: 00082 #define mcSYMBOL_LEFTMOST 0 00083 #define mcSYMBOL_RIGHTMOST 1 00084 00085 int mgui_nCursorPos; 00086 00087 public: // customizable variables 00088 00092 static wxColour sgui_clrUndefSymbols; 00093 00094 #endif 00095 00096 00097 #ifdef mcENABLE_MATH 00098 public: // customizable variables 00099 00100 static int smath_nUnknownOrderPos; 00101 static int smath_nParameterOrderPos; 00102 static int smath_nConstantOrderPos; 00103 00104 #endif 00105 00106 00107 00108 public: 00109 00110 mcSymbolHelpers() { 00111 mdata_pEntry = NULL; 00112 00113 // mcSymbol allows both exponents and subscript 00114 mdata_bSubEnabled = mdata_bExpEnabled = TRUE; 00115 data_Init(); 00116 } 00117 00118 virtual ~mcSymbolHelpers() { data_Unlink(); } 00119 00120 protected: 00121 00122 void gui_Init() { 00123 00124 // this sets the cursor pos to zero 00125 mcExpElementHelpers::gui_Init(); 00126 00127 // cursor begins positioned at the end of the symbol; infact, when 00128 // the mcSymbol class has been allocated by MathCore input system, the user 00129 // has already pressed the symbol associated with mcSymbol class 00130 mgui_nCursorPos = mcSYMBOL_RIGHTMOST; 00131 } 00132 00133 00134 00135 00136 #ifdef mcENABLE_DATA 00137 public: 00138 00139 #ifdef __MCDEBUG__ 00140 00141 wxString data_BaseDebug(long flags) const; 00142 #endif 00143 00144 void data_DeepCopy(const mcElementHelpers *p) { 00145 00146 // link this symbol to the same mcSymbolProperties of 'p' 00147 data_LinkWith(((const mcSymbolHelpers *)p)->mdata_pEntry); 00148 mcExpElementHelpers::data_DeepCopy(p); 00149 } 00150 00151 bool data_isSameAs(const mcElementHelpers *p) const { 00152 if (!mcElementHelpers::data_isSameAs(p)) 00153 return FALSE; 00154 return mdata_pEntry == ((const mcSymbolHelpers *)p)->mdata_pEntry; 00155 } 00156 00157 00158 00162 00165 void data_LinkWith(mcSymbolProperties *prop) { 00166 if (mdata_pEntry) data_Unlink(); 00167 if (prop == NULL) return; 00168 mdata_pEntry = prop; 00169 prop->data_Link(this); 00170 } 00171 00175 void data_Unlink() { 00176 if (mdata_pEntry) mdata_pEntry->data_Unlink(this); 00177 mdata_pEntry = NULL; 00178 } 00179 00181 bool data_isLinked() const 00182 { return mdata_pEntry != NULL; } 00183 00185 bool data_isLinkedWith(const mcSymbolProperties *p) const 00186 { return mdata_pEntry == p; } 00187 00190 void data_Update(); 00191 00193 00194 00195 00199 00201 wxString data_GetSubscript() const { 00202 mcASSERT(mdata_pEntry, wxT("An unlinked symbol ?")); 00203 return mdata_pEntry->m_strSubscript; // should be in sync with mcExpElement's subscript 00204 } 00205 00207 wxString data_GetSymbol() const { 00208 mcASSERT(mdata_pEntry, wxT("An unlinked symbol ?")); 00209 return mdata_pEntry->m_strSymbol; 00210 } 00211 00213 wxString data_GetInlinedSymbol() const { 00214 mcASSERT(mdata_pEntry, wxT("An unlinked symbol ?")); 00215 return mdata_pEntry->io_GetInlinedSym(); 00216 } 00217 00220 wxString data_GetEncodedType() const { 00221 if (data_isParameter()) return wxT("p"); 00222 if (data_isUnknown()) return wxT("u"); 00223 if (data_isConstant()) return wxT("c"); 00224 return wxEmptyString; // unregistered ? 00225 } 00226 00228 mcRealValue data_GetValue() const { 00229 return mdata_pEntry->m_fValue; 00230 } 00231 00233 const mcExtRange *data_GetDomain() const { 00234 return mdata_pEntry->m_pDomain; 00235 } 00236 00238 mcExtRange *data_GetDomain() { 00239 return mdata_pEntry->m_pDomain; 00240 } 00241 00243 const mcSymbolProperties *data_GetConstProperties() const { 00244 return mdata_pEntry; 00245 } 00246 00247 mcSymbolProperties *data_GetProperties() { 00248 return mdata_pEntry; 00249 } 00250 00252 00253 00254 00258 00261 bool data_isGreekSymbol() const { 00262 mcASSERT(mdata_pEntry, wxT("An unlined symbol ?")); 00263 return mdata_pEntry->m_fEncoding == wxFONTENCODING_ISO8859_7; 00264 } 00265 00270 bool data_isRegistered() const { 00271 mcASSERT(mdata_pEntry, wxT("An unlinked symbol ?")); 00272 return mdata_pEntry->data_isRegistered(); 00273 } 00274 00275 bool data_isParameter() const { 00276 mcASSERT(mdata_pEntry, wxT("An unlinked symbol ?")); 00277 return mdata_pEntry->data_isParameter(); 00278 } 00279 00280 bool data_isUnknown() const { 00281 mcASSERT(mdata_pEntry, wxT("An unlinked symbol ?")); 00282 return mdata_pEntry->data_isUnknown(); 00283 } 00284 00285 bool data_isConstant() const { 00286 mcASSERT(mdata_pEntry, wxT("An unlinked symbol ?")); 00287 return mdata_pEntry->data_isConstant(); 00288 } 00289 00291 00292 00293 00297 00302 void data_SetSymbol(const wxString &str); 00303 00305 void data_SetValue(double d) { mdata_pEntry->m_fValue = d; } 00306 void data_SetAsGreek(bool b = TRUE) { mdata_pEntry->m_fEncoding = wxFONTENCODING_ISO8859_7; } 00307 void data_SetSubscript(const wxString &str); 00308 00310 #endif // mcENABLE_DATA 00311 00312 00313 00314 00315 #ifdef mcENABLE_GUI 00316 public: 00317 00322 00327 bool gui_isBeginKey(const mcKey &ke) const; 00328 00332 bool gui_isBaseEndKey(const mcKey &key) const; 00333 00336 bool gui_DrawAsActiveOverBase() const { return TRUE; } 00337 00338 mcInputRes gui_BaseInput(const mcKey &ke, mcElement *pnew); 00339 mcInputRes gui_SubInput(const mcKey &ev, mcElement *pnew); 00340 mcInsertRes gui_BaseInsert(const mcElement &, mcElement *); 00341 00342 mcMoveCursorRes gui_BaseMoveCursor(mcMoveCursorFlag flag, long modifiers); 00343 void gui_GetBaseCursorPos(mcCursorPos &) const; 00344 int gui_BaseMoveCursorUsingPoint(wxDC &, const wxPoint &); 00345 int gui_GetBaseRelCursorPos(wxDC &dc, wxPoint *pt) const; 00346 int gui_DrawBase(wxDC &dc, int x, int y, long flags, const wxPoint &pt) const; 00347 00348 void gui_SetBaseCursorPos(const mcCursorPos &code); 00349 void gui_EditBase(); 00350 void gui_DoRecalcBaseSize(); 00351 00353 00354 #endif // mcENABLE_GUI 00355 00356 00357 00358 00359 #ifdef mcENABLE_MATH 00360 public: 00361 00367 bool math_isListedBeforeOf(const mcElement &s) const; 00368 00370 int math_GetOrderPos() const { 00371 if (data_isParameter()) return smath_nParameterOrderPos; 00372 if (data_isUnknown()) return smath_nUnknownOrderPos; 00373 if (data_isConstant()) return smath_nConstantOrderPos; 00374 return -1; // unregistered ? 00375 } 00376 00377 00378 00382 00383 bool math_CompareThisOnly(const mcElement &, long flags) const; 00384 00385 mcExpSimRes math_ExpandBase(long flags, mcElement *newelem); 00386 mcExpSimRes math_SimplifyBase(long flags, mcElement *newelem); 00387 mcExpSimRes math_SimplifyBaseExp(long flags, mcElement *pnew); 00388 00389 // these do not apply 00390 virtual mcBasicOpRes math_Add(const mcElement &, mcElement *p, bool add) { return mcBOR_REMOVE_OPERAND; } 00391 virtual mcBasicOpRes math_MultiplyBaseOnlyBy(const mcElement &, mcElement *p) { return mcBOR_REMOVE_OPERAND; } 00392 virtual mcBasicOpRes math_DivideBaseOnlyBy(const mcElement &, mcElement *p) { return mcBOR_REMOVE_OPERAND; } 00393 00402 bool math_CanBeDivBy(const mcElement &p) const { return math_CompareThisOnly(p, TRUE); } 00403 bool math_CanBeMultWith(const mcElement &p) const { return math_CompareThisOnly(p, TRUE); } 00404 bool math_CanBeAddedWith(const mcElement &p) const { return FALSE; } 00405 00406 mcRealValue math_GetBaseLenght() const { return 1; } 00407 00408 mcRealValue math_EvaluateBase() const; 00409 mcMathType math_GetBaseMathType() const; 00410 00412 00413 #endif // mcENABLE_MATH 00414 00415 00416 00417 #ifdef mcENABLE_IO 00418 public: 00419 00420 bool io_isBeginTag(const wxXml2Node &tag) const { 00421 if (tag.GetName() == wxT("mi")) 00422 return TRUE; 00423 return FALSE; 00424 } 00425 00426 bool io_isBeginChar(const wxString &str) const { 00427 if (wxIsalpha(str.GetChar(0))) 00428 return TRUE; 00429 return FALSE; 00430 } 00431 00432 wxXml2Node io_GetBaseMathML(bool bGetPresentation) const; 00433 wxString io_GetBaseInlinedExpr() const; 00434 00435 bool io_ImportPresentationMathML(wxXml2Node tag, wxString &pErr); 00436 bool io_ImportBaseInlinedExpr(const wxString &str, int *count, wxString &pErr); 00437 00438 #endif // mcENABLE_IO 00439 }; 00440 00441 00442 00443 00450 class mcSymbol : public mcExpElement 00451 { 00452 mcDEFINE_MAIN_CLASS(Symbol, mcExpElement); 00453 00454 public: 00455 00456 mcSymbol(const mcSymbolProperties *sym) 00457 { data_SetRefData(new mcSymbolHelpers()); hlp()->data_LinkWith((mcSymbolProperties *)sym); } 00458 00459 mcSymbol operator^(const mcPolynomial &m) const 00460 { mcSymbol ret(*this); ret.math_RaiseTo(m); return ret; } 00461 mcSymbol &operator^=(const mcPolynomial &m) 00462 { *this = (*this)^m;return *this; } 00463 00464 00469 00471 static mcSymbolArray arrParameters; 00472 00474 static mcSymbolArray arrConstants; 00475 00477 static mcSymbolArray arrUnknowns; 00478 00480 static mcSymbolArray arrUnregistered; 00481 00482 // WARNING: A UNREGISTERED mcSYMBOL CANNOT KNOW IF IT IS THE LAST SYMBOL OF 00483 // THAT TYPE.... SO, WHEN IT IS DESTROYED IT CANNOT KNOW IF IT HAS 00484 // TO DELETE THE UNREGISTERED SYMBOL FROM THE arrUnregistered OR NOT. 00485 // 00486 // SOLUTION: mcSymbolProperties HOLDS A LIST OF POINTERS TO THE SYMBOLS 00487 // LINKED WITH THAT CLASS AND SO IT ALWAYS KNOW IF IT HAS 00488 // INSTANCES OR IT'S UNLINKED. 00489 00492 static void InitSymbols(); 00493 00495 static void CleanupSymbols(); 00496 00508 static mcSymbolArray *math_FindSymbol( 00509 long flags, 00510 const wxString &name, 00511 wxFontEncoding enc = wxFONTENCODING_DEFAULT, 00512 const mcRealValue &value = 0.0, 00513 const wxString &subscript = wxEmptyString, 00514 const wxString &inlined = wxEmptyString, 00515 int occ = 0, 00516 int *entry = NULL, 00517 int skipArr = -1); 00518 00519 static mcSymbolArray *math_FindSymbol(long flags, 00520 const mcSymbolProperties &symtofind, 00521 int occurrence = 0, 00522 int *entry = NULL, 00523 int skipArr = -1); 00524 00526 static void CheckArray(mcSymbolArray *); 00527 00530 static void CheckSymbols(); 00531 00558 static bool LoadSymbols(const wxXml2Node &main, bool removeprevious = TRUE); 00559 00564 static void LoadDefaultSymbols(bool removeprevious = TRUE); 00565 00567 00568 00569 00571 virtual void data_Update() { 00572 data_Update(); 00573 mcElement::data_Update(); 00574 } 00575 00576 bool data_isValidContainerFor(mcElementType t) const 00577 { return t == mcET_SYMBOL; } 00578 00579 00580 00581 mcWRAPPER void data_LinkWith(mcSymbolProperties *prop) 00582 { hlp()->data_LinkWith(prop); } 00583 mcWRAPPER void data_Unlink() 00584 { hlp()->data_Unlink(); } 00585 mcWRAPPER bool data_isLinked() const 00586 { return hlp()->data_isLinked(); } 00587 mcWRAPPER bool data_isLinkedWith(const mcSymbolProperties *p) const 00588 { return hlp()->data_isLinkedWith(p); } 00589 00590 mcWRAPPER wxString data_GetSubscript() const 00591 { return hlp()->data_GetSubscript(); } 00592 mcWRAPPER wxString data_GetSymbol() const 00593 { return hlp()->data_GetSymbol(); } 00594 00595 /* //! Returns the string used to export this symbol as inlined expression. 00596 wxString data_GetInlinedSymbol() const { 00597 mcASSERT(mdata_pEntry, wxT("An unlinked symbol ?")); 00598 return mdata_pEntry->GetInlinedSym(); 00599 } 00600 00603 wxString data_GetEncodedType() const { 00604 if (data_isParameter()) return wxT("p"); 00605 if (data_isUnknown()) return wxT("u"); 00606 if (data_isConstant()) return wxT("c"); 00607 return wxEmptyString; // unregistered ? 00608 } 00609 00611 mcRealValue data_GetValue() const { 00612 return mdata_pEntry->m_fValue; 00613 } 00614 00616 const mcExtRange *data_GetDomain() const { 00617 return mdata_pEntry->m_pDomain; 00618 } 00619 00621 mcExtRange *data_GetDomain() { 00622 return mdata_pEntry->m_pDomain; 00623 } 00624 */ 00626 mcWRAPPER const mcSymbolProperties *data_GetConstProperties() const 00627 { return hlp()->data_GetConstProperties(); } 00628 00629 mcWRAPPER mcSymbolProperties *data_GetProperties() 00630 { return hlp()->data_GetProperties(); } 00631 00632 00633 /* 00634 00638 00641 bool data_isGreekSymbol() const { 00642 mcASSERT(mdata_pEntry, wxT("An unlined symbol ?")); 00643 return mdata_pEntry->m_fEncoding == wxFONTENCODING_ISO8859_7; 00644 } 00645 00650 bool data_isRegistered() const { 00651 mcASSERT(mdata_pEntry, wxT("An unlinked symbol ?")); 00652 return mdata_pEntry->isRegistered(); 00653 } 00654 00655 bool data_isParameter() const { 00656 mcASSERT(mdata_pEntry, wxT("An unlinked symbol ?")); 00657 return mdata_pEntry->isParameter(); 00658 } 00659 00660 bool data_isUnknown() const { 00661 mcASSERT(mdata_pEntry, wxT("An unlinked symbol ?")); 00662 return mdata_pEntry->isUnknown(); 00663 } 00664 00665 bool data_isConstant() const { 00666 mcASSERT(mdata_pEntry, wxT("An unlinked symbol ?")); 00667 return mdata_pEntry->math_isConstant(); 00668 } 00669 00671 00672 00673 00677 00682 void data_SetSymbol(const wxString &str); 00683 00685 void data_SetValue(double d) { mdata_pEntry->m_fValue = d; } 00686 void data_SetAsGreek(bool b = TRUE) { mdata_pEntry->m_fEncoding = wxFONTENCODING_ISO8859_7; } 00687 void data_SetSubscript(const wxString &str); 00688 */ 00689 00690 }; 00691 00692 00693 #endif // SYMBOL_H 00694
[ Top ] |