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 00035 #ifndef mcFUNCTION_H 00036 #define mcFUNCTION_H 00037 00038 // optimization for GCC compiler 00039 #ifdef __GNUG__ 00040 #pragma interface "Function.h" 00041 #endif 00042 00043 // required includes 00044 #include "mc/Bracket.h" 00045 #include "mc/Text.h" 00046 00047 #ifdef mcUSE_WXSCRIPT 00048 #include <wx/script.h> // script classes (a wxWidgets extension) 00049 00050 class wxScriptFunction; 00051 class wxScriptFunctionArray; 00052 class wxScriptFile; 00053 00054 #else 00055 00056 #define wxScriptFunction void 00057 #define wxScriptFunctionArray wxArrayPtrVoid 00058 00059 #endif 00060 00061 00062 mcDEFINE_HELPER_CLASSES(mcFunction) 00063 00064 00065 00066 00067 00068 #define mcFUNCTION_TYPE_NOTSET -1 00069 00072 #define mcFUNCTION_TYPE_NOTFOUND -1 00073 00074 00075 00079 class mcFunctionHelpers : public mcExpElementHelpers 00080 { 00081 mcDEFINE_REFERENCE_DATA(mcFunction, mcET_FUNCTION); 00082 00083 #ifdef mcENABLE_DATA 00084 protected: 00085 00087 mcBracket mdata_eArg; 00088 00090 mcText mdata_eName; 00091 00093 int mdata_nFncType; 00094 00095 #endif 00096 00097 00098 00099 #ifdef mcENABLE_GUI 00100 public: // customizable variables 00101 00102 static int sgui_nSpaceAboveBelow; 00103 static int sgui_nSpaceLeftRight; 00104 00105 virtual int gui_GetSpaceAboveBelow() const { return sgui_nSpaceAboveBelow; } 00106 virtual int gui_GetSpaceLeftRight() const { return sgui_nSpaceLeftRight; } 00107 00108 protected: 00109 00110 // the mcFunctionGUI class uses the positive values of mgui_nCursorPos 00111 // to store cursor position: 00112 // zero means that the cursor is placed on the leftmost point of 00113 // the base; one means that it's placed on the right of the first 00114 // letter of the function name.... 00115 00116 #define mcFUNCTION_INSIDENAME 0 00117 #define mcFUNCTION_INSIDEARG 1 00118 00119 int mgui_nCursorPos; 00120 00121 public: // customizable variables 00122 00124 static mcKey *sgui_pNewFunction; 00125 00126 #endif 00127 00128 00129 00130 public: 00131 00132 mcFunctionHelpers() { 00133 00134 // this will also reset the string stored in mdata_eName... 00135 data_SetFncType(mcFUNCTION_TYPE_NOTSET); 00136 00137 mdata_eName.data_SetFilter(wxT("abcdefghijklmnopqrstuvwxyz") 00138 wxT("ABCDEFGHIJKLMNOPQRSTUVWXYZ'")); 00139 data_Init(); 00140 } 00141 00142 virtual ~mcFunctionHelpers() {} 00143 00144 protected: 00145 00146 void gui_Init() { 00147 mcExpElementHelpers::gui_Init(); 00148 mgui_nCursorPos = mcFUNCTION_INSIDEARG; 00149 mdata_eName.hlp()->mgui_bDrawEmptyBoxIfEmpty = FALSE; 00150 } 00151 00152 00153 00154 00155 #ifdef mcENABLE_DATA 00156 public: 00157 00158 #ifdef __MCDEBUG__ 00159 wxString data_BaseDebug(long flags) const; 00160 #endif 00161 00162 int data_GetChildrenCount() const { 00163 // the mcText used for the function name and the mcBracket used 00164 // as argument container are always present... 00165 return mcExpElementHelpers::data_GetChildrenCount()+2; 00166 } 00167 00168 const mcElement &data_GetConstChild(int n) const { 00169 mcRETURN_ELEMENT_CHILD(n, mcExpElementHelpers); 00170 if (n == 0) return data_GetArgObj(); 00171 if (n == 1) return data_GetNameObj(); 00172 return mcEmptyElement; 00173 } 00174 00175 void data_SetChild(int n, const mcElement &newchild) { 00176 mcSET_ELEMENT_CHILD(n, mcExpElementHelpers, newchild); 00177 mcASSERT((n == 0 && newchild.data_GetType() == mcET_BRACKET) || 00178 (n == 1 && newchild.data_GetType() == mcET_TEXT), 00179 wxT("Invalid new child")); 00180 00181 if (n == 0) data_SetArgObj(newchild); 00182 if (n == 1) data_SetNameObj(newchild); 00183 } 00184 00185 void data_DeepCopy(const mcElementHelpers *p) { 00186 const mcFunctionHelpers *e = (const mcFunctionHelpers *)p; 00187 00188 mdata_eArg.hlp()->data_DeepCopy(e->mdata_eArg.hlp()); 00189 mdata_eName.hlp()->data_DeepCopy(e->mdata_eName.hlp()); 00190 mdata_nFncType = e->mdata_nFncType; 00191 mcExpElementHelpers::data_DeepCopy(e); 00192 } 00193 00194 bool data_isSameAs(const mcElementHelpers *p) const { 00195 if (!mcElementHelpers::data_isSameAs(p)) 00196 return FALSE; 00197 00198 const mcFunctionHelpers *fd = (const mcFunctionHelpers *)p; 00199 if (mdata_eName != fd->mdata_eName) return FALSE; 00200 if (mdata_eArg != fd->mdata_eArg) return FALSE; 00201 return TRUE; 00202 } 00203 00208 void data_CreateSub(); 00209 00211 wxString data_GetName() const; 00212 00214 void data_CheckName(); 00215 00217 void data_SetName(const wxString &str) 00218 { mdata_eName.hlp()->data_SetText(str); } 00219 00222 mcText &data_GetNameObj() { return mdata_eName; } 00223 const mcText &data_GetNameObj() const { return mdata_eName; } 00224 mcTextHelpers *data_GetNameObjHlp() { return mdata_eName.hlp(); } 00225 const mcTextHelpers *data_GetNameObjHlp() const { return mdata_eName.hlp(); } 00226 00229 mcBracket &data_GetArgObj() { return mdata_eArg; } 00230 const mcBracket &data_GetArgObj() const { return mdata_eArg; } 00231 mcBracketHelpers *data_GetArgObjHlp() { return mdata_eArg.hlp(); } 00232 const mcBracketHelpers *data_GetArgObjHlp() const { return mdata_eArg.hlp(); } 00233 00234 void data_SetNameObj(const mcText &p) { mdata_eName.hlp()->data_DeepCopy(p.hlp()); } 00235 void data_SetArgObj(const mcBracket &p) { mdata_eArg.hlp()->data_DeepCopy(p.hlp()); } 00236 00237 00239 bool data_isRegistered() const 00240 { return mdata_nFncType != mcFUNCTION_TYPE_NOTSET; } 00241 00242 00246 00247 // WHAT's THE TYPE OF A FUNCTION SINCE WE LOAD IT FROM SCRIPTS ? 00248 void data_SetFncType(int n); 00249 int data_GetFncType() const { return mdata_nFncType; } 00250 00252 wxScriptFunction *data_GetScript() const; 00253 00254 #endif // mcENABLE_DATA 00255 00256 00257 00258 00259 #ifdef mcENABLE_GUI 00260 public: 00261 00266 00267 int gui_GetArgOffsetx() const; 00268 int gui_GetArgOffsety() const; 00269 int gui_GetNameOffsetx() const; 00270 int gui_GetNameOffsety() const; 00271 00272 void gui_Setup(int functiontype); 00273 wxSize gui_GetSizeOfArg() const; 00274 wxSize gui_GetSizeOfName() const; 00275 00277 00278 00279 00284 00285 bool gui_isBeginKey(const mcKey &key) const { 00286 00287 if (key.MatchKey(*sgui_pNewFunction)) 00288 return TRUE; 00289 return FALSE; 00290 } 00291 00292 bool gui_isBaseEndKey(const mcKey &ev) const { 00293 if (mgui_nCursorPos == mcFUNCTION_INSIDENAME) { 00294 if (mdata_eName.gui_isEndKey(ev)) 00295 return TRUE; 00296 00297 // mcText doesn't return TRUE for some situations... 00298 if (mdata_eName.gui_GetCursorPos().isBegin() && 00299 !ev.MatchKey(*mcMathCore::Get()->m_pCancelKey) && 00300 mdata_eName.hlp()->data_isToReject(ev.GetKeyCode())) 00301 return TRUE; 00302 } 00303 00304 if (mgui_nCursorPos == mcFUNCTION_INSIDEARG && 00305 mdata_eArg.hlp()->gui_isEndKey(ev)) 00306 return TRUE; 00307 return FALSE; 00308 } 00309 00310 bool gui_DrawAsActiveOverBase() const { return FALSE; } 00311 00312 int gui_DrawBase(wxDC &dc, int x, int y, long flags, const wxPoint &pt) const; 00313 int gui_BaseMoveCursorUsingPoint(wxDC &dc, const wxPoint &); 00314 int gui_GetBaseRelCursorPos(wxDC &dc, wxPoint *pt) const; 00315 mcMoveCursorRes gui_BaseMoveCursor(mcMoveCursorFlag, long modifiers); 00316 mcMoveCursorRes gui_MoveCursor(mcMoveCursorFlag, long modifiers); 00317 mcInputRes gui_BaseInput(const mcKey &key, mcElement *pnew); 00318 mcInsertRes gui_BaseInsert(const mcElement &, mcElement *); 00319 void gui_GetBaseCursorPos(mcCursorPos &) const; 00320 00321 int gui_GetExpOffsetx() const; 00322 int gui_GetExpOffsety() const; 00323 00324 int gui_GetSubOffsetx() const; 00325 int gui_GetSubOffsety() const; 00326 00327 void gui_SetCursorPos(const mcCursorPos &code); 00328 void gui_SetBaseCursorPos(const mcCursorPos &) {} 00329 void gui_DoRecalcBaseSize(); 00330 00331 void gui_EditBase(); 00332 void gui_EditBaseAndSetPos(const mcCursorPos &cp); 00333 00336 bool gui_hasBaseSthOnRightSide() const { 00337 return FALSE; 00338 } 00339 00343 mcMoveCursorRes gui_ExpMoveCursor(mcMoveCursorFlag, long); 00344 mcMoveCursorRes gui_SubMoveCursor(mcMoveCursorFlag, long); 00345 00349 void gui_CheckSub(); 00350 00352 00353 #endif // mcENABLE_GUI 00354 00355 00356 00357 #ifdef mcENABLE_MATH 00358 public: 00359 00360 bool math_CanBeAddedWith(const mcElement &p) const { return FALSE; } 00361 bool math_CanBeMultWith(const mcElement &p) const { return FALSE; } 00362 bool math_CanBeDivBy(const mcElement &p) const { return FALSE; } 00363 00364 // these do not apply on this object 00365 virtual mcBasicOpRes math_Add(const mcElement &, mcElement *p, bool add) { return mcBOR_REMOVE_OPERAND; } 00366 virtual mcBasicOpRes math_Subtract(const mcElement &, mcElement *p) { return mcBOR_REMOVE_OPERAND; } 00367 virtual mcBasicOpRes math_MultiplyBaseOnlyBy(const mcElement &, mcElement *p) { return mcBOR_REMOVE_OPERAND; } 00368 virtual mcBasicOpRes math_DivideBaseOnlyBy(const mcElement &, mcElement *p) { return mcBOR_REMOVE_OPERAND; } 00369 00370 mcMathType math_GetBaseMathType() const; 00371 //bool hasSameContentOf(const mcElement &p) const { return FALSE; } 00372 bool math_CompareThisOnly(const mcElement &p) const { return FALSE; } 00373 00374 mcRealValue math_EvaluateBase() const; 00375 00376 // FIXME: this cannot be a fixed value: it should vary from fnc to fnc. 00377 mcRealValue math_GetLenght() const { return 20; } 00378 00379 int math_GetOrderPos() const { return 4; } 00380 00381 mcExpSimRes math_SimplifyBase(long flags, mcElement *newelem); 00382 mcExpSimRes math_ExpandBase(long flags, mcElement *newelem); 00383 00384 #endif // mcENABLE_MATH 00385 00386 00387 00388 00389 #ifdef mcENABLE_IO 00390 public: 00391 00392 bool io_isBeginTag(const wxXml2Node &tag) const 00393 { return FALSE; } 00394 00395 bool io_isBeginChar(const wxString &str) const; 00396 00397 // statics 00398 static wxArrayString io_ImportArgument(const wxString &str, int *count, wxString &pErr); 00399 static bool io_isFunctionBeginChar(const wxString &str); 00400 00401 00402 // MATH ML export functions 00403 wxXml2Node io_GetBaseMathML(bool bGetPresentation) const; 00404 wxXml2Node io_GetMathML(bool bGetPresentation) const; 00405 wxString io_GetBaseInlinedExpr() const; 00406 //wxString io_GetInlinedExpr() const; 00407 00408 bool io_ImportPresentationMathML(wxXml2Node tag, wxString &pErr); 00409 bool io_ImportInlinedExpr(const wxString &str, int *count, wxString &pErr); 00410 00413 bool io_ImportBaseInlinedExpr(const wxString &, int *, wxString &) { return FALSE; } 00414 00416 virtual void io_GetExpSubInlinedToken(wxString &subexp); 00417 00418 #endif // mcENABLE_IO 00419 }; 00420 00421 00425 class mcFunction : public mcExpElement 00426 { 00427 mcDEFINE_MAIN_CLASS(Function, mcExpElement); 00428 00429 public: 00430 00432 static wxScriptFunctionArray arrFunctions; 00433 00435 static bool LoadScriptFile(const wxString &name); 00436 00437 #ifdef mcUSE_WXSCRIPT 00438 00440 static wxString GetAllowedScriptFileExtString() 00441 { return wxScriptFile::GetAllowedExtString(); } 00442 static wxArrayString GetAllowedScriptFileExt() 00443 { return wxScriptFile::GetAllowedExt(); } 00444 #else 00445 00446 static wxString GetAllowedScriptFileExtString() 00447 { return wxEmptyString; } 00448 static wxArrayString GetAllowedScriptFileExt() 00449 { return wxArrayString(); } 00450 00451 #endif 00452 00462 static int data_GetFunctionType(mcElement *p, int n); 00463 static int data_GetFunctionType(const wxString &str); 00464 00465 bool data_isValidContainerFor(mcElementType t) const 00466 { return t == mcET_FUNCTION; } 00467 00468 00469 00470 mcWRAPPER void data_SetName(const wxString &str) 00471 { hlp()->data_SetName(str); } 00472 00473 mcWRAPPER wxString data_GetName() const { return hlp()->data_GetName(); } 00474 mcWRAPPER mcText &data_GetNameObj() { return hlp()->data_GetNameObj(); } 00475 mcWRAPPER const mcText &data_GetNameObj() const { return hlp()->data_GetNameObj(); } 00476 00477 mcWRAPPER mcBracket &data_GetArgObj() { return hlp()->data_GetArgObj(); } 00478 mcWRAPPER const mcBracket &data_GetArgObj() const { return hlp()->data_GetArgObj(); } 00479 00480 mcWRAPPER void data_SetNameObj(const mcText &p) 00481 { hlp()->data_SetNameObj(p); } 00482 mcWRAPPER void data_SetArgObj(const mcBracket &p) 00483 { hlp()->data_SetArgObj(p); } 00484 00485 mcWRAPPER bool data_isRegistered() const 00486 { return hlp()->data_isRegistered(); } 00487 00488 00489 mcWRAPPER void data_SetFncType(int n) 00490 { hlp()->data_SetFncType(n); } 00491 mcWRAPPER int data_GetFncType() const 00492 { return hlp()->data_GetFncType(); } 00493 00494 mcWRAPPER wxScriptFunction *data_GetScript() const 00495 { return hlp()->data_GetScript(); } 00496 00497 mcWRAPPER void gui_Setup(int fnc) 00498 { hlp()->gui_Setup(fnc); } 00499 }; 00500 00501 #endif // mcFUNCTION_h
[ Top ] |