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 NUMBER_H 00035 #define NUMBER_H 00036 00037 // optimization for GCC compiler 00038 #ifdef __GNUG__ 00039 #pragma interface "Number.h" 00040 #endif 00041 00042 // required includes 00043 #include "mc/ExpElement.h" 00044 00045 00046 00049 #define mcNUMBER_DECIMAL_POINT wxT('.') 00050 00051 00052 00053 mcDEFINE_HELPER_CLASSES(mcNumber) 00054 00055 // defined later 00056 extern mcNumber mcEmptyNumber; 00057 00058 00059 00063 class mcNumberHelpers : public mcExpElementHelpers 00064 { 00065 mcDEFINE_REFERENCE_DATA(mcNumber, mcET_NUMBER); 00066 00067 #ifdef mcENABLE_DATA 00068 protected: // DATA variables 00069 00071 mcRealValue mdata_n; 00072 00073 #endif 00074 00075 00076 00077 #ifdef mcENABLE_GUI 00078 protected: // GUI variables 00079 00091 wxString mgui_strTrailer; 00092 00107 int mgui_nCursorPos; 00108 00109 public: // customizable variables 00110 00117 static int sgui_nDigitToShow; 00118 00120 static wxString sgui_strFloatingPoint; 00121 00122 00123 public: // utilities 00124 00129 static bool gui_isDigit(int vk); 00130 00132 static bool gui_isDecimalPoint(wxChar totest) 00133 { return sgui_strFloatingPoint.Find(totest) != wxNOT_FOUND; } 00134 00135 #endif 00136 00137 00138 00139 #ifdef mcENABLE_MATH 00140 public: // customizable variables 00141 00147 static bool smath_bUseIntegersWhenPossible; 00148 00149 public: // static utilities 00150 00152 static mcNumber *smath_pOne; 00153 static mcNumber *smath_pTwo; 00154 static mcNumber *smath_pFour; 00155 static mcNumber *smath_pMinusOne; 00156 static mcNumber *smath_pZero; 00157 00158 static bool math_isZero(const mcElement &); 00159 00160 #endif 00161 00162 00163 00164 public: 00165 00166 mcNumberHelpers() { 00167 mdata_n = 0; // zero by default 00168 //m_n.Set(0); 00169 00170 mdata_bExpEnabled = TRUE; 00171 mdata_bSubEnabled = FALSE; // do not allow subscripts 00172 00173 data_Init(); 00174 } 00175 00176 virtual ~mcNumberHelpers() {} 00177 00178 protected: 00179 00180 void gui_Init() { 00181 mcExpElementHelpers::gui_Init(); 00182 mgui_nCursorPos = 0; // cursor is placed on first digit 00183 } 00184 00185 00186 00187 00188 #ifdef mcENABLE_DATA 00189 public: 00190 00191 #ifdef __MCDEBUG__ 00192 00194 wxString data_BaseDebug(long flags) const { 00195 00196 wxString exp = data_Get().GetStr(); 00197 wxString smart = data_Get().GetSmartStr(); 00198 00199 // choose shortest 00200 return wxT("mcNumber ") + (exp.Len() > smart.Len() ? smart : exp) + wxT("\n"); 00201 } 00202 00203 #endif 00204 00205 void data_DeepCopy(const mcElementHelpers *p) { 00206 const mcNumberHelpers *n = (const mcNumberHelpers *)p; 00207 mdata_n = n->mdata_n; 00208 mgui_strTrailer = n->mgui_strTrailer; 00209 mcExpElementHelpers::data_DeepCopy(p); 00210 } 00211 00212 bool data_isSameAs(const mcElementHelpers *p) const { 00213 if (!mcElementHelpers::data_isSameAs(p)) 00214 return FALSE; 00215 00216 const mcNumberHelpers *ed = (const mcNumberHelpers *)p; 00217 if (mdata_n != ed->mdata_n) return FALSE; 00218 return TRUE; 00219 } 00220 00221 bool data_isAllowedBefore(mcElementType type) const { 00222 if (type == mcET_NUMBER) 00223 return FALSE; 00224 return TRUE; 00225 } 00226 00227 bool data_isAllowedAfter(mcElementType type) const { 00228 // mcET_PARENTHESIS is a special case: when it's a left 00229 // bracket, then there must be *no* operators between it 00230 // and other elements: (*4x) is invalid !! 00231 if (type == mcET_NUMBER || type == mcET_BRACKET || 00232 type == mcET_FUNCTION || type == mcET_SYMBOL || 00233 type == mcET_RADICAL || type == mcET_FRACTION) 00234 return FALSE; 00235 return TRUE; 00236 } 00237 00238 void data_Set(const mcRealValue &d) { mdata_n = d; } 00239 mcRealValue data_Get() const { return mdata_n; } 00240 00241 #endif // mcENABLE_DATA 00242 00243 00244 00245 00246 00247 #ifdef mcENABLE_GUI 00248 public: 00249 00250 void gui_Set(const wxString &toset); 00251 wxString gui_GetStr() const 00252 { return data_Get().GetSmartStr()+mgui_strTrailer; } 00253 00254 00259 00260 bool gui_isBeginKey(const mcKey &ev) const; 00261 bool gui_isBaseEndKey(const mcKey &ev) const; 00262 00265 bool gui_DrawAsActiveOverBase() const { return TRUE; } 00266 00267 mcInsertRes gui_BaseInsert(const mcElement &, mcElement *); 00268 mcInputRes gui_BaseInput(const mcKey &key, mcElement *pnew); 00269 mcMoveCursorRes gui_BaseMoveCursor(mcMoveCursorFlag flag, long modifiers); 00270 int gui_DrawBase(wxDC &dc, int x, int y, long flags, const wxPoint &pt) const; 00271 int gui_BaseMoveCursorUsingPoint(wxDC &, const wxPoint &); 00272 int gui_GetBaseRelCursorPos(wxDC &dc, wxPoint *pt) const; 00273 void gui_GetBaseCursorPos(mcCursorPos &) const; 00274 00275 void gui_SetBaseCursorPos(const mcCursorPos &); 00276 void gui_DoRecalcBaseSize(); 00277 void gui_EditBase(); 00278 00282 bool gui_Split(mcElement *); 00283 bool gui_MergeWith(const mcElement &); 00284 00285 bool gui_isSplittable() const { return TRUE; } 00286 00288 00289 #endif // mcENABLE_GUI 00290 00291 00292 00293 00294 00295 #ifdef mcENABLE_MATH 00296 public: 00297 00298 void math_Abs() { data_Set(data_Get().abs()); } 00299 bool math_isValid() const { return data_Get().isValid(); } 00300 00301 bool math_GetNumDen(mcIntegerValue &num, mcIntegerValue &den); 00302 mcFraction math_TransformInFraction(); 00303 00304 void math_RaiseBaseTo(mcRealValue n); 00305 virtual void math_RaiseTo(const mcIntegerValue &n); 00306 00307 00308 00312 00313 bool math_CanBeAddedWith(const mcElement &p) const; 00314 bool math_CanBeMultWith(const mcElement &p) const; 00315 bool math_CanBeDivBy(const mcElement &p) const; 00316 00317 mcBasicOpRes math_Add(const mcElement &, mcElement *, bool add); 00318 00319 mcBasicOpRes math_MultiplyBaseOnlyBy(const mcElement &, mcElement *); 00320 mcBasicOpRes math_DivideBaseOnlyBy(const mcElement &, mcElement *); 00321 mcBasicOpRes math_MultiplyBaseBy(const mcElement &, mcElement *); 00322 mcBasicOpRes math_DivideBaseBy(const mcElement &, mcElement *) 00323 { return mcBOR_REMOVE_OPERAND; } 00324 00325 mcRealValue math_GetBaseLenght() const { return data_Get().GetNumOfDigits(); } 00326 mcRealValue math_EvaluateBase() const { return data_Get(); } 00327 int math_GetOrderPos() const { return 0; } 00328 //mcBasicOpRes math_MakeReciprocal(mcElement *); 00329 00330 mcMathType math_GetBaseMathType() const 00331 { return mcMathType(mcMTL1_POLYNOMIAL, mcMTL2_ALGEBRAIC, mcMTL3_CONSTANT); } 00332 00333 mcBasicOpRes math_MakeReciprocal(mcElement *); 00334 00335 mcExpSimRes math_ExpandBase(long flags, mcElement *newelem); 00336 mcExpSimRes math_SimplifyBase(long flags, mcElement *newelem); 00337 mcExpSimRes math_SimplifyBaseExp(long flags, mcElement *pnew); 00338 00339 //bool hasSameContentOf(const mcElement &p) const; 00340 bool math_CompareThisOnly(const mcElement &p, long flags) const; 00341 00342 mcMonomial math_GetBaseLCM(const mcElement &p) const; 00343 mcMonomial math_GetGCD(const mcElement &p) const; 00344 00346 00347 #endif // mcENABLE_MATH 00348 00349 00350 00351 00352 #ifdef mcENABLE_IO 00353 public: 00354 00355 bool io_isBeginTag(const wxXml2Node &tag) const { 00356 if (tag.GetName() == wxT("mn")) 00357 return TRUE; 00358 return FALSE; 00359 } 00360 00361 bool io_isBeginChar(const wxString &str) const; 00362 00363 // MATH ML export functions 00364 wxXml2Node io_GetBaseMathML(bool bGetPresentation) const; 00365 wxString io_GetBaseInlinedExpr() const; 00366 00367 bool io_ImportPresentationMathML(wxXml2Node tag, wxString &pErr); 00368 bool io_ImportBaseInlinedExpr(const wxString &, int *count, wxString &pErr); 00369 00370 #endif // mcENABLE_IO 00371 }; 00372 00373 00374 00375 00381 class mcNumber : public mcExpElement 00382 { 00383 mcDEFINE_MAIN_CLASS(Number, mcExpElement); 00384 00385 public: 00386 00388 mcNumber(const mcRealValue &n) 00389 { data_SetRefData(new mcNumberHelpers); hlp()->data_Set(n); } 00390 00391 bool data_isValidContainerFor(mcElementType t) const 00392 { return t == mcET_NUMBER; } 00393 00394 mcWRAPPER void data_Set(const mcRealValue &d) { hlp()->data_Set(d); } 00395 mcWRAPPER mcRealValue data_Get() const { return hlp()->data_Get(); } 00396 00397 mcWRAPPER void math_Abs() 00398 { hlp()->math_Abs(); } 00399 00400 mcWRAPPER bool math_isValid() const 00401 { return hlp()->math_isValid(); } 00402 00403 mcWRAPPER bool math_GetNumDen(mcIntegerValue &num, mcIntegerValue &den) 00404 { return hlp()->math_GetNumDen(num, den); } 00405 00406 // this needs to be in the source file 00407 mcFraction math_TransformInFraction(); 00408 }; 00409 00410 #endif // NUMBER_H 00411 00412
[ Top ] |