Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

MathWnd.cpp

Go to the documentation of this file.
00001 
00002 // MathGUI = 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 //                                                                   //
00030 
00031 
00032 
00033 // optimization for GCC compiler
00034 #ifdef __GNUG__
00035    #pragma implementation "MathWnd.h"
00036 #endif
00037 
00038 
00039 // includes
00040 #include "mg/mgprec.h"
00041 #include <wx/wfstream.h>      // not included by wxprec.h
00042 #include <wx/mstream.h>
00043 
00044 #ifndef mgPRECOMP
00045    #include "mg/MathWnd.h"
00046 #endif
00047 
00048 
00049 
00050 
00051 // tell Doxygen not to parse the following lines
00052 #ifndef DOXYGEN_SKIP
00053 
00054 // Creates the array of mgMathBox structures
00055 #include <wx/arrimpl.cpp>  // this is a magic incantation which must be done!
00056 WX_DEFINE_OBJARRAY(wxMathBoxArray);
00057 
00058 #endif
00059 
00060 
00061 #define CMATHWND_SPACE_LEFT         10
00062 #define CMATHWND_SPACE_RIGHT     10
00063 #define CMATHWND_SPACE_ABOVE     10
00064 #define CMATHWND_SPACE_BOTTOM    10
00065 
00066 #define CMATHWND_DEFAULT_BOXWIDTH   140
00067 #define CMATHWND_DEFAULT_BOXHEIGHT  80
00068 
00069 
00070 // the event tables connect the wxWidgets events with the functions (event
00071 // handlers) which process them. It can be also done at run-time, but for the
00072 // simple menu events like this the static method is much simpler.
00073 IMPLEMENT_CLASS(mgMathWnd, wxScrolledWindow)
00074 BEGIN_EVENT_TABLE(mgMathWnd, wxScrolledWindow)
00075 
00076    // children change handlers
00077     EVT_CHILD_CREATED(wxID_ANY, mgMathWnd::OnChildWindowChange)
00078     EVT_CHILD_MOVED(wxID_ANY, mgMathWnd::OnChildWindowChange)
00079     EVT_CHILD_RESIZED(wxID_ANY, mgMathWnd::OnChildWindowChange)
00080     EVT_CHILD_CLOSED(wxID_ANY, mgMathWnd::OnChildWindowChange)
00081 
00082    // focus events
00083    //EVT_SET_FOCUS(mgMathWnd::OnSetFocus)
00084 /* EVT_KILL_FOCUS(mgMathWnd::OnFocusLost)
00085 
00086    // miscellaneous events
00087    EVT_SIZE(mgMathWnd::OnSize)*/
00088    //EVT_PAINT(mgMathWnd::OnPaint)
00089 
00090    // mouse events
00091 /* EVT_RIGHT_DOWN(mgMathWnd::OnRDown)
00092    EVT_RIGHT_UP(mgMathWnd::OnRUp)
00093    EVT_LEFT_DOWN(mgMathWnd::OnLDown)
00094    EVT_LEFT_UP(mgMathWnd::OnLUp)
00095    EVT_MOTION(mgMathWnd::OnMouseMove)
00096 
00097    // keyboard events
00098    EVT_CHAR(mgMathWnd::OnChar)
00099 
00100    // context menu events
00101    EVT_MENU_RANGE(CUSTOMID_BASE, CUSTOMID_BASE+MAXMENU_ITEMS, mgMathWnd::OnCtxMenuItem)*/
00102 END_EVENT_TABLE()
00103 
00104 
00105 
00106 
00107 
00109 // Constructor\Destructor
00110 mgMathWnd::mgMathWnd(wxWindow *parent, wxWindowID id, 
00111       const wxPoint &pos) : wxScrolledWindow(parent, -1, 
00112       pos, parent->GetSize(), wxSUNKEN_BORDER | wxHSCROLL | wxVSCROLL | 
00113                            wxNO_FULL_REPAINT_ON_RESIZE, wxT("MathWnd"))
00114 {
00115    SetFocus();
00116    //GetCaret()->Show();
00117    
00118    // set white as the window background color
00119    SetBackgroundColour(wxColour(255, 255, 255));
00120    
00121    // init all
00122    Clean();
00123    
00124    // SetFocus() seems not to work properly; place a SetFocus event
00125    // on the queue... 
00126    wxFocusEvent evt(wxEVT_SET_FOCUS, GetId());
00127    GetEventHandler()->AddPendingEvent(evt);
00128 
00129    Refresh();
00130 }
00131 
00132 mgMathWnd::~mgMathWnd() {
00133    
00134    // wxMathBoxArray will automatically delete all allocated objects...
00135    // it's too easy !!! :-)
00136 }
00138 
00139 
00141 // GENERAL functions
00142 void mgMathWnd::Clean()
00143 {
00144    // delete everything
00145    GetChildren().DeleteContents(TRUE);
00146    GetChildren().Clear();
00147    
00148    // re init
00149    m_nSelBox = 0;
00150    m_nActiveElemID = -1;
00151    AddBox(FALSE, FALSE);
00152    
00153    // update cursor position, bitmap of current line and client size
00154    //UpdateCaretPos();
00155    //CheckNewSize();
00156    //UpdateBoxBmp(0);
00157 }
00158 
00159 wxString mgMathWnd::GetDebug()
00160 {
00161    wxString str;
00162 
00163    str = wxT("\n------------- Math window debug info: -------------\n\n");
00164    for (int i=0; i < GetBoxCount(); i++) {
00165 
00166       str += wxString::Format(wxT("||||||||||| MATH BOX #%d:\n"), i);
00167       str += GetBox(i)->GetDebug();
00168    }
00169 
00170    return str;
00171 }
00173 
00174 
00176 // SCROLLBAR functions
00177 void mgMathWnd::UpdateScrollRange()
00178 {
00179     wxNode *Child = GetChildren().First();
00180     wxSize GesSize;
00181     while (Child)
00182     {
00183         wxWindow *chw = wxDynamicCast(Child->GetData(),wxResizeableControl);
00184         if (chw)
00185         {
00186             wxRect rect = chw->GetRect();
00187             rect.x += GetScrollPos(wxHORIZONTAL);
00188             rect.y += GetScrollPos(wxVERTICAL);
00189             if (rect.GetBottom() > GesSize.y)
00190                 GesSize.y = rect.GetBottom();
00191             if (rect.GetRight() > GesSize.x)
00192                 GesSize.x = rect.GetRight();
00193         }
00194         Child = Child->Next();
00195     }
00196     SetScrollbars(1,1,GesSize.x,GesSize.y,
00197       GetScrollPos(wxHORIZONTAL),GetScrollPos(wxVERTICAL),true);
00198 }
00200 
00201 
00203 // CURSOR functions
00204 /*
00205 void mgMathWnd::UpdateCaretPos()
00206 {
00207    // get current cursor position   
00208    wxDC dc;
00209    int n;
00210 
00211    GetCaret()->Move(GetBox(m_nSelBox)->GetCursorPos(dc, GetBox(m_nSelBox)->GetPosition().x, 
00212       GetBox(m_nSelBox), &n))->GetPosition().y;
00213    GetCaret()->SetSize(mgMathWnd_CURSOR_WIDTH, n);
00214 }
00215 /*
00216 void mgMathWnd::SetCursorColor(wxColour col)
00217 {
00218    //m_brushCursor.SetColour(col);
00219    //m_penCursor.SetColour(col);
00220 }*/
00221 /*
00222 void mgMathWnd::UpdateBB(wxDC &dc, wxPoint &cursor)
00223 {
00224    // this function must be as fast as possible (it's called at every
00225    // mouse movement)
00226    
00227    // create some variables (remember that the window maybe scrolled)
00228    wxRect rc(GetBox(m_nSelBox), GetBox(m_nSelBox)->GetPosition()->GetPosition().y.x, 
00229       GetBox(m_nSelBox)->GetWidth(), GetBox(m_nSelBox)->GetHeight());
00230    
00231    // check if cursor is inside the bb of the selected line
00232    if (rc.Inside(cursor)) {
00233       
00234       // tranform from scrolled window coord to line coord.
00235       cursor.x -= GetBox(m_nSelBox)->GetPosition().x;
00236       cursor.y -= GetBox(m_nSelBox)->GetPosition().y;
00237       
00238       // update the bitmap of the line; this step cannot be skipped because
00239       // this function also checks cursor position and the function isIDChanged()
00240       // is based on this check...
00241       UpdateBoxBmp(&cursor);
00242       
00243    } else {
00244       
00245       // update the bitmap of the line; this step cannot be skipped because
00246       // this function also checks cursor position and the function isIDChanged()
00247       // is based on this check...
00248       UpdateBoxBmp(DRW_NONACTIVE);
00249    }
00250    
00251    // if the activation state hasn't changed, do nothing (to avoid
00252    // flickering)
00253    if (!GetBox(m_nSelBox)->isIDChanged())
00254       return;
00255    
00256    // redraw only the modified element
00257    ReDrawSelBox(dc);
00258 }
00259 /*
00260 void mgMathWnd::DrawCursor(bool bDraw)
00261 {
00262    // if user pressed a key, stop erasing the cursor for a while
00263    /*if (m_nWait > 0 && bDraw == FALSE) {
00264       m_nWait -= mgMathWnd_CURSOR_PERIOD;
00265       return;
00266    }
00267    
00268    // create a DC for the window
00269    wxDC dc;
00270    
00271    if (bDraw) {
00272       
00273       // draw a black cursor
00274       dc.SetBrush(m_brushCursor);
00275       dc.SetPen(m_penCursor);
00276       dc.DrawRectangle(m_rcLastPosCursor);
00277       
00278    } else {
00279       
00280       // to erase old cursor, blit the current used bitmap on
00281       // the screen (current used bitmap is stored with also
00282       // activation and selection state, but without cursor)
00283       DrawBoxBmp(dc, m_nSelBox);
00284    }
00285 }*/
00286 
00288 
00289 
00290 
00291 
00293 // BOX UTILITY functions
00294 /*
00295 int mgMathWnd::UpdateBoxBmp(const wxPoint &p)
00296 {
00297    return GetBox(m_nSelBox)->UpdateBoxBmp(m_hMemDC, GetBox(m_nSelBox), GetBox(m_nSelBox), p)->GetPosition()->GetPosition().y.x; 
00298 }*/
00299 
00300 
00301 /*
00302 void mgMathWnd::UpdateBoxBmp()
00303 {
00304    wxPoint p = wxGetMousePosition();
00305    
00306    // remap cursor position in the correct way
00307    ScreenToClient(p);      // from screen to window coord
00308    p.x -= GetBox(m_nSelBox)->GetPosition().x;   // from scrolled window to line coord
00309    p.y -= GetBox(m_nSelBox)->GetPosition().y;
00310    
00311    // use std version of the function
00312    UpdateBoxBmp(&p);
00313 }*/
00314 
00315 void mgMathWnd::SelectBox(int n)
00316 {
00317    //mcASSERT(n >= 0 && n < (int)GetBoxCount(), "Invalid new index");
00318    
00319    // save last line in the bitmap, without activation and selection state
00320    //GetBox(m_nSelBox)->DeSelect();
00321    //UpdateBoxBmp(m_nSelBox, DRW_NONACTIVE);
00322    
00323    // select the new line; caller should redraw to get a correct output
00324    m_nSelBox = n;
00325    /*wxFocusEvent ev(wxEVT_SET_FOCUS, GetBox(n)->GetId());
00326    GetBox(n)->OnSetFocus(ev);
00327    GetBox(n)->Refresh();*/
00328    //GetBox(n)->SetFocus();
00329    ((GetChildren().Item(n))->GetData())->SetFocus();
00330 
00331    // update the bitmap of the selected line
00332    //UpdateBoxBmp(m_nSelBox);
00333 }
00334 
00335 void mgMathWnd::AddBox(bool bMath, bool bCopyLast)
00336 {
00337    wxSize sz(CMATHWND_DEFAULT_BOXWIDTH, CMATHWND_DEFAULT_BOXHEIGHT);
00338    wxPoint pos(15, 15);
00339 
00340    if (GetBoxCount() > 0) {
00341       int n = GetBoxCount()-1;
00342       pos = GetBox(n)->GetPosition();
00343       pos.x += 0; pos.y += GetBox(n)->GetSize().GetHeight()+10;
00344       sz = GetBox(n)->GetSize();
00345    }
00346 
00347    // first of all, create a new mgMathBox
00348    mgResizeableBox *pnew;
00349    if (bMath)
00350       pnew = new mgResizeableMathBox(this, -1, pos, sz);
00351    else
00352       pnew = new mgResizeableTextBox(this, -1, pos, sz);
00353    m_arrMathBox.Add(pnew);
00354    
00355    // create some pointers
00356    mgResizeableBox *pold = GetSelBox();
00357    
00358    // select the new line (so the bitmap of the previous
00359    // selected line is updated)
00360    SelectBox(GetChildren().GetCount()-1);
00361    //mgResizeableBox *boh = GetSelBox();
00362    //mcASSERT(pnew == boh, "SelectBox doesn't work");
00363    
00364    // then, copy the last line if requested
00365    if (bCopyLast) {
00366       
00367       // deep copy everything
00368       pnew->DeepCopy(*pold);
00369    }
00370    
00371    // redraw
00372    Refresh();
00373 }
00374 
00375 /*
00376 void mgMathWnd::SelectBoxByPoint(wxPoint &pt)
00377 {
00378    wxRect rc;
00379    
00380    // set up some fixed data on the rect structure
00381    rc.width = GetClientSize().GetWidth();
00382    rc.x = GetBox(m_nSelBox)->GetPosition().x;
00383    
00384    // move the cursor on another data line
00385    for (int i=0; i < 1; i++) {
00386       
00387       // skip currently selected line; we have already tested
00388       // that it's not the line where the user clicked
00389       if (i == m_nSelBox) continue;
00390       
00391       // set up the rect for this line
00392       rc.y = GetBox(m_nSelBox)->GetPosition().y;
00393       rc.height = GetBox(m_nSelBox)->GetHeight();
00394       
00395       // is the cursor inside this line's rectangle ?
00396       if (rc.Inside(pt)) {
00397          
00398          // yes, select it
00399          SelectBox(i);
00400          
00401          // update cursor data
00402          UpdateCaretPos();
00404          
00405          // redraw and exit this event handler
00406          Refresh();
00407          return;
00408       }
00409    }
00410    
00411    // no lines have been selected; deselect the current line
00412    GetBox(m_nSelBox)->DeSelect();
00413    UpdateBoxBmp(m_nSelBox, &pt);
00414    Refresh();
00415 }
00416 */
00417 void mgMathWnd::DeleteBox(int n)
00418 {
00419    // removes the selected line
00420    (GetChildren().Item(n)->GetData())->Destroy();
00421    
00422    // select previous if following does not exist
00423    if (m_nSelBox >= 1)
00424       m_nSelBox--;
00425    
00426    // redraw window
00427    Refresh();
00428 }
00430 
00431 
00432 
00433 
00435 // mgMathWnd EVENT HANDLERS
00436 
00437 void mgMathWnd::OnChildWindowChange(wxCommandEvent &ev)
00438 {
00439    // check which child window sent this message
00440    wxWindow *w = FindWindowById(ev.GetId(), this);
00441    if (w != NULL) {
00442       wxPoint newpos = w->GetPosition();
00443       if (w->GetPosition().x < 0) newpos.x = 0;
00444       if (w->GetPosition().y < 0) newpos.y = 0;
00445       
00446       w->Move(newpos);
00447    }
00448 
00449    // scrollbar range could have changed
00450    UpdateScrollRange();
00451 }
00452 
00453 void mgMathWnd::OnPaint(wxPaintEvent &ev)
00454 {
00455    wxPaintDC dc(this);
00456 
00457    // on MS windows, this sets up some optimizations
00458    dc.BeginDrawing();
00459    
00460    // draw all the lines
00461    //int y = GetBox(m_nSelBox)->GetPosition().y;
00462    //DrawBoxBmp(dc, TRUE);
00463 
00464    for (int i=0; i < (int)m_arrMathBox.GetCount(); i++) {
00465       
00466       // draw the line using stored bitmap
00467       //DrawBoxBmp(dc, i, TRUE);
00468       
00469       // add the space between two lines
00470       //y += mgMathWnd_SPACE_INTERLINE;
00471       GetBox(i)->Refresh();
00472    }
00473 
00474 
00475    // be sure to unselect from memory DC previous bmp
00476    //m_hMemDC.SelectObject(wxNullBitmap);
00477    
00478    // on MS windows, shut down draw optimizations
00479    dc.EndDrawing();
00480 }
00481 
00482 void mgMathWnd::OnSize(wxSizeEvent &se)
00483 {
00484    //int w = se.GetSize().GetWidth()-GetBox(m_nSelBox)->GetPosition().x-CMATHWND_SPACE_RIGHT;
00485    
00486    // update width inside all lines; this is required for line
00487    // description feature
00488    /*for (int i=0; i < 1; i++)
00489       GetBox(m_nSelBox)->SetParentWidth(w);*/
00490    
00491    // update also cursor pos (it could be inside line description)
00492    //UpdateCaretPos();
00493 }
00494 
00495 
00497 // MOUSE events
00498 /*
00499 void mgMathWnd::OnLDown(wxMouseEvent &me)
00500 {
00501    // stop flashing cursor
00502    GetCaret()->Show(FALSE);
00503    
00504    // prepare some variables
00505    wxDC dc;
00506    wxPoint pt = me.GetLogicalPosition(dc);
00507    
00508    // get some data
00509    wxRect rc(GetBox(m_nSelBox), GetBox(m_nSelBox), GetBox(m_nSelBox)->GetWidth()->GetPosition()->GetPosition().y.x, 
00510       GetBox(m_nSelBox)->GetHeight());// = GetBoxBB(m_nSelBox);
00511    
00512    // move the cursor where user clicked
00513    if (rc.Inside(pt)) {
00514       
00515       // move the cursor inside the math data
00516       GetBox(m_nSelBox)->MoveCursor(dc, MC_USEPOINT, pt.x, pt.y-GetBox(m_nSelBox))->GetPosition().y;
00517       UpdateCaretPos();
00518       
00519    } /*else {
00520       
00521       // try to select line using the point
00522       SelectBoxByPoint(pt);
00523    }*/
00524    /*
00525    // set up the capture of the cursor
00526    m_ptOrigin = pt;
00527    
00528    m_rcSelection.x = m_ptOrigin.x;
00529    m_rcSelection.y = m_ptOrigin.y;
00530    
00531    // capture the mouse (so, if it exits the window
00532    // the OnLUP function will still be called)
00533    CaptureMouse();
00534    
00535    // change cursor
00536    //SetCursor(wxCursor(wxCURSOR_RIGHT_ARROW));//*wxCROSS_CURSOR);
00537 }
00538 
00539 void mgMathWnd::OnRDown(wxMouseEvent &me)
00540 {
00541    //wxDC dc;
00542    //wxMenu m;
00543    //wxPoint pt = me.GetLogicalPosition(dc);
00544    //OnLDown(me);
00545    
00546    //SelectBoxByPoint(pt);
00547    //GetBox(m_nSelBox)->GetMathObj()->MultiplyBySel();
00548    
00549    //UpdateBoxBmp(m_nSelBox, &pt);
00550    //ReDrawSelBox(dc);
00551    
00552    //PopupMenu(&m, me.GetPosition());
00553 }
00554 
00555 void mgMathWnd::OnLUp(wxMouseEvent &me)
00556 {
00557    // maybe the user just selected another data line
00558    if (GetCapture() == this) {
00559       
00560       // restore the conditions before the user started the click
00561       ReleaseMouse();
00562       //SetCursor(wxNullCursor);
00563       //m_tCursor.Start();
00564       
00565       // move the cursor inside the math data
00566       wxDC dc;
00567       wxPoint pt = me.GetLogicalPosition(dc);
00568       wxRect rc(GetBox(m_nSelBox), GetBox(m_nSelBox)->GetPosition()->GetPosition().y.x, 
00569          GetBox(m_nSelBox)->GetWidth(), GetBox(m_nSelBox)->GetHeight());
00570       
00571       // check if point is over the selected line
00572       if (rc.Inside(pt)) {
00573          
00574          // user released button over the selected line; move the cursor
00575          // to the nearest available position
00576          GetBox(m_nSelBox)->MoveCursor(dc, MC_USEPOINT, pt.x, pt.y-GetBox(m_nSelBox))->GetPosition().y;
00577          UpdateCaretPos();
00578       } else if (!rc.Inside(m_ptOrigin)) {
00579          
00580          // user clicked in an empty area and released the button in another
00581          // empty area
00582          //OnSyntaxErr("Nothing in that point");
00583       }
00584       
00585       /*wxString tmp;
00586       tmp.Printf(wxT("top-left: %d, %d\n\nwidth: %d\nheight: %d\n\norigin: %d, %d"), m_rcSelection.x, m_rcSelection.y, m_rcSelection.width, m_rcSelection.height, m_ptOrigin.x, m_ptOrigin.y);
00587       wxMessageBox(tmp, _(wxT("About g_nsMathStudio")), wxOK | wxICON_INFORMATION, this);*/
00588 /* }
00589 }
00590 
00591 void mgMathWnd::OnRUp(wxMouseEvent &me)
00592 {
00593    wxDC dc;
00594    wxMenu m;
00595    
00596    // get the point in scrolled window coord
00597    wxPoint tmp = me.GetLogicalPosition(dc);
00598    
00599    if (m_nActiveElemID != DRW_ONSELECTION) {
00600       
00601       // create a dummy selection rectangle
00602       m_rcSelection.x = tmp.x;
00603       m_rcSelection.y = tmp.y;
00604       m_rcSelection.width = 1;
00605       m_rcSelection.height = 1;
00606       
00607       // select the element under cursor
00608       int n = GetBox(m_nSelBox)->GetPosition().y;
00609       GetBox(m_nSelBox)->OnSelect(dc, GetBox(m_nSelBox), GetBox(m_nSelBox), m_rcSelection)->GetPosition()->GetPosition().y.x;
00610       UpdateBoxBmp(&tmp);
00611       ReDrawSelBox(dc);
00612    }
00613    
00614    // get an array of string from the math object
00615    wxArrayString arr = GetBox(m_nSelBox)->GetPossibleOpOnSel(m_nCmdID);
00616    for (int i=0; i < (int)arr.GetCount(); i++) {
00617       m.Append(CUSTOMID_BASE+i, arr.Item(i));
00618    }
00619    
00620    // pop up the context menu
00621    PopupMenu(&m, tmp);
00622 }
00623 
00624 void mgMathWnd::OnCtxMenuItem(wxCommandEvent &ce)
00625 {
00626    wxDC dc;
00627    
00628    // exec the command chosen by the user
00629    GetBox(m_nSelBox)->ExecCmdOnSel(m_nCmdID[ce.GetId()-CUSTOMID_BASE-2]);
00630    //GetBox(m_nSelBox)->GetMathObj()->Debug();
00631    
00632    // update cursor pos and redraw the window
00633    //CheckNewSize();
00634    UpdateCaretPos();
00635    UpdateBoxBmp();
00636    
00637    // redraw only modified line
00638    ReDrawSelBox(dc);
00639 }
00640 
00641 void mgMathWnd::OnMouseMove(wxMouseEvent &me)
00642 {  
00643    wxDC dc;
00644    
00645    // get the point in scrolled window coord
00646    wxPoint tmp = me.GetLogicalPosition(dc);
00647    
00648    if (me.LeftIsDown()) {
00649       
00650       // update selection rectangle
00651       m_rcSelection.x = m_ptOrigin.x;
00652       m_rcSelection.y = m_ptOrigin.y;
00653       m_rcSelection.width = tmp.x-m_ptOrigin.x;
00654       m_rcSelection.height = tmp.y-m_ptOrigin.y;
00655       if (m_rcSelection.width < 0) {
00656          m_rcSelection.x += m_rcSelection.width;
00657          m_rcSelection.width = -m_rcSelection.width;
00658       }
00659       if (m_rcSelection.height < 0) {
00660          m_rcSelection.y += m_rcSelection.height;
00661          m_rcSelection.height = -m_rcSelection.height;
00662       }
00663       
00664       // check that everything's okay
00665       mcASSERT(m_rcSelection.width >= 0 && m_rcSelection.height >= 0, wxT("invalid rect"));
00666       mcASSERT(m_rcSelection.x >= 0 && m_rcSelection.y >= 0, wxT("invalid rect"));
00667       
00668       // update selection
00669       GetBox(m_nSelBox)->OnSelect(dc, GetBox(m_nSelBox), GetBox(m_nSelBox), m_rcSelection)->GetPosition()->GetPosition().y.x;
00670       
00671       // redraw for some strange reasons... :-)
00673       ReDrawSelBox(dc);
00674    }
00675    
00676    UpdateBB(dc, tmp);
00677 }
00678 
00679 
00680 
00682 // FOCUS events
00683 */
00684 void mgMathWnd::OnSetFocus(wxFocusEvent &fe)
00685 {
00686    //for (int i=0; i < GetBoxCount(); i++)
00687    // GetBox(i)->SetFocus();
00688 }
00689 /*
00690 void mgMathWnd::OnFocusLost(wxFocusEvent &fe)
00691 {
00692    // stop drawing cursor
00693    //m_tCursor.Stop();
00694    
00695    // erase it, and the next time, draw it
00696    //DrawCursor(FALSE);//, NULL);
00697    //m_nShow = TRUE;
00698 }
00699 
00700 
00701 
00703 // MISCELLANEOUS events
00704 
00705 void mgMathWnd::OnTimer(wxTimerEvent &te)
00706 {
00707    // draw or erase the cursor
00708    //DrawCursor(m_nShow);//, NULL);
00709    
00710    // next time, do the opposite
00711    //m_nShow = !m_nShow;
00712 }
00713 
00714 void mgMathWnd::OnChar(wxKeyEvent &ke)
00715 {
00716    wxDC dc;
00717    
00718    switch (ke.m_keyCode) {
00719       
00720       // cursor movement keys handlers
00721    case WXK_LEFT:
00722       GetBox(m_nSelBox)->MoveCursor(dc, mcMCF_LEFT, 0, 0);
00723       break;
00724    case WXK_RIGHT:
00725       GetBox(m_nSelBox)->MoveCursor(dc, mcMCF_RIGHT, 0, 0);
00726       break;
00727    case WXK_UP:
00728       GetBox(m_nSelBox)->MoveCursor(dc, mcMCF_UP, 0, 0);
00729       break;
00730    case WXK_DOWN:
00731       GetBox(m_nSelBox)->MoveCursor(dc, mcMCF_DOWN, 0, 0);
00732       break;
00733    case WXK_HOME:
00734       GetBox(m_nSelBox)->SetCursorPos(mcCP_BEGIN);
00735       break;
00736    case WXK_END:
00737       GetBox(m_nSelBox)->SetCursorPos(mcCP_END);
00738       break; 
00739       
00740       
00741    default:
00742       // a numpad key was pressed; ignore it; this function will be called
00743       // again, by wxWidgets, with a translated ASCII code
00744       if (ke.m_keyCode >= WXK_NUMPAD0 && ke.m_keyCode <= WXK_NUMPAD9)
00745          return;
00746 
00747       // a little exception: if user pressed CTRL+ENTER we must correct,
00748       // on win32 the key event which we receive....
00749       if (ke.ControlDown() && ke.GetKeyCode() == 10) {
00750 
00751 #ifdef __WXMSW__
00752          // Get Win32 native scancode
00753          if ((ke.GetRawKeyFlags() >> 16) == 28) // 28 = ENTER scancode
00754             ke.m_keyCode = 13;
00755 #endif
00756       }
00757       
00758       // one of ()0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
00759       // or abcdefghijklmnopqrstuvwxyz key was pressed
00760       GetBox(m_nSelBox)->Input(ke);//(unsigned char)ke.GetKeyCode(), (int)ke.GetKeyCode());
00761    }
00762    
00763    // update cursor pos and redraw the window
00764    //CheckNewSize(m_nSelBox);
00765    UpdateCaretPos();
00766    UpdateBoxBmp();
00767    
00768    // redraw only modified line
00769    ReDrawSelBox(dc);
00770 }
00772 
00773 
00774 */
00775 
00776 bool mgMathWnd::Export(bool bXHTML, const wxString &filename, 
00777                  const wxString &title, bool bMathPlayer, bool bUpperTag,
00778                  bool bUseNS, const wxString &ns, const wxString &href, 
00779                  int indentstep)
00780 {
00781    wxFile f;
00782    wxString err;
00783 
00784    // create a new file with the given name in write mode, 
00785    // overwrite existing if necessary
00786    mcASSERT(filename.Len() > 0, wxT("Incorrect file name"));
00787    if (f.Open(filename, wxFile::write) == FALSE) {
00788       
00789       err.Printf(wxT("Cannot overwrite %s. The file is being used by another application\n") \
00790          wxT("which opened the file in exclusive mode. Close all the applications that use\n") \
00791          wxT("this file and retry, or choose another file name."), filename.c_str());
00792       wxMessageBox(err, wxT("Error"), wxICON_ERROR | wxOK | wxCENTRE);
00793       return FALSE;
00794    }
00795 
00796    wxFileOutputStream stream(f);
00797    mcASSERT(stream.Ok(), wxT("Something wrong with the creation of file"));
00798 
00799    // write in the file using native line ending
00800    //wxTextOutputStream stream(fstream, wxEOL_NATIVE);
00801    return Export(bXHTML, stream, title, FALSE, bMathPlayer, 
00802                      bUpperTag, bUseNS, ns, href, indentstep);
00803 }
00804 
00805 wxString mgMathWnd::GetExportPreview(bool bXHTML, const wxString &title, bool bMathPlayer,
00806                   bool bUpperTag,   bool bUseNS, const wxString &ns, const wxString &href, 
00807                   int indentstep)
00808 {
00809    /*wxMemoryOutputStream mos;
00810    wxString res;
00811 
00812    if (Export(bXHTML, mos, title, TRUE, bMathPlayer, 
00813             bUpperTag, bUseNS, ns, href, indentstep) == FALSE)
00814       return wxString(wxT("CANNOT PREVIEW !!!"));
00815    
00816    // copy directly inside the string
00817    mos.CopyTo(res.GetWriteBuf(mos.GetSize()+1), mos.GetSize());
00818    res[mos.GetSize()] = wxT('\0');
00819    res.UngetWriteBuf();*/
00820 
00821    return wxEmptyString;
00822 }
00823 
00824 bool mgMathWnd::Export(bool bXHTML, wxOutputStream &stream, 
00825                  const wxString &title, bool bPreview, bool bMathPlayer, 
00826                   bool bUpperTag, bool bUseNS, const wxString &ns, 
00827                   const wxString &href, int indentstep)
00828 {
00829    wxString err, str;
00830 
00831 
00832    // close file and return OK 
00833    return TRUE;
00834 }
00835 
00836 bool mgMathWnd::Import(int type, const wxString &filename, wxString *pDesc)
00837 {
00838 /* wxXml2Document doc;
00839    wxXml2Node root, cur;
00840    wxString str, err;
00841    int n=0;
00842    
00843    // check parameters
00844    mcASSERT(filename.Len() > 0, wxT("Incorrect file name"));
00845    
00846    // load the given file
00847    wxFileInputStream def(filename); 
00848    wxString file(filename);
00849    wxString tmpfilename;
00850 
00851    if (def.Ok() == FALSE) {
00852       
00853       // load error
00854       err.Printf(wxT("Cannot read %s. The file is being used by another application\n") \
00855          wxT("which opened the file in exclusive mode. Close all the applications that use\n") \
00856          wxT("this file and retry, or choose another file."), filename.c_str());
00857       wxMessageBox(err, wxT("Error"), wxICON_ERROR | wxOK | wxCENTRE);  
00858       return FALSE;
00859    }
00860 
00861    // check if loaded file is an XML or an XHTML file
00862    def.Read(str.GetWriteBuf(16), 16);
00863    str.UngetWriteBuf();
00864    def.SeekI(0);
00865 
00866    if (str.CmpNoCase(wxT("<?xml")) != 0 || str.CmpNoCase(wxT("<? xml")) != 0) {
00867       
00868       // we must convert this (X)HTML file to an XML file; we will use
00869       // a temporary file
00870       tmpfilename = wxFileName::CreateTempFileName(wxT("ms"));
00871       wxFileOutputStream tmpoutstream(tmpfilename);
00872       
00873       wxString xmlhdr = wxT("<?xml version=\")1.0\wxT(" encoding=\")UTF-8\wxT(" standalone=\")no\wxT("?>\n")
00874          wxT("<?xml-stylesheet type=\")text/xsl\wxT(" href=\")" + wxGetCwd() +
00875          wxT("/XSL/mathml.xsl\")?>\n";
00876 
00877       tmpoutstream.Write(xmlhdr, xmlhdr.Len());    
00878       //tmpoutstream.SeekO(0, wxFromEnd);
00879       tmpoutstream.Write(def);
00880       file = tmpfilename;
00881    }
00882 
00883    // parse the given file
00884    if (doc.Load(file, &err) == FALSE) {
00885 
00886       // parse error
00887       wxMessageBox(wxT(wxT("There was an error while parsing and the given file\n")
00888          wxT("couldn't be imported. Error description:\n\n'")) + err + wxT("'"), 
00889          wxT("Error"), wxICON_ERROR | wxOK | wxCENTRE);
00890       if (!tmpfilename.IsEmpty())
00891          wxRemoveFile(tmpfilename);
00892       return FALSE;
00893    }
00894 
00895    // delete the eventually created temporary file
00896    if (!tmpfilename.IsEmpty())         
00897       wxRemoveFile(tmpfilename);
00898 
00899    // find MATH tags and import their contents; ignore everything else
00900    root = doc.GetRoot();
00901    cur = root.Find(wxT("math"), wxT(""), 0, FALSE);
00902    
00903    if (cur == wxXml2EmptyNode) {
00904       // we couldn't find it
00905       err.Printf(wxT("Cannot find the MathML main tag <MATH>. The file does not contain\n")
00906          wxT("any MathML information or it is corrupt."));
00907       wxMessageBox(err, wxT("Error"), wxICON_ERROR | wxOK | wxCENTRE);
00908       return FALSE;
00909    }
00910    
00911    // extract MathML content from the xml document
00912    while (cur != wxXml2EmptyNode) {
00913 
00914       wxXml2Node toparse = cur.GetChildren();
00915       
00916       while (toparse != wxXml2EmptyNode) {
00917 
00918          // be sure everything is embedded in an MROW section
00919          if (toparse.GetType() == wxXML_ELEMENT_NODE) {
00920             
00921             if (toparse.GetName() != wxT("mrow"))
00922                toparse = EncapsulateInMROW(toparse);
00923          
00924             // add a new line and import this MATH tags in it
00925             //if (n > 0) AddBox(FALSE);
00926             GetBox(m_nSelBox)->ImportMathML(toparse, &err);
00927          }
00928 
00929          toparse = toparse.GetNext();
00930       }
00931       
00932       // search other MATH tags
00933       cur = root.Find(wxT("math"), wxT(""), n, FALSE);
00934    }
00935    */
00936    return TRUE;
00937 }
00938 
00939 
00940 


Documentation generated with Doxygen on Sun Feb 6 17:19:26 2005
Visit MathStudio home page for more info

[ Top ]