00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00030
00031
00032
00033
00034 #ifdef __GNUG__
00035 #pragma implementation "MathBox.h"
00036 #endif
00037
00038
00039
00040 #include "mg/mgprec.h"
00041
00042 #ifndef mgPRECOMP
00043
00044 #include "mc/MathCore.h"
00045 #include "mc/Function.h"
00046 #include "mc/Fraction.h"
00047 #include "mc/Radical.h"
00048
00049 #include "mg/GUIUtils.h"
00050 #include "mg/MathBox.h"
00051 #endif
00052
00053
00054 #include <wx/image.h>
00055 #include <wx/wfstream.h>
00056 #include <wx/txtstrm.h>
00057 #include <wx/mstream.h>
00058 #include <wx/filename.h>
00059 #include <wx/clipbrd.h>
00060
00061
00062
00063
00064 int mgMathBox::nCursorWidth = 2;
00065 int mgMathBox::nSpaceAround = 5;
00066 bool mgMathBox::bUseNativeNewLines = TRUE;
00067
00068
00069 mgMathBoxCmd mgMathBox::cmd[] =
00070 {
00071
00072 { mgMBC_CUT, wxT("Cut") },
00073 { mgMBC_COPY_ASPLAIN, wxT("Copy as plain text") },
00074 { mgMBC_COPY_ASMATHML, wxT("Copy as MathML") },
00075 { mgMBC_PASTE, wxT("Paste") },
00076 { mgMBC_SELECTALL, wxT("Select all") },
00077
00078 { mgMBC_CREATENEW_ANDLINE, wxT("Create a new line connected with AND") },
00079 { mgMBC_CREATENEW_ORLINE, wxT("Create a new line connected with OR") },
00080 { mgMBC_SIMPLEEND, wxT("") },
00081
00082
00083 { mgMBC_EMBED_NUMFRACTION, wxT("Embed as num of a fraction") },
00084 { mgMBC_EMBED_DENFRACTION, wxT("Embed as den of a fraction") },
00085 { mgMBC_EMBED_RADICAL, wxT("Embed into a radical") },
00086 { mgMBC_EMBED_BRACKET, wxT("Bracketize") },
00087 { mgMBC_ADVEND, wxT("") },
00088
00089 #ifdef __MGDEBUG__
00090 { mgMBC_DEBUG, wxT("View debug info") },
00091 #endif
00092
00093 { mgMBC_LAST, wxT("") }
00094 };
00095
00096
00097
00098
00099
00100 DEFINE_EVENT_TYPE( mgEVT_ACTIVE_ELEM_CHANGED )
00101
00102
00103
00104
00105
00106 IMPLEMENT_CLASS(mgMathBox, wxWindow)
00107 BEGIN_EVENT_TABLE(mgMathBox, wxWindow)
00108
00109
00110 EVT_SET_FOCUS(mgMathBox::OnSetFocus)
00111 EVT_KILL_FOCUS(mgMathBox::OnFocusLost)
00112
00113
00114 EVT_SIZE(mgMathBox::OnSize)
00115 EVT_PAINT(mgMathBox::OnPaint)
00116
00117
00118
00119
00120 EVT_RIGHT_UP(mgMathBox::OnRUp)
00121 EVT_LEAVE_WINDOW(mgMathBox::OnLeaveWindow)
00122 EVT_LEFT_DOWN(mgMathBox::OnLDown)
00123 EVT_LEFT_UP(mgMathBox::OnLUp)
00124 EVT_MOTION(mgMathBox::OnMouseMove)
00125
00126
00127 EVT_CHAR(mgMathBox::OnChar)
00128
00129
00130 EVT_MENU_RANGE(mgMATHBOX_CONTEXTMENU_BASEID,
00131 mgMATHBOX_CONTEXTMENU_FINALID,
00132 mgMathBox::OnCtxMenuItem)
00133 END_EVENT_TABLE()
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 void mgMathBox::Init()
00145 {
00146 m_pClient = NULL;
00147
00148
00149 SetBackgroundColour(wxColour(255, 255, 255));
00150
00151
00152 SetClientEvtHandler(GetParent());
00153 m_bProcSpecialChar = FALSE;
00154 m_bAutoExpand = FALSE;
00155 Clean();
00156
00157
00158 ResetSelectionRect();
00159
00160
00161 if (GetCaret() == NULL)
00162 SetCaret(new wxCaret(this, nCursorWidth, 10));
00163
00164
00165
00166
00167 EnableInput(TRUE);
00168 m_bSelectionEnabled = TRUE;
00169 m_bContextMenuEnabled = TRUE;
00170 m_bPreProcessingEnabled = TRUE;
00171
00172 UpdateCaretPos();
00173 UpdateCaret();
00174 }
00175
00176 void mgMathBox::EnableInput(bool bEnable)
00177 {
00178 m_bInputEnabled = bEnable;
00179
00180
00181 if (m_bInputEnabled) {
00182 SetCursor(wxCursor(wxCURSOR_IBEAM));
00183 } else {
00184 SetCursor(wxCursor(wxCURSOR_ARROW));
00185 }
00186
00187
00188 UpdateCaret();
00189 }
00190
00191 void mgMathBox::DeepCopy(const mgMathBox &tocopy)
00192 {
00193
00194 m_mathContent.data_DeepCopy(tocopy.m_mathContent);
00195
00196 m_rcSelection = tocopy.m_rcSelection;
00197 m_bProcSpecialChar = tocopy.m_bProcSpecialChar;
00198
00199
00200 }
00201
00202 void mgMathBox::Clean()
00203 {
00204
00205 m_mathContent.data_Clear();
00206
00207
00208
00209 GetMathObj().gui_AddEmptyLineToNewAndSystem();
00210
00211
00212
00213
00214 ResetGUI();
00215 }
00216
00217 wxString mgMathBox::GetDebug() const
00218 {
00219
00220 return m_mathContent.data_GetDebug(0, mcELEMENT_DBG_SELECTION);
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 wxSize mgMathBox::GetContentSize() const
00232 {
00233 int w = m_mathContent.gui_GetWidth()+nSpaceAround*2,
00234 h = m_mathContent.gui_GetHeight()+nSpaceAround*2;
00235
00236 return wxSize(w, h);
00237 }
00238
00239 void mgMathBox::FitContents()
00240 {
00241
00242
00243 wxSize min = GetContentSize();
00244 SetSize(min);
00245 UpdateContentPos();
00246
00247
00248
00249
00250 }
00251
00252 void mgMathBox::SetSizeHintsToFitContents()
00253 {
00254 FitContents();
00255
00256
00257
00258 wxSize s = GetContentSize();
00259 SetSizeHints(s.GetWidth(), s.GetHeight());
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269 void mgMathBox::UpdateContentPos()
00270 {
00271 wxSize sz(GetClientSize()), mathsz(GetContentSize());
00272
00273
00274 m_ptPos.y = (sz.GetHeight()-mathsz.GetHeight())/2;
00275
00276
00277 m_ptPos.x = (sz.GetWidth()-mathsz.GetWidth())/2;
00278
00279
00280 if (m_ptPos.x < 0) m_ptPos.x = 0;
00281 if (m_ptPos.y < 0) m_ptPos.y = 0;
00282 }
00283
00284 void mgMathBox::UpdateCaret()
00285 {
00286
00287 mgCaret *cur = GetCaret();
00288 if (!cur) return;
00289
00290
00291 if (!m_bInputEnabled || isSelecting()) {
00292
00293
00294 cur->ForceHide();
00295
00296 } else {
00297
00298 cur->ForceShow();
00299 }
00300
00301
00302
00303 }
00304
00305 void mgMathBox::UpdateCaretPos()
00306 {
00307 wxClientDC dc(this);
00308 int n;
00309
00310
00311 wxPoint p = m_mathContent.gui_GetRelCursorPos(dc, GetXPos(), GetYPos(), &n);
00312 mcASSERT(n != 0, wxT("Cursor is not positioned in a valid point..."));
00313
00314
00315 wxCaret *cur = GetCaret();
00316 if (!cur) return;
00317 cur->Move(p);
00318 cur->SetSize(nCursorWidth, n);
00319
00320 UpdateCaret();
00321 }
00322
00323 int mgMathBox::UpdateMathBmp(long flags, const wxPoint &p)
00324 {
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 int x=GetXPos(), y=GetYPos();
00346 int ret = m_mathContent.gui_UpdateBmp(x, y, flags, p);
00347
00348
00349 if (m_mathContent.gui_NeedsRefresh()) {
00350
00351 wxClientDC dc(this);
00352 RedrawMath(dc, x, y);
00353 }
00354
00355
00356 if (m_mathContent.gui_isIDChanged()) {
00357
00358 wxCommandEvent ev(mgEVT_ACTIVE_ELEM_CHANGED, GetId());
00359 ev.SetExtraLong(m_mathContent.gui_GetActiveElemID());
00360 if (m_pClient) m_pClient->AddPendingEvent(ev);
00361 }
00362
00363 return ret;
00364 }
00365
00366 void mgMathBox::UpdateMathBmpWithCurrentPos()
00367 {
00368 wxPoint p = wxGetMousePosition();
00369
00370
00371 p = ScreenToClient(p);
00372
00373
00374 UpdateMathBmp(mcDRW_USEPOINT, p);
00375 }
00376
00377 void mgMathBox::ForceBmpUpdate()
00378 {
00379 int x=GetXPos(), y=GetYPos();
00380 wxPoint p = wxGetMousePosition();
00381
00382
00383 p = ScreenToClient(p);
00384
00385
00386 m_mathContent.gui_ForceBmpUpdate(x, y, mcDRW_USEPOINT, p);
00387
00388
00389 wxClientDC dc(this);
00390 RedrawMath(dc, x, y);
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400 void mgMathBox::RedrawMath(wxDC &dc, int x, int y)
00401 {
00402
00403 #if 0
00404 mgCaret *caret = GetCaret();
00405 if (caret) caret->ForceHide();
00406 #endif
00407 m_mathContent.gui_DrawBmp(dc, x, y);
00408
00409
00410
00411 UpdateCaret();
00412 }
00413
00414 void mgMathBox::ResetGUI()
00415 {
00416 m_mathContent.gui_SetCursorPos(mcCP_BEGIN);
00417 m_mathContent.gui_UpdateExpDepth();
00418 m_mathContent.gui_DeepRecalcSize();
00419
00420
00421 ForceBmpUpdate();
00422 UpdateContentPos();
00423 UpdateCaretPos();
00424 Refresh();
00425 }
00426
00427 void mgMathBox::CheckReturnFlag(int res)
00428 {
00429 switch (res) {
00430 case mcMCR_SETFOCUS_PREVIOUS:
00431 case mcMCR_SETFOCUS_NEXT:
00432 case mcMCR_SETFOCUS_ABOVE:
00433 case mcMCR_SETFOCUS_BELOW:
00434 mcMathCore::Get()->SyntaxError(wxT("Cannot move cursor beyond math data"));
00435 break;
00436
00437 case mcMCR_CANNOT_SETFOCUS:
00438
00439
00440 break;
00441 }
00442 }
00443
00444
00445
00446
00447
00448
00449
00450 void mgMathBox::OnPaint(wxPaintEvent &ev)
00451 {
00452 wxCaretSuspend cs(this);
00453 wxPaintDC dc(this);
00454
00455
00456 dc.BeginDrawing();
00457
00458
00459 dc.SetBrush(*wxCYAN_BRUSH);
00460 dc.DrawRectangle(m_rcSelection);
00461
00462
00463 RedrawMath(dc, GetXPos(), GetYPos());
00464
00465
00466 dc.EndDrawing();
00467
00468
00469 mgLogBoxEvent(wxT("mgMathBox::OnPaint() - window repainted"));
00470 }
00471
00472 void mgMathBox::OnSize(wxSizeEvent &se)
00473 {
00474
00475
00476 UpdateCaretPos();
00477
00478
00479
00480 wxClientDC dc(this);
00481 dc.SetPen(*wxWHITE_PEN);
00482 dc.SetBrush(*wxWHITE_BRUSH);
00483 dc.DrawRectangle(m_ptPos, GetContentSize());
00484
00485
00486 UpdateContentPos();
00487 UpdateCaretPos();
00488 RedrawMath(dc, GetXPos(), GetYPos());
00489
00490
00491 mgLogBoxEvent(wxT("mgMathBox::OnSize() - window resized"));
00492 }
00493
00494 void mgMathBox::OnSpecialChar(wxKeyEvent &ke)
00495 {
00496 m_bProcSpecialChar = TRUE;
00497 OnChar(ke);
00498 m_bProcSpecialChar = FALSE;
00499 }
00500
00501 void mgMathBox::OnChar(wxKeyEvent &ke)
00502 {
00503 wxClientDC dc(this);
00504 int r, mod=mcMCF_NOMODIFIERS;
00505
00506
00507
00508
00509
00510 if (ke.AltDown()) {
00511 ke.Skip();
00512 return;
00513 }
00514
00515
00516
00517 if (ke.GetKeyCode() == WXK_START
00518 #ifdef __WXMSW__
00519 || ke.GetKeyCode() == 397
00520 #endif
00521 ) {
00522 ke.Skip();
00523 return;
00524 }
00525
00526
00527 if (!m_bInputEnabled) {
00528 wxBell();
00529 return;
00530 }
00531
00532
00533 if (ke.ShiftDown())
00534 mod = mcMCF_EXTEND_SELECTION;
00535
00536
00537 if (ke.GetKeyCode() >= 65 && ke.GetKeyCode() <= 90 && ke.ShiftDown())
00538 ke.m_shiftDown = FALSE;
00539
00540 switch (ke.m_keyCode) {
00541
00542
00543 case WXK_LEFT:
00544 r = m_mathContent.gui_MoveCursor(mcMCF_LEFT, mod);
00545 CheckReturnFlag(r);
00546 UpdateCaretPos();
00547 break;
00548 case WXK_RIGHT:
00549 r = m_mathContent.gui_MoveCursor(mcMCF_RIGHT, mod);
00550 CheckReturnFlag(r);
00551 UpdateCaretPos();
00552 break;
00553 case WXK_UP:
00554 r = m_mathContent.gui_MoveCursor(mcMCF_UP, mod);
00555 CheckReturnFlag(r);
00556 UpdateCaretPos();
00557 break;
00558 case WXK_DOWN:
00559 r = m_mathContent.gui_MoveCursor(mcMCF_DOWN, mod);
00560 CheckReturnFlag(r);
00561 UpdateCaretPos();
00562 break;
00563 case WXK_HOME:
00564 m_mathContent.gui_SetCursorPos(mcCP_BEGIN);
00565 UpdateCaretPos();
00566 break;
00567 case WXK_END:
00568 m_mathContent.gui_SetCursorPos(mcCP_END);
00569 UpdateCaretPos();
00570 break;
00571
00572
00573 default:
00574
00575 if (!m_bProcSpecialChar) {
00576
00577
00578
00579 if (ke.m_keyCode >= WXK_NUMPAD0 && ke.m_keyCode <= WXK_NUMPAD9)
00580 return;
00581
00582 #ifdef __WXMSW__
00583
00584
00585 if (ke.ControlDown() && ke.GetKeyCode() == 10) {
00586
00587
00588 if ((ke.GetRawKeyFlags() >> 16) == 28)
00589 ke.m_keyCode = 13;
00590 }
00591 #endif
00592 }
00593
00594 #ifdef __WXGTK__
00595
00596
00597 ke.m_metaDown = false;
00598 #endif
00599
00600
00601 mcKey mykey(ke);
00602
00603
00604
00605 wxChar c = ke.GetKeyCode();
00606 if (m_bProcSpecialChar || c == mcMMRO_LESS ||
00607 c == mcMMRO_GREATER || c == mcMMRO_EQUAL)
00608 mykey.SetAsSpecialKey();
00609
00610
00611
00612 mgLogBoxEvent(wxT("mgMathBox::OnChar() - before processing: [%s]"),
00613 m_mathContent.io_GetInlinedExpr().c_str());
00614 m_mathContent.gui_Input(mykey, NULL);
00615 mgLogBoxEvent(wxT("mgMathBox::OnChar() - after processing: [%s]"),
00616 m_mathContent.io_GetInlinedExpr().c_str());
00617
00618
00619 if (m_bAutoExpand)
00620 FitContents();
00621
00622 UpdateContentPos();
00623 UpdateCaretPos();
00624
00625 Refresh();
00626 ForceBmpUpdate();
00627
00628 }
00629
00630
00631 mgLogBoxEvent(wxT("mgMathBox::OnChar() - input handled"));
00632 }
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 void mgMathBox::OnSetCursor(wxSetCursorEvent &ev)
00643 {
00644 SetCursor(wxCursor(wxCURSOR_ARROW));
00645
00646
00647 mgLogBoxEvent(wxT("mgMathBox::OnSetCursor() - cursor has been set"));
00648 }
00649
00650 void mgMathBox::OnLeaveWindow(wxMouseEvent &ev)
00651 {
00652
00653
00654
00655
00656 UpdateMathBmp(mcDRW_NONACTIVE);
00657
00658
00659 mgLogBoxEvent(wxT("mgMathBox::OnLeaveWindow() - cursor has leaved the box"));
00660 }
00661
00662 void mgMathBox::OnLDown(wxMouseEvent &me)
00663 {
00664
00665
00666 if (!m_bSelectionEnabled)
00667 return;
00668
00669
00670 bool needsupdate = m_mathContent.gui_isSelected();
00671 m_mathContent.gui_DeSelect();
00672 if (needsupdate) ForceBmpUpdate();
00673
00674
00675 wxClientDC dc(this);
00676 wxPoint pt = me.GetLogicalPosition(dc);
00677
00678
00679 m_rcSelection.x = pt.x;
00680 m_rcSelection.y = pt.y;
00681
00682
00683
00684 m_rcSelection.width = 0;
00685 m_rcSelection.height = 0;
00686
00687
00688
00689 CaptureMouse();
00690
00691
00692 UpdateCaret();
00693
00694
00695
00696 mgLogBoxEvent(wxT("mgMathBox::OnLDown() - started selection dragging"));
00697 }
00698
00699 void mgMathBox::OnLUp(wxMouseEvent &me)
00700 {
00701
00702
00703
00704 if (GetCapture() == this) {
00705
00706
00707
00708
00709 ResetSelectionRect();
00710
00711
00712 ReleaseMouse();
00713
00714
00715 wxClientDC dc(this);
00716 wxPoint pt = me.GetLogicalPosition(dc);
00717 wxRect rc(GetRectOfContents());
00718
00719
00720 if (rc.Inside(pt)) {
00721
00722
00723
00724 m_mathContent.gui_MoveCursorUsingPoint(dc,
00725 wxPoint(pt.x-rc.x, pt.y-rc.y));
00726
00727
00728
00729
00730
00731
00732 } else {
00733
00734 if (pt.x < rc.x) {
00735
00736
00737 m_mathContent.gui_SetCursorPos(mcCP_BEGIN);
00738
00739 } else if (pt.x > rc.x+rc.width) {
00740
00741
00742 m_mathContent.gui_SetCursorPos(mcCP_END);
00743
00744 } else if (pt.y < rc.y || pt.y > rc.y+rc.height) {
00745
00746
00747
00748 pt.y = rc.y+m_mathContent.gui_GetHeight()/2;
00749 m_mathContent.gui_MoveCursorUsingPoint(dc,
00750 wxPoint(pt.x-rc.x, pt.y-rc.y));
00751 }
00752 }
00753
00754
00755 UpdateCaretPos();
00756 UpdateCaret();
00757
00758
00759
00760 mgLogBoxEvent(wxT("mgMathBox::OnLUp() - selection ended (%d elements selected)"),
00761 m_mathContent.gui_isSelected());
00762 }
00763 }
00764
00765 void mgMathBox::OnRUp(wxMouseEvent &me)
00766 {
00767
00768 if (!m_bContextMenuEnabled)
00769 return;
00770
00771
00772 wxClientDC dc(this);
00773 wxPoint tmp = me.GetLogicalPosition(dc);
00774 if (m_mathContent.gui_GetActiveElemID() != mcDRW_ONSELECTION) {
00775
00776
00777
00778 m_rcSelection.x = tmp.x;
00779 m_rcSelection.y = tmp.y;
00780 m_rcSelection.width = 1;
00781 m_rcSelection.height = 1;
00782
00783
00784
00785
00786 if (m_rcSelection.Intersects(GetRectOfContents())) {
00787
00788
00789
00790 m_rcSelection.x-=GetXPos();
00791 m_rcSelection.y-=GetYPos();
00792 m_mathContent.gui_OnSelect(dc, m_rcSelection);
00793 ForceBmpUpdate();
00794
00795 }
00796
00797
00798 }
00799
00800
00801 wxMenu m;
00802 m_eSelection = m_mathContent.gui_GetSelection();
00803 GetContextMenu(m, m_eSelection);
00804
00805
00806 PopupMenu(&m, tmp);
00807
00808
00809 mgLogBoxEvent(wxT("mgMathBox::OnRUp() - popped the context menu"));
00810 }
00811
00812 void mgMathBox::OnMouseMove(wxMouseEvent &me)
00813 {
00814 wxClientDC dc(this);
00815
00816
00817 wxPoint tmp = me.GetLogicalPosition(dc);
00818
00819 if (GetCapture() == this) {
00820
00821
00822
00823
00824
00825 m_rcSelection.width = tmp.x-m_rcSelection.x;
00826 m_rcSelection.height = tmp.y-m_rcSelection.y;
00827
00828
00829 wxRect rc(m_rcSelection);
00830 if (rc.width < 0) {
00831 rc.x += rc.width;
00832 rc.width = -rc.width;
00833 }
00834 if (rc.height < 0) {
00835 rc.y += rc.height;
00836 rc.height = -rc.height;
00837 }
00838
00839
00840 if (rc.width == 0) rc.width++;
00841 if (rc.height == 0) rc.height++;
00842
00843
00844 mcASSERT(rc.width > 0 && rc.height > 0, wxT("invalid rect"));
00845 wxRect mathrc(GetRectOfContents());
00846 if (!mathrc.Intersects(rc))
00847 return;
00848
00849
00850 rc.Offset(-mathrc.x, -mathrc.y);
00851 m_mathContent.gui_OnSelect(dc, rc);
00852
00853
00854
00855 ForceBmpUpdate();
00856
00857 } else {
00858
00859
00860
00861 UpdateMathBmp(mcDRW_USEPOINT, tmp);
00862 }
00863
00864
00865 mgLogBoxEvent(wxT("mgMathBox::OnMouseMove() - mouse movement handled"));
00866 }
00867
00868
00869
00870
00871
00872
00873
00874 void mgMathBox::OnSetFocus(wxFocusEvent &fe)
00875 {
00876
00877 mgLogDebug(wxT("mgMathBox::OnSetFocus() - focus set"));
00878 }
00879
00880 void mgMathBox::OnFocusLost(wxFocusEvent &fe)
00881 {
00882
00883 mgLogDebug(wxT("mgMathBox::OnSetFocus() - focus lost"));
00884 }
00885
00886
00887
00888
00889
00890
00891
00892 void mgMathBox::OnCtxMenuItem(wxCommandEvent &ce)
00893 {
00894 wxClientDC dc(this);
00895
00896
00897 switch (ce.GetId()-mgMATHBOX_CONTEXTMENU_BASEID) {
00898 case mgMBC_CUT:
00899 Cut(m_eSelection);
00900 break;
00901
00902 case mgMBC_COPY_ASPLAIN:
00903 CopyAsPlainText(m_eSelection);
00904 break;
00905
00906 case mgMBC_COPY_ASMATHML:
00907 CopyAsMathML(m_eSelection);
00908 break;
00909
00910 case mgMBC_SELECTALL:
00911 m_mathContent.gui_SelectAll();
00912 break;
00913
00914 case mgMBC_PASTE:
00915 Paste(m_eSelection);
00916 break;
00917
00918 case mgMBC_EMBED_NUMFRACTION:
00919 EmbedAsFractionNum(m_eSelection);
00920 break;
00921
00922 case mgMBC_EMBED_DENFRACTION:
00923 EmbedAsFractionDen(m_eSelection);
00924 break;
00925
00926 case mgMBC_CREATENEW_ANDLINE:
00927 m_mathContent.gui_AddEmptyLineToLastAndSystem();
00928 break;
00929
00930 case mgMBC_CREATENEW_ORLINE:
00931 m_mathContent.gui_AddEmptyLineToNewAndSystem();
00932 break;
00933
00934 #ifdef __MGDEBUG__
00935 case mgMBC_DEBUG:
00936
00937
00938 mgLogDebug(m_mathContent.data_GetDebug(0,
00939 mcELEMENT_DBG_EXPDEPTH | mcELEMENT_DBG_SELECTION | mcELEMENT_DBG_ID));
00940 break;
00941 #endif
00942
00943 default:
00944 break;
00945
00946
00947
00948 }
00949
00950
00951 ResetGUI();
00952
00953
00954 mgLogBoxEvent(wxT("mgMathBox::OnCtxMenuItem - context menu click handled"));
00955 }
00956
00957 void mgMathBox::GetContextMenu(wxMenu &m, const mcElement &selection) const
00958 {
00959 int j;
00960
00961
00962 for (j=0; j<mgMBC_SIMPLEEND; j++)
00963 m.Append(mgMATHBOX_CONTEXTMENU_BASEID+cmd[j].m_nID,
00964 cmd[j].m_strDescription);
00965 m.AppendSeparator();
00966
00967
00968 for (j=mgMBC_SIMPLEEND+1; j<mgMBC_ADVEND; j++)
00969 m.Append(mgMATHBOX_CONTEXTMENU_BASEID+cmd[j].m_nID,
00970 cmd[j].m_strDescription);
00971
00972
00973 wxArrayString arr;
00974 if (selection != mcEmptyElement) {
00975
00976
00977
00978
00979 } else {
00980 }
00981
00982
00983 int startid=mgMATHBOX_CONTEXTMENU_MATHCMD_BASEID+m.GetMenuItemCount();
00984 if (arr.GetCount()) m.AppendSeparator();
00985 for (j=0; j < (int)arr.GetCount(); j++)
00986 m.Append(startid+j, arr.Item(j));
00987
00988 #ifdef __WXDEBUG__
00989 m.AppendSeparator();
00990 m.Append(mgMATHBOX_CONTEXTMENU_BASEID+mgMBC_DEBUG, wxT("View debug info"));
00991 #endif
00992 }
00993
00994
00995
00996
00997
00998
00999
01000 void mgMathBox::InsertFraction() {
01001 wxKeyEvent fakekey = mcFractionHelpers::sgui_pNewFraction->GetEvent();
01002 OnSpecialChar(fakekey);
01003 }
01004
01005 void mgMathBox::InsertRadical() {
01006 wxKeyEvent fakekey = mcRadicalHelpers::sgui_pNewRadical->GetEvent();
01007 OnSpecialChar(fakekey);
01008 }
01009
01010 void mgMathBox::InsertFunction() {
01011 wxKeyEvent fakekey = mcFunctionHelpers::sgui_pNewFunction->GetEvent();
01012 OnSpecialChar(fakekey);
01013 }
01014
01015 void mgMathBox::EditExponent() {
01016 wxKeyEvent fakekey = mcMathCore::Get()->m_pEditExpKey->GetEvent();
01017 OnSpecialChar(fakekey);
01018 }
01019
01020 void mgMathBox::EditSubscript() {
01021 wxKeyEvent fakekey = mcMathCore::Get()->m_pEditSubscriptKey->GetEvent();
01022 OnSpecialChar(fakekey);
01023 }
01024
01025 void mgMathBox::Cut(const mcElement &sel)
01026 {
01027
01028 CopyAsPlainText(sel);
01029
01030
01031 m_mathContent.gui_DeleteSelection();
01032 }
01033
01034 #define mgGET_SEL(x) \
01035 mcElement x(sel); \
01036 if (x == mcEmptyElement) { \
01037 x = m_mathContent.gui_GetSelection(); \
01038 if (x == mcEmptyElement) \
01039 return; \
01040 }
01041
01042 void mgMathBox::CopyAsPlainText(const mcElement &sel)
01043 {
01044 mgGET_SEL(elem);
01045
01046 wxString str(elem.io_GetInlinedExpr());
01047 str = ConvertString(str);
01048
01049
01050 if (wxTheClipboard->Open())
01051 {
01052
01053
01054 wxTheClipboard->SetData( new wxTextDataObject(str) );
01055 wxTheClipboard->Close();
01056 }
01057 }
01058
01059 void mgMathBox::CopyAsMathML(const mcElement &sel)
01060 {
01061 mgGET_SEL(elem);
01062
01063 wxXml2Document doc;
01064 wxStringOutputStream stream;
01065 wxXml2Node math(elem.io_GetMathML(TRUE));
01066
01067 doc.Create();
01068 doc.SetRoot(math);
01069
01070 if (doc.Save(stream, wxT("UTF-8"), wxXML2DOC_USE_NATIVE_NEWLINES | wxXML2DOC_USE_INDENTATION) == -1)
01071 return;
01072
01073 math.DestroyIfUnlinked();
01074 doc.DestroyIfUnlinked();
01075
01076
01077 if (wxTheClipboard->Open())
01078 {
01079
01080
01081 wxTheClipboard->SetData( new wxTextDataObject(stream.GetStr()) );
01082 wxTheClipboard->Close();
01083 }
01084 }
01085
01086 void mgMathBox::Paste(const mcElement &sel)
01087 {
01088
01089 wxMessageBox(wxT("Still not working..."), wxT("Sorry"));
01090 return;
01091
01092
01093 if (!wxTheClipboard->Open() ||
01094 !wxTheClipboard->IsSupported( wxDF_TEXT ))
01095 return;
01096
01097
01098 wxTextDataObject data;
01099 wxTheClipboard->GetData( data );
01100 wxString str = data.GetText();
01101 wxTheClipboard->Close();
01102
01103
01104 mcPolynomial pol;
01105 wxString err;
01106 if (!pol.io_ImportInlinedExpr(str, NULL, err)) {
01107 wxBell();
01108 return;
01109 }
01110
01111
01112 mcInsertRes r(m_mathContent.gui_Insert(pol, NULL));
01113 if (r != mcINSR_OKAY) {
01114 wxBell();
01115 return;
01116 }
01117 }
01118
01119 void mgMathBox::EmbedAsFractionNum(const mcElement &sel)
01120 {
01121 mcMathLine ¤t = m_mathContent.gui_GetFocusLine();
01122 mcPolynomial &pol = current.gui_GetFocusMem();
01123 pol.math_EmbedInFraction(FALSE);
01124 }
01125
01126 void mgMathBox::EmbedAsFractionDen(const mcElement &sel)
01127 {
01128 mcMathLine ¤t = m_mathContent.gui_GetFocusLine();
01129 mcPolynomial &pol = current.gui_GetFocusMem();
01130 pol.math_EmbedInFraction(TRUE);
01131 }
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 wxString mgMathBox::ConvertString(const wxString &str) const
01142 {
01143 if (!bUseNativeNewLines)
01144 return str;
01145
01146 wxString ret(str);
01147 #if defined(__WXMSW__)
01148 ret.Replace(wxT("\n"), wxT("\r\n"));
01149 #elif defined(__WXMAC__)
01150 ret.Replace(wxT("\n"), wxT("\n\r"));
01151 #endif
01152 return ret;
01153 }
01154
01155 bool mgMathBox::Export(bool bXHTML, const wxString &filename,
01156 const wxString &title, bool bMathPlayer, bool bUpperTag,
01157 bool bUseNS, const wxString &ns, const wxString &href,
01158 int indentstep) const
01159 {
01160 wxFile f;
01161 wxString err;
01162
01163
01164
01165 mcASSERT(filename.Len() > 0, wxT("Incorrect file name"));
01166 if (f.Open(filename, wxFile::write) == FALSE) {
01167
01168 err.Printf(wxT("Cannot overwrite %s. The file is being used by another application\n")
01169 wxT("which opened the file in exclusive mode. Close all the applications that use\n")
01170 wxT("this file and retry, or choose another file name."), filename.c_str());
01171 wxMessageBox(err, wxT("Error"), wxICON_ERROR | wxOK | wxCENTRE);
01172 return FALSE;
01173 }
01174
01175 wxFileOutputStream stream(f);
01176 mcASSERT(stream.Ok(), wxT("Something wrong with the creation of file"));
01177
01178
01179
01180 return Export(bXHTML, stream, title, bMathPlayer,
01181 bUpperTag, bUseNS, ns, href, indentstep);
01182 }
01183
01184 wxString mgMathBox::GetExportPreview(bool bXHTML, const wxString &title,
01185 bool bMathPlayer, bool bUpperTag,
01186 bool bUseNS, const wxString &ns,
01187 const wxString &href, int indentstep) const
01188 {
01189 wxStringOutputStream sos;
01190
01191 if (Export(bXHTML, sos, title, bMathPlayer,
01192 bUpperTag, bUseNS, ns, href, indentstep) == FALSE)
01193 return wxString(wxT("CANNOT PREVIEW !!!"));
01194
01195
01196 return sos.GetStr();
01197 }
01198
01199 bool mgMathBox::Export(bool bXHTML, wxOutputStream &stream,
01200 const wxString &title, bool bMathPlayer,
01201 bool bUpperTag, bool bUseNS, const wxString &ns,
01202 const wxString &href, int indentstep) const
01203 {
01204 wxString err, str;
01205
01206
01207 wxXml2Document doc;
01208 doc.Create();
01209 doc.SetMathMLDTD();
01210
01211 wxXml2Node html;
01212 html.CreateRoot(doc, wxT("html"));
01213
01214
01215
01216 if (!bXHTML)
01217 doc.SetStyleSheet(href);
01218
01219
01220
01221
01222 if (!bUseNS) {
01223
01224
01225 html.AddProperty(wxT("xmlns"), wxT("http://www.w3.org/1999/xhtml"));
01226
01227 } else {
01228
01229
01230 html.AddProperty(wxT("xmlns:") + ns, wxT("http://www.w3.org/1998/Math/MathML"));
01231 }
01232
01233 html.AddProperty(wxT("lang"), wxT("en"));
01234 html.AddProperty(wxT("xml:lang"), wxT("en"));
01235
01236
01237
01238
01239
01240 html.AddContainerChild(wxT("head"));
01241 html.Get(wxT("head")).AddTextChild(wxT("title"), title);
01242 wxXml2Node body = html.AddContainerChild(wxT("body"));
01243
01244
01245
01246
01247
01248 body.AddCommentChild(
01249 wxT(" MathML 2.0 exported by MathStudio - http://mathstudio.sourceforge.net - ") \
01250 wxT("MathStudio is an open source program released under GPL; please write to ") \
01251 wxT("frm@users.sourceforge.net if you encounter any problem or if you want to ") \
01252 wxT("give suggestions or advices. "));
01253
01254
01255
01256 wxXml2Node mathcontent(m_mathContent.io_GetMathML(TRUE));
01257
01258
01259
01260
01261
01262 wxXml2Node math(wxXML_ELEMENT_NODE, body, wxT("math"));
01263 wxString prefix(ns);
01264
01265
01266 if (bUseNS) {
01267
01268 if (bMathPlayer) {
01269
01270
01271
01272
01273
01274 wxXml2Node parent(html.Get(wxT("head")));
01275 wxXml2Node obj(wxXML_TEXT_NODE, parent, wxT("object"));
01276 wxXml2Node import(wxXML_ELEMENT_NODE, parent, wxT("import"));
01277
01278 obj.AddProperty(wxT("id"), wxT("MathPlayer"));
01279 obj.AddProperty(wxT("classid"), wxT("clsid:32F66A20-7614-11D4-BD11-00104BD3F987"));
01280
01281
01282
01283
01284 import.SetType(wxXML_PI_NODE);
01285 import.SetContent(wxT("namespace=\"") + ns + wxT("\" implementation=\"#MathPlayer\""));
01286 }
01287
01288
01289
01290 wxXml2Namespace mathns(prefix, wxT("http://www.w3.org/1998/Math/MathML"), math);
01291
01292 } else {
01293
01294
01295
01296
01297 math.AddProperty(wxT("xmlns"), wxT("http://www.w3.org/1998/Math/MathML"));
01298 }
01299
01300
01301 math.AddChild(mathcontent);
01302
01303
01304 math.AddProperty(wxT("display"), wxT("block"));
01305 math.AddProperty(wxT("mode"), wxT("display"));
01306
01307
01308
01309
01310
01311 if (bUpperTag) {
01312
01313
01314 doc.GetRoot().MakeUpper();
01315 }
01316
01317
01318 doc.Save(stream, wxT("UTF-8"), indentstep);
01319
01320
01321 html.DestroyIfUnlinked();
01322 math.DestroyIfUnlinked();
01323 body.DestroyIfUnlinked();
01324 mathcontent.DestroyIfUnlinked();
01325
01326
01327 doc.DestroyIfUnlinked();
01328
01329
01330 return TRUE;
01331 }
01332
01333 bool mgMathBox::Import(int type, const wxString &filename, wxString *pDesc)
01334 {
01335 wxXml2Document doc;
01336 wxXml2Node root, cur;
01337 wxString str, err;
01338 int n=0;
01339
01340
01341 mcASSERT(filename.Len() > 0, wxT("Incorrect file name"));
01342
01343
01344 wxFileInputStream def(filename);
01345 wxString file(filename);
01346 wxString tmpfilename;
01347
01348 if (def.Ok() == FALSE) {
01349
01350
01351 err.Printf(wxT("Cannot read %s. The file is being used by another application\n") \
01352 wxT("which opened the file in exclusive mode. Close all the applications that use\n") \
01353 wxT("this file and retry, or choose another file."), filename.c_str());
01354 wxMessageBox(err, wxT("Error"), wxICON_ERROR | wxOK | wxCENTRE);
01355 return FALSE;
01356 }
01357
01358
01359 def.Read(str.GetWriteBuf(16), 16);
01360 str.UngetWriteBuf();
01361 def.SeekI(0);
01362
01363 if (str.CmpNoCase(wxT("<?xml")) != 0 || str.CmpNoCase(wxT("<? xml")) != 0) {
01364
01365
01366
01367 tmpfilename = wxFileName::CreateTempFileName(wxT("ms"));
01368 wxFileOutputStream tmpoutstream(tmpfilename);
01369
01370 wxString xmlhdr = wxT("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n")
01371 wxT("<?xml-stylesheet type=\"text/xsl\" href=\")") + wxGetCwd() +
01372 wxT("/XSL/mathml.xsl\"?>\n");
01373
01374 tmpoutstream.Write(xmlhdr, xmlhdr.Len());
01375
01376 tmpoutstream.Write(def);
01377 file = tmpfilename;
01378 }
01379
01380
01381 if (doc.Load(file, &err) == FALSE) {
01382
01383
01384 wxMessageBox(wxT("There was an error while parsing and the given file\n")
01385 wxT("couldn't be imported. Error description:\n\n'") + err + wxT("'"),
01386 wxT("Error"), wxICON_ERROR | wxOK | wxCENTRE);
01387 if (!tmpfilename.IsEmpty())
01388 wxRemoveFile(tmpfilename);
01389 return FALSE;
01390 }
01391
01392
01393 if (!tmpfilename.IsEmpty())
01394 wxRemoveFile(tmpfilename);
01395
01396
01397 root = doc.GetRoot();
01398 cur = root.Find(wxT("math"), wxT(""), 0, FALSE);
01399
01400 if (cur == wxXml2EmptyNode) {
01401
01402 err.Printf(wxT("Cannot find the MathML main tag <MATH>. The file does not contain\n")
01403 wxT("any MathML information or it is corrupt."));
01404 wxMessageBox(err, wxT("Error"), wxICON_ERROR | wxOK | wxCENTRE);
01405 return FALSE;
01406 }
01407
01408
01409 while (cur != wxXml2EmptyNode) {
01410
01411 wxXml2Node toparse = cur.GetChildren();
01412
01413 while (toparse != wxXml2EmptyNode) {
01414
01415
01416 if (toparse.GetType() == wxXML_ELEMENT_NODE) {
01417
01418 if (toparse.GetName() != wxT("mrow"))
01419 toparse.Encapsulate(wxT("mrow"));
01420
01421
01422
01423 m_mathContent.io_ImportPresentationMathML(toparse, err);
01424 }
01425
01426 toparse = toparse.GetNext();
01427 }
01428
01429
01430 cur = root.Find(wxT("math"), wxT(""), n, FALSE);
01431 }
01432
01433 root.DestroyIfUnlinked();
01434 cur.DestroyIfUnlinked();
01435 doc.DestroyIfUnlinked();
01436
01437 return TRUE;
01438 }
01439
01440 bool mgMathBox::ImportInlinedExpr(const wxString &str)
01441 {
01442 bool res = m_mathContent.io_ImportInlinedExpr(str);
01443
01444
01445 m_mathContent.gui_SetFocusIdx(m_mathContent.data_GetCount()-1);
01446 m_mathContent.gui_SetCursorPos(mcCP_END);
01447 ResetGUI();
01448
01449 return res;
01450 }
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460 IMPLEMENT_CLASS(mgResizeableBox, wxResizeableControl)
01461 BEGIN_EVENT_TABLE(mgResizeableBox, wxResizeableControl)
01462
01463
01464 EVT_SIZE(mgResizeableBox::OnSize)
01465 EVT_PAINT(mgResizeableBox::OnPaint)
01466
01467 EVT_KILL_FOCUS(mgResizeableBox::OnKillFocus)
01468 EVT_SET_CURSOR(mgResizeableBox::OnSetCursor)
01469
01470 EVT_MOVE(mgResizeableBox::OnMove)
01471
01472
01473
01474 EVT_CHILD_RESIZED(wxID_ANY, mgResizeableBox::OnChildResize)
01475
01476
01477
01478 END_EVENT_TABLE()
01479
01480
01481 mgResizeableBox::mgResizeableBox(wxWindow *parent,
01482 wxWindowID id,
01483 const wxPoint &pos,
01484 const wxSize &size) :
01485 wxResizeableControl(parent, id, pos, size, wxSIMPLE_BORDER |
01486 wxCLIP_CHILDREN | wxNO_FULL_REPAINT_ON_RESIZE, wxT("ResizeableBox"))
01487 {
01488
01489
01490
01491 SetMinBorder(wxResizeableControl::SizeXRad*2+1);
01492
01493
01494
01495
01496
01497 wxMoveEvent ev(pos);
01498
01499 this->AddPendingEvent(ev);
01500 }
01501
01502 mgResizeableBox::mgResizeableBox(const mgResizeableBox &tocopy) :
01503 wxResizeableControl(tocopy.GetParent(), tocopy.GetId(),
01504 tocopy.GetPosition(), tocopy.GetClientSize(),
01505 tocopy.GetWindowStyle(), tocopy.GetName())
01506 {
01507
01508 DeepCopy(tocopy);
01509 }
01510
01511 void mgResizeableBox::DeepCopy(const mgResizeableBox &tocopy)
01512 {
01513
01514 m_nMinBorder = tocopy.m_nMinBorder;
01515 }
01516
01517 int mgResizeableBox::GetBorder()
01518 {
01519
01520
01521
01522
01523 return m_nMinBorder;
01524 }
01525
01526 void mgResizeableBox::SetMinBorder(int n)
01527 {
01528
01529 m_nMinBorder = n;
01530 if (GetChild()) GetChild()->Move(GetBorder(), GetBorder());
01531
01532
01533 wxSizeEvent ev(GetClientSize());
01534 OnSize(ev);
01535 }
01536
01537
01538
01539
01540
01541
01542
01543
01544 wxString mgResizeableBox::GetDebug()
01545 {
01546 return wxT("If you want to get debug info about this resizeable box, ") \
01547 wxT("override the GetDebug() function.");
01548 }
01549
01550 void mgResizeableBox::OnChildResize(wxCommandEvent &event)
01551 {
01552 if (GetChild()) {
01553 int w = GetChild()->GetSize().GetWidth()+GetBorder()*2+2,
01554 h = GetChild()->GetSize().GetHeight()+GetBorder()*2+2;
01555 wxSize newsz = GetSize();
01556
01557
01558 if (w > newsz.GetWidth()) newsz.SetWidth(w);
01559 if (h > newsz.GetHeight()) newsz.SetHeight(h);
01560 SetSize(newsz);
01561
01562 Refresh();
01563 }
01564 }
01565
01566 void mgResizeableBox::OnSize(wxSizeEvent &event)
01567 {
01568 if (GetChild() && m_hasfocus) {
01569
01570
01571 event.m_size.SetWidth(event.GetSize().GetWidth()-GetBorder()*2-2);
01572 event.m_size.SetHeight(event.GetSize().GetHeight()-GetBorder()*2-2);
01573
01574
01575 event.m_id = GetChild()->GetId();
01576
01577
01578 GetChild()->SetSize(event.GetSize());
01579 }
01580
01581
01582 event.Skip();
01583 }
01584
01585
01586
01587
01588
01589 void mgResizeableBox::OnSetFocus(wxFocusEvent &event)
01590 {
01591
01592
01593
01594
01595
01596
01597
01598 event.Skip();
01599 }
01600
01601 void mgResizeableBox::OnChildSetFocus(wxCommandEvent &ev)
01602 {
01603
01604 if (!m_hasfocus) {
01605 Raise();
01606 Update();
01607 m_hasfocus = true;
01608 }
01609
01610 wxClientDC dc(this);
01611 ForceDrawSizeRect(dc);
01612
01613 mgLogDebug(wxT("mgResizeableBox::OnChildSetFocus [%d] child has received focus"), GetId());
01614 }
01615
01616
01617
01618
01619
01620 bool isChildren(wxWindow *parent, wxWindow *child)
01621 {
01622 for (wxWindowList::Node *tocheck = parent->GetChildren().GetFirst(); tocheck;
01623 tocheck = tocheck->GetNext()) {
01624 if (child == tocheck->GetData() || isChildren(tocheck->GetData(), child))
01625 return TRUE;
01626 }
01627
01628 return FALSE;
01629 }
01630
01631 void mgResizeableBox::OnKillFocus(wxFocusEvent &event)
01632 {
01633
01634
01635
01636 event.Skip();
01637 }
01638
01639 void mgResizeableBox::OnChildKillFocus(wxCommandEvent &event)
01640 {
01641 wxWindow *focused = FindFocus();
01642 if (!isChildren(this, focused) && focused != this) {
01643
01644
01645 m_hasfocus = false;
01646 wxClientDC dc(this);
01647 EraseSizeRect(dc);
01648
01649
01650
01651
01652 mgLogDebug(wxT("mgResizeableBox::OnChildKillFocus [%d] focus ") \
01653 wxT("has been definetely lost"), GetId());
01654
01655 } else {
01656
01657 mgLogDebug(wxT("mgResizeableBox::OnChildKillFocus [%d] focus has ") \
01658 wxT("been set on the resizeable control or one of its children"), GetId());
01659 }
01660 }
01661
01662
01663
01664
01665 void mgResizeableBox::OnMove(wxMoveEvent &ev)
01666 {
01667
01668
01669
01670
01671
01672
01673
01674 if (GetChild())
01675 GetChild()->Move(ev.GetPosition().x+GetBorder(), ev.GetPosition().y+GetBorder());
01676
01677
01678
01679 }
01680
01681 void mgResizeableBox::OnPaint(wxPaintEvent &ev)
01682 {
01683 if (m_hasfocus) {
01684 wxPaintDC dc(this);
01685
01686 wxBrush brsh(wxColour(0, 0, 0), wxBDIAGONAL_HATCH );
01687 dc.SetBrush(brsh);
01688 dc.DrawRectangle(wxPoint(0, 0), GetClientSize());
01689
01690
01691
01692 DrawSizeRect(dc);
01693 }
01694
01695
01696
01697 }
01698
01699
01700
01701
01702
01703
01704
01705 void mgResizeableBox::OnSetCursor(wxSetCursorEvent &ev)
01706 {
01707
01708
01709 if (!GetChild() || !GetChild()->GetRect().Inside(wxPoint(ev.GetX(), ev.GetY())))
01710 ev.Skip();
01711 }
01712
01713
01714
01715
01716
01718
01719 IMPLEMENT_CLASS(mgResizeableMathBox, mgResizeableBox)
01720 BEGIN_EVENT_TABLE(mgResizeableMathBox, mgResizeableBox)
01721
01722
01723
01724
01725 END_EVENT_TABLE()
01726
01727
01728 mgResizeableMathBox::mgResizeableMathBox(wxWindow *parent,
01729 wxWindowID id, const wxPoint &pos, const wxSize &size) :
01730 mgResizeableBox(parent, id, pos, size)
01731 {
01732 m_pMathBox = new mgMathBox(this);
01733 SetMinBorder(wxResizeableControl::SizeXRad*2+1);
01734
01735
01736
01737
01738
01739
01740 }
01741
01742 mgResizeableMathBox::mgResizeableMathBox(const mgResizeableMathBox &tocopy) :
01743 mgResizeableBox(tocopy.GetParent(), tocopy.GetId(), tocopy.GetPosition(),
01744 tocopy.GetClientSize())
01745 {
01746 m_pMathBox = new mgMathBox(*tocopy.m_pMathBox);
01747
01748
01749 DeepCopy(tocopy);
01750 }
01751
01752 void mgResizeableMathBox::DeepCopy(const mgResizeableMathBox &tocopy)
01753 {
01754 mgResizeableBox::DeepCopy(tocopy);
01755
01756
01757 m_pMathBox->DeepCopy(*tocopy.m_pMathBox);
01758 }
01759
01760 wxString mgResizeableMathBox::GetDebug()
01761 {
01762 return m_pMathBox->GetDebug();
01763 }
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01781
01782 IMPLEMENT_CLASS(mgResizeableTextBox, mgResizeableBox)
01783 BEGIN_EVENT_TABLE(mgResizeableTextBox, mgResizeableBox)
01784
01785 END_EVENT_TABLE()
01786
01787
01788 mgResizeableTextBox::mgResizeableTextBox(
01789 wxWindow *parent,
01790 wxWindowID id,
01791 const wxPoint &pos,
01792 const wxSize &size) :
01793
01794 mgResizeableBox(parent, id, pos, size)
01795 {
01796
01797
01798 m_pTextCtrl = new wxTextCtrl(parent, -1, wxT(""), wxDefaultPosition,
01799 wxDefaultSize, wxTE_MULTILINE);
01800
01801
01802
01803
01804 SetMinBorder(wxResizeableControl::SizeXRad*2+1);
01805 }
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827 wxString mgResizeableTextBox::GetDebug()
01828 {
01829 return wxT("Resizeable TEXT box content: ") + m_pTextCtrl->GetValue();
01830 }
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051