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
00035
00036 #ifdef __GNUG__
00037 #pragma implementation "Text.h"
00038 #endif
00039
00040
00041 #include "mc/mcprec.h"
00042 #ifdef __BORLANDC__
00043 #pragma hdrstop
00044 #endif
00045
00046 #ifndef mcPRECOMP
00047 #include <wx/dcscreen.h>
00048 #include "mc/MathCore.h"
00049 #include "mc/Text.h"
00050 #endif
00051
00052
00053 mcIMPLEMENT_MAIN_CLASS(mcText, mcDecoration);
00054
00055
00056
00057 mcText *mcTextHelpers::smath_pEmpty = NULL;
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 void mcTextHelpers::data_DeepCopy(const mcElementHelpers *p)
00068 {
00069 const mcTextHelpers *e = (const mcTextHelpers *)p;
00070
00071 mdata_arrStr = e->mdata_arrStr;
00072 mdata_bMultiline = e->mdata_bMultiline;
00073 mdata_strFilter = e->mdata_strFilter;
00074
00075
00076 mgui_nCursorPos = e->mgui_nCursorPos;
00077 mgui_nRowPos = e->mgui_nRowPos;
00078 mgui_bDrawEmptyBoxIfEmpty = e->mgui_bDrawEmptyBoxIfEmpty;
00079
00080
00081 if (e->mgui_pEmptyBox)
00082 mgui_pEmptyBox = new mcEmptyBox();
00083 else
00084 mcSAFE_DELETE(mgui_pEmptyBox);
00085 }
00086
00087 void mcTextHelpers::data_SetText(const wxString &str)
00088 {
00089 wxString mystr(str);
00090
00091 if (mystr.Freq(wxT('\n')) > 0) {
00092
00093 mcASSERT(mdata_bMultiline == TRUE,
00094 wxT("Cannot set text with \\n in a single line element"));
00095
00096
00097
00098 for (int i=0, m=str.Freq(wxT('\n')); i < m; i++) {
00099 mdata_arrStr.Add(str.Left(mystr.Index(wxT('\n'))));
00100 mystr = mystr.Right(mystr.Len()-mystr.Index(wxT('\n')));
00101 }
00102
00103 } else {
00104
00105
00106 mdata_arrStr.Clear();
00107 mdata_arrStr.Add(mystr);
00108 }
00109
00110 if (mcMathCore::Get()->isGUIEnabled())
00111 gui_SetCursorPos(mcCP_END);
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 void mcTextHelpers::gui_Init()
00123 {
00124 mgui_bDrawEmptyBoxIfEmpty = TRUE;
00125 mgui_nCursorPos = mgui_nRowPos = 0;
00126
00127
00128 mgui_pEmptyBox = new mcEmptyBox();
00129 mcDecorationHelpers::gui_Init();
00130 }
00131
00132 mcInputRes mcTextHelpers::gui_Input(const mcKey &key, mcElement *pnew)
00133 {
00134
00135 if (mcMathCore::Get()->m_pDeleteKey->MatchKey(key)) {
00136
00137 if (mgui_nCursorPos > 0) {
00138
00139
00140 mdata_arrStr[mgui_nRowPos] =
00141 mdata_arrStr[mgui_nRowPos].Left(mgui_nCursorPos-1) +
00142 mdata_arrStr[mgui_nRowPos].Right(
00143 mdata_arrStr[mgui_nRowPos].Len()-mgui_nCursorPos);
00144 mgui_nCursorPos--;
00145
00146 if (mgui_nCursorPos == 0 && mdata_arrStr[mgui_nRowPos].IsEmpty())
00147 mdata_arrStr.Remove(mgui_nRowPos);
00148
00149 if (data_isArrayEmpty())
00150 return mcIR_DELETE_THIS;
00151
00152 } else if (mgui_nRowPos > 0) {
00153
00154
00155
00156 mcASSERT(mgui_nCursorPos == 0, wxT("something wrong"));
00157 mdata_arrStr.Remove(mgui_nRowPos);
00158 mgui_nRowPos--;
00159 gui_SetCursorPos(mcCP_END);
00160
00161 } else {
00162
00163 if (data_isArrayEmpty())
00164 return mcIR_DELETE_THIS;
00165
00166 mdata_arrStr.Empty();
00167 }
00168
00169 return mcIR_OKAY;
00170 }
00171
00172
00173 if (mcMathCore::Get()->m_pCancelKey->MatchKey(key)) {
00174
00175 if (mgui_nCursorPos == (int)mdata_arrStr[mgui_nRowPos].Len()) {
00176
00177 if (mgui_nRowPos < data_GetRowCount()-1) {
00178
00179
00180 mdata_arrStr[mgui_nRowPos] += mdata_arrStr[mgui_nRowPos+1];
00181 mdata_arrStr.Remove(mgui_nRowPos+1);
00182
00183 } else {
00184
00185
00186 return mcIR_DELETE_NEXT;
00187 }
00188 }
00189
00190 if (data_isArrayEmpty())
00191 return mcIR_DELETE_THIS;
00192
00193 mdata_arrStr[mgui_nRowPos] =
00194 mdata_arrStr[mgui_nRowPos].Left(mgui_nCursorPos) +
00195 mdata_arrStr[mgui_nRowPos].Right(
00196 mdata_arrStr[mgui_nRowPos].Len()-mgui_nCursorPos-1);
00197
00198 return mcIR_OKAY;
00199 }
00200
00201
00202 if (mcMathCore::Get()->m_pNewLineKey->MatchKey(key)) {
00203
00204 if (mdata_bMultiline) {
00205
00206
00207 mdata_arrStr.Add(wxT(""));
00208 mgui_nRowPos++;
00209 mgui_nCursorPos = 0;
00210
00211 } else {
00212
00213
00214 mcMathCore::Get()->SyntaxError(wxT("Cannot create a new line here"));
00215 }
00216
00217 return mcIR_OKAY;
00218 }
00219
00220
00221
00222 if (data_isToReject((wxChar)key.GetKeyCode())) {
00223
00224 mcMathCore::Get()->SyntaxError(wxT("Cannot accept this input here"));
00225 return mcIR_OKAY;
00226 }
00227
00228
00229 if (data_isArrayEmpty()) {
00230 mdata_arrStr.Add(wxT(""));
00231 mgui_nRowPos = mgui_nCursorPos = 0;
00232 }
00233
00234
00235
00236 wxString &str = mdata_arrStr.Item(mgui_nRowPos);
00237
00238 str = str.Left(mgui_nCursorPos) + wxString((wxChar)key.GetKeyCode(), 1) +
00239 str.Right(str.Len()-mgui_nCursorPos);
00240 mgui_nCursorPos++;
00241
00242 return mcIR_OKAY;
00243 }
00244
00245 mcMoveCursorRes mcTextHelpers::gui_MoveCursor(mcMoveCursorFlag flag, long modifiers)
00246 {
00247 if (data_isArrayEmpty() && mgui_bDrawEmptyBoxIfEmpty)
00248 return mgui_pEmptyBox->hlp()->gui_MoveCursor(flag, modifiers);
00249
00250 switch (flag) {
00251 case mcMCF_LEFT:
00252 if (mgui_nCursorPos > 0)
00253 mgui_nCursorPos--;
00254 else
00255 return mcMCR_SETFOCUS_PREVIOUS;
00256 break;
00257
00258 case mcMCF_RIGHT:
00259 if (mgui_nCursorPos < (int)mdata_arrStr[mgui_nRowPos].Len())
00260 mgui_nCursorPos++;
00261 else
00262 return mcMCR_SETFOCUS_NEXT;
00263 break;
00264
00265 case mcMCF_UP:
00266 if (mgui_nRowPos > 0) {
00267 mgui_nRowPos--;
00268
00269
00270 mgui_nCursorPos = (mgui_nCursorPos > (int)mdata_arrStr[mgui_nRowPos].Len()) ?
00271 mdata_arrStr[mgui_nRowPos].Len() : mgui_nCursorPos;
00272 } else
00273 return mcMCR_SETFOCUS_ABOVE;
00274 break;
00275
00276 case mcMCF_DOWN:
00277 if (mgui_nRowPos < data_GetRowCount()-1) {
00278 mgui_nRowPos++;
00279
00280
00281 mgui_nCursorPos = (mgui_nCursorPos > (int)mdata_arrStr[mgui_nRowPos].Len()) ?
00282 mdata_arrStr[mgui_nRowPos].Len() : mgui_nCursorPos;
00283 } else
00284 return mcMCR_SETFOCUS_BELOW;
00285 break;
00286 }
00287
00288 return mcMCR_OKAY;
00289 }
00290
00291 int mcTextHelpers::gui_MoveCursorUsingPoint(wxDC &dc, const wxPoint &p)
00292 {
00293 if (data_isArrayEmpty() && mgui_bDrawEmptyBoxIfEmpty) {
00294 mgui_nCursorPos = 0;
00295 mgui_nRowPos = 0;
00296 return mcMCR_OKAY;
00297 }
00298
00299
00300 gui_SelectStyle(dc);
00301
00302 int h, w, y = 0;
00303 for (int i=0; i < data_GetRowCount(); y+=h, i++) {
00304 h = gui_GetRowHeight(&dc, i);
00305 w = gui_GetRowWidth(&dc, i);
00306 if (p.x >= 0 && p.x <= w &&
00307 p.y >= y && p.y <= y+h) {
00308
00309
00310 int dx = w/mdata_arrStr[i].Len();
00311
00312
00313 mgui_nCursorPos = p.x/dx;
00314 mgui_nRowPos = i;
00315
00316 return mcMCR_OKAY;
00317 }
00318 }
00319
00320
00321 return mcMCR_CANNOT_SETFOCUS;
00322 }
00323
00324 int mcTextHelpers::gui_Draw(wxDC &dc, int x, int y, long flags, int w, wxColour *col) const
00325 {
00326 if (data_isArrayEmpty() && mgui_bDrawEmptyBoxIfEmpty) {
00327
00328
00329 mgui_pEmptyBox->hlp()->gui_Draw(dc, x, y, mcDRW_NONACTIVE, wxDefaultPosition);
00330 return data_GetID();
00331 }
00332
00333
00334 gui_SelectStyle(dc);
00335 if (col) dc.SetTextForeground(*col);
00336
00337 for (int i=0; i < data_GetRowCount(); y+=gui_GetRowHeight(&dc, i), i++)
00338 dc.DrawText(mdata_arrStr[i], x, y);
00339
00340
00341 return data_GetID();
00342 }
00343
00344 int mcTextHelpers::gui_GetRelCursorPos(wxDC &dc, wxPoint *pt) const
00345 {
00346 if (data_isArrayEmpty() && mgui_bDrawEmptyBoxIfEmpty) {
00347
00348
00349 return mgui_pEmptyBox->hlp()->gui_GetRelCursorPos(dc, pt);
00350 }
00351
00352 if (mdata_arrStr.IsEmpty())
00353 return 0;
00354
00355
00356 gui_SelectStyle(dc);
00357
00358 pt->x = gui_GetWidthOf(&dc,
00359 mdata_arrStr[mgui_nRowPos].Left(mgui_nCursorPos));
00360 pt->y = 0;
00361
00362
00363 for (int i=0; i < mgui_nRowPos; i++)
00364 pt->y += gui_GetRowHeight(&dc, i);
00365
00366
00367
00368 return gui_GetRowHeight(&dc, mgui_nRowPos);
00369 }
00370
00371 void mcTextHelpers::gui_DoRecalcSize()
00372 {
00373 int h=0;
00374 wxScreenDC dc;
00375
00376 if (data_isArrayEmpty() && mgui_bDrawEmptyBoxIfEmpty) {
00377
00378
00379 mgui_pEmptyBox->hlp()->gui_RecalcSize();
00380 mgui_sz = mgui_pEmptyBox->hlp()->gui_GetSize();
00381 return;
00382 }
00383
00384
00385 gui_SelectStyle(dc);
00386 for (int i=0; i < data_GetRowCount(); i++)
00387 h += gui_GetRowHeight(&dc, i);
00388
00389 mgui_sz = wxSize(gui_GetWidthOf(&dc, data_GetLongestStr()), h);
00390 }
00391
00392 void mcTextHelpers::gui_SetCursorPos(const mcCursorPos &code)
00393 {
00394 if (code.isBegin()) {
00395
00396
00397 mgui_nCursorPos = 0;
00398
00399 } else if (code.isEnd()) {
00400
00401
00402 if (!data_isArrayEmpty())
00403 mgui_nCursorPos = mdata_arrStr[mgui_nRowPos].Len();
00404 else
00405 mgui_nCursorPos = 0;
00406
00407 } else {
00408
00409 mcASSERT(0, wxT("Cannot accept this flag"));
00410 }
00411 }
00412
00413 void mcTextHelpers::gui_GetCursorPos(mcCursorPos &cp) const
00414 {
00415 if (mgui_nCursorPos == 0)
00416 cp.gui_Push(mcCP_BEGIN);
00417 else if (mgui_nCursorPos == (int)mdata_arrStr[mgui_nRowPos].Len() &&
00418 mgui_nRowPos == data_GetRowCount()-1)
00419 cp.gui_Push(mcCP_END);
00420 else
00421 cp.gui_Push(mgui_nCursorPos);
00422 }
00423
00424 void mcTextHelpers::gui_UpdateExpDepth()
00425 {
00426 if (mcMathCore::Get()->isGUIEnabled()) {
00427 mcElement *p = mgui_pEmptyBox;
00428 if (p) p->gui_SetAtSameLevelOf(this);
00429 }
00430
00431
00432 mcElementHelpers::gui_UpdateExpDepth();
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 wxXml2Node mcTextHelpers::io_GetMathML(bool bGetPresentation) const
00444 {
00445
00446 mcASSERT(!mdata_bMultiline, wxT("Cannot create a multiline MTEXT tag"));
00447
00448
00449 return wxXml2Node(wxXML_TEXT_NODE, wxXml2EmptyDoc, wxT("mtext"), mdata_arrStr[0]);
00450 }
00451
00452 wxString mcTextHelpers::io_GetInlinedExpr() const
00453 {
00454 if (mdata_arrStr.IsEmpty()) return wxEmptyString;
00455
00456
00457 return mdata_arrStr[0];
00458 }
00459
00460 bool mcTextHelpers::io_ImportPresentationMathML(wxXml2Node tag, wxString &pErr)
00461 {
00462 return TRUE;
00463 }
00464
00465 bool mcTextHelpers::io_ImportInlinedExpr(const wxString &str, int *count, wxString &pErr)
00466 {
00467
00468 data_SetText(str);
00469 *count = str.Len();
00470
00471 return TRUE;
00472 }
00473
00474
00475
00476
00477
00478
00479
00480 bool mcTextHelpers::math_CompareThisOnly(const mcElement &p, long flags) const
00481 {
00482 if (!mcElementHelpers::math_CompareThisOnly(p, flags))
00483 return FALSE;
00484
00485
00486 if (data_GetText() == mcText(p).hlp()->data_GetText())
00487 return TRUE;
00488 return FALSE;
00489 }
00490
00491