X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2Fmath_cursor.C;h=382072e65afff0c999cba38459cc7a35025a59d2;hb=4590c8cfab02a3bc56813cfb1f2e80bd1119af9e;hp=81aba8a6a2e0eaaa37a2ed4fea1329298b56d096;hpb=7d2c9440e74368554d820d4c1fff22dddbd22e93;p=lyx.git diff --git a/src/mathed/math_cursor.C b/src/mathed/math_cursor.C index 81aba8a6a2..382072e65a 100644 --- a/src/mathed/math_cursor.C +++ b/src/mathed/math_cursor.C @@ -1,19 +1,19 @@ /* -* File: math_cursor.C -* Purpose: Interaction for mathed -* Author: Alejandro Aguilar Sierra -* Created: January 1996 -* Description: Math interaction for a WYSIWYG math editor. -* -* Dependencies: Xlib, XForms -* -* Copyright: 1996, Alejandro Aguilar Sierra -* -* Version: 0.8beta, Mathed & Lyx project. -* -* You are free to use and modify this code under the terms of -* the GNU General Public Licence version 2 or later. -*/ + * File: math_cursor.C + * Purpose: Interaction for mathed + * Author: Alejandro Aguilar Sierra + * Created: January 1996 + * Description: Math interaction for a WYSIWYG math editor. + * + * Dependencies: Xlib, XForms + * + * Copyright: 1996, Alejandro Aguilar Sierra + * + * Version: 0.8beta, Mathed & Lyx project. + * + * You are free to use and modify this code under the terms of + * the GNU General Public Licence version 2 or later. + */ #ifdef __GNUG__ #pragma implementation @@ -25,6 +25,7 @@ #include "math_parser.h" #include "math_cursor.h" #include "math_macro.h" +#include "math_macroarg.h" #include "math_macrotable.h" #include "math_root.h" #include "support/lstrings.h" @@ -43,12 +44,17 @@ #include "math_macrotemplate.h" #include "mathed/support.h" -static MathedArray selarray; + + using std::endl; +namespace { + +MathedArray selarray; + // This was very smaller, I'll change it later -static inline +inline bool IsMacro(short tok, int id) { return tok != LM_TK_STACK && @@ -63,74 +69,149 @@ bool IsMacro(short tok, int id) !(tok == LM_TK_SYM && id < 255); } -static int const MAX_STACK_ITEMS = 32; +int const MAX_STACK_ITEMS = 32; struct MathStackXIter { +public: + enum type {MATHSTK, SELSTK}; + +private: std::vector item; - int i; + int pos_; + type id_; - MathStackXIter(int n = MAX_STACK_ITEMS) - : item(n), i(0) { + +public: + + MathStackXIter(type id) + : item(MAX_STACK_ITEMS), pos_(-1), id_(id) { } MathedXIter * push() { - return &item[i++]; + //dump(); + ++pos_; + return &item[pos_]; } MathedXIter * pop() { - return &item[--i]; + //dump(); + item[pos_] = MathedXIter(); + --pos_; + return &item[pos_]; } MathedXIter * Item(int idx) { - return (idx + 1 <= i) ? &item[i - idx - 1] : 0; + if (idx > pos_) + lyxerr << "Wrong index: " << idx << " pos_: " << pos_ << endl; + return &item[pos_ - idx]; } void Reset() { - i = 0; + pos_ = -1; } bool Full() { - return i >= MAX_STACK_ITEMS; + return pos_ >= MAX_STACK_ITEMS - 2; + } + + bool empty() { + return pos_ <= 0; + } + + MathParInset * outer() { + return empty() ? 0 : item[0].getPar(); + } + + int Level() { + return pos_; + } + + MathParInset * parInset(int i) { + return pos_ < 0 ? 0 : item[i].getPar(); } - bool Empty() { - return i <= 1; + + void dump() { + lyxerr << "\n------------- MathStack ------------\n"; + for (int i = 0; i < pos_ + 3; ++i) { + lyxerr << "pos: " << i << " par: " + << item[i].getPar() << " data: '" + << *item[i].GetData() << "'" << endl; + } + lyxerr << "------------- MathStack ------------\n"; + } + +}; + +MathStackXIter mathstk = MathStackXIter(MathStackXIter::MATHSTK); +MathStackXIter selstk = MathStackXIter(MathStackXIter::SELSTK); + +} // namespace anon + + +extern MathedCursor * mathcursor; + +bool is_mathcursor_inside(MathParInset * p) +{ + //lyxerr << "called is_mathcursor_inside: " << p << endl; + + if (!mathcursor) { + //lyxerr << " mathcursor not set" << endl; + return false; } - int Level() { return i; } + for (int i = 0; i < mathstk.Level(); ++i) { + //lyxerr << " level: " << i << " " << mathstk.parInset(i) << endl; + if (mathstk.parInset(i) == p) { + //lyxerr << " found!" << endl; + return true; + } + } -} mathstk, selstk; + //lyxerr << " cursor: " << mathcursor->cursor->getPar() << endl; + if (mathcursor->cursor->getPar() == p) { + //lyxerr << " found!" << endl; + return true; + } + //lyxerr << " not found" << endl; + return false; +} /***---------------- Mathed Cursor ---------------------------***/ + MathedCursor::MathedCursor(MathParInset * p) // : par(p) { - accent = 0; - anchor = 0; - lastcode = LM_TC_MIN; + accent = 0; + anchor = 0; + lastcode = LM_TC_MIN; SetPar(p); - if (!MathMacroTable::built) - MathMacroTable::mathMTable.builtinMacros(); } - void MathedCursor::SetPar(MathParInset * p) { - macro_mode = false; - selection = false; // not SelClear() ? - mathstk.Reset(); - cursor = mathstk.push(); - par = p; - cursor->SetData(par); + macro_mode = false; + selection = false; // not SelClear() ? + mathstk.Reset(); + cursor = mathstk.push(); + par = p; + SetCursorData(par); +} + + +void MathedCursor::SetCursorData(MathParInset * p) +{ + //lyxerr << "SetCursorData: " << p << endl; + cursor->SetData(p); } void MathedCursor::draw(Painter & pain, int x, int y) { // lyxerr << "Cursor[" << x << " " << y << "] "; - //win = pm; // win = (mathedCanvas) ? mathedCanvas: pm; + //lyxerr << "MathedCursor::draw: par: " << par << endl; par->Metrics(); int w = par->Width() + 2; @@ -142,7 +223,7 @@ void MathedCursor::draw(Painter & pain, int x, int y) h += 8; } - pain.rectangle(x - 1, y - a, w, h, LColor::mathframe); + pain.rectangle(x - 1, y - a, w, h, LColor::green); par->draw(pain, x, y); cursor->Adjust(); @@ -160,14 +241,16 @@ void MathedCursor::Redraw(Painter & pain) par->GetXY(x, y); //mathed_set_font(LM_TC_VAR, 1); pain.fillRectangle(x, y - par->Ascent(), - x + w, y - par->Ascent() + h, - LColor::mathbg); + x + w, y - par->Ascent() + h, LColor::mathbg); + + lyxerr << "MathedCursor::Redraw: par: " << par << endl; par->draw(pain, x, y); } bool MathedCursor::Left(bool sel) { + //par->GetData().dump(cerr); if (macro_mode) { // was MacroModeBack() if (!imacro->GetName().empty()) { @@ -190,7 +273,7 @@ bool MathedCursor::Left(bool sel) bool result = cursor->Prev(); - if (!result && !mathstk.Empty()) { + if (!result && !mathstk.empty()) { cursor = mathstk.pop(); cursor->Adjust(); result = true; @@ -210,9 +293,10 @@ bool MathedCursor::Left(bool sel) if (!p) return result; + //lyxerr << "\nInset, max arg # " << p->getMaxArgumentIdx() << endl; p->setArgumentIdx(p->getMaxArgumentIdx()); cursor = mathstk.push(); - cursor->SetData(p); + SetCursorData(p); cursor->GoLast(); } } @@ -223,7 +307,7 @@ bool MathedCursor::Left(bool sel) // Leave the inset bool MathedCursor::Pop() { - if (!mathstk.Empty()) { + if (!mathstk.empty()) { cursor = mathstk.pop(); cursor->Next(); return true; @@ -240,7 +324,7 @@ bool MathedCursor::Push() if (!p) return false; cursor = mathstk.push(); - cursor->SetData(p); + SetCursorData(p); return true; } return false; @@ -274,22 +358,22 @@ bool MathedCursor::Right(bool sel) } if (!selection) { - MathParInset *p = cursor->GetActiveInset(); + MathParInset * p = cursor->GetActiveInset(); if (!p) { - lyxerr << "Math error: Inset expected." << endl; - return cursor->Next(); + lyxerr << "Math error: Inset expected." << endl; + return cursor->Next(); } p->setArgumentIdx(0); cursor = mathstk.push(); - cursor->SetData(p); + SetCursorData(p); result = true; } else result = cursor->Next(); } else { - if (cursor->GetChar()!= LM_TC_CR) - result = cursor->Next(); - if (!result && !mathstk.Empty()) { + if (cursor->GetChar() != LM_TC_CR) + result = cursor->Next(); + if (!result && !mathstk.empty()) { cursor = mathstk.pop(); cursor->Next(); cursor->Adjust(); @@ -312,16 +396,16 @@ void MathedCursor::SetPos(int x, int y) lastcode = LM_TC_MIN; mathstk.Reset(); cursor = mathstk.push(); - cursor->SetData(par); + SetCursorData(par); cursor->fitCoord(x, y); - while (cursor->GetX()OK()) { + while (cursor->GetX() < x && cursor->OK()) { if (cursor->IsActive()) { MathParInset * p = cursor->GetActiveInset(); if (p->Inside(x, y)) { p->SetFocus(x, y); cursor = mathstk.push(); - cursor->SetData(p); + SetCursorData(p); cursor->fitCoord(x, y); continue; } @@ -359,7 +443,7 @@ void MathedCursor::End() } -MathMatrixInset * create_multiline(short int type, int cols) +MathMatrixInset create_multiline(short int type, int cols) { int columns; string align; @@ -395,8 +479,8 @@ MathMatrixInset * create_multiline(short int type, int cols) break; } - MathMatrixInset * mt = new MathMatrixInset(columns, -1); - mt->SetAlign(' ', align); + MathMatrixInset mt(columns, -1); + mt.SetAlign(' ', align); return mt; } @@ -414,7 +498,7 @@ void MathedCursor::Insert(byte c, MathedTextCodes t) if (t == LM_TC_CR) { MathParInset * p = cursor->getPar(); - if (p == par && p->GetType()GetType()>LM_OT_MIN) { + if (p == par && p->GetType() < LM_OT_MPAR && p->GetType() > LM_OT_MIN) { short int type = LM_OT_MPAR; int cols = 1; if (c >= '1' && c <= '9') { @@ -430,7 +514,8 @@ void MathedCursor::Insert(byte c, MathedTextCodes t) if (p->GetType() == LM_OT_PARN) ++type; - MathMatrixInset * mt = create_multiline(type, cols); + MathMatrixInset * mt = + new MathMatrixInset(create_multiline(type, cols)); mt->SetStyle(LM_ST_DISPLAY); mt->SetType(type); mt->setData(p->GetData()); @@ -439,26 +524,28 @@ void MathedCursor::Insert(byte c, MathedTextCodes t) p = mt; p->Metrics(); int pos = cursor->getPos(); - cursor->SetData(par); + SetCursorData(par); cursor->goPosAbs(pos); } - if (p && p->Permit(LMPF_ALLOW_CR)) { + if (p && p->Permit(LMPF_ALLOW_CR)) { cursor->addRow(); } } else if (t == LM_TC_TAB) { MathParInset * p = cursor->getPar(); - if (p && p->Permit(LMPF_ALLOW_TAB)) { + if (p && p->Permit(LMPF_ALLOW_TAB)) { if (c) { cursor->insert(c, t); cursor->checkTabs(); } else cursor->goNextColumn(); - } else // Navigate between arguments - if (p && p->GetType() == LM_OT_MACRO) { - if (p->getArgumentIdx() < p->getMaxArgumentIdx()) { - p->setArgumentIdx(p->getArgumentIdx() + 1); - cursor->SetData(p); - return; + } else { + // Navigate between arguments + if (p && p->GetType() == LM_OT_MACRO) { + if (p->getArgumentIdx() < p->getMaxArgumentIdx()) { + p->setArgumentIdx(p->getArgumentIdx() + 1); + SetCursorData(p); + return; + } } } } else { @@ -470,9 +557,9 @@ void MathedCursor::Insert(byte c, MathedTextCodes t) } } - if (accent) { + if (accent) doAccent(c, t); - } else + else cursor->insert(c, t); lastcode = t; @@ -495,7 +582,7 @@ void MathedCursor::insertInset(MathedInset * p, int t) SelDel(); } - if (mathstk.i < MAX_STACK_ITEMS - 1) { + if (!mathstk.Full()) { if (accent && !MathIsActive(t)) { doAccent(p); } else { @@ -520,10 +607,10 @@ void MathedCursor::Delete() return; } - if (cursor->Empty() && !mathstk.Empty()) + if (cursor->Empty() && !mathstk.empty()) cursor = mathstk.pop(); - // if (cursor->GetChar()!= LM_TC_TAB) + // if (cursor->GetChar() != LM_TC_TAB) cursor->Delete(); cursor->checkTabs(); } @@ -541,9 +628,8 @@ void MathedCursor::DelLine() MathParInset * p = cursor->getPar(); - if (p && p->GetType() <= LM_OT_MATRIX && p->GetType() >= LM_OT_MPAR) { + if (p && p->GetType() <= LM_OT_MATRIX && p->GetType() >= LM_OT_MPAR) cursor->delRow(); - } } @@ -565,16 +651,18 @@ bool MathedCursor::Up(bool sel) if (MathIsUp(cd)) { Push(); return true; - } else { - // A subscript may be followed by a superscript - cursor->ipush(); - cursor->Next(); - if (MathIsUp(cursor->GetChar())) { - Push(); - return true; - } else // return to the previous state - cursor->ipop(); } + + // A subscript may be followed by a superscript + cursor->ipush(); + cursor->Next(); + if (MathIsUp(cursor->GetChar())) { + Push(); + return true; + } + + // return to the previous state + cursor->ipop(); } result = cursor->Up(); @@ -586,16 +674,16 @@ bool MathedCursor::Up(bool sel) bool is_down = (cx->GetChar() == LM_TC_DOWN); cursor = mathstk.pop(); cursor->Next(); - result = (is_down) ? true: Up(); + result = is_down ? true : Up(); } else { - result = (p->getArgumentIdx() > 0); + result = p->getArgumentIdx() > 0; if (result) { p->setArgumentIdx(p->getArgumentIdx() - 1); - cursor->SetData(p); + SetCursorData(p); } } - if (!result && !mathstk.Empty()) { + if (!result && !mathstk.empty()) { cursor = mathstk.pop(); return Up(); } @@ -622,16 +710,17 @@ bool MathedCursor::Down(bool sel) if (MathIsDown(cd)) { Push(); return true; - } else { + } // A superscript may be followed by a subscript cursor->ipush(); cursor->Next(); if (MathIsDown(cursor->GetChar())) { Push(); return true; - } else - cursor->ipop(); } + + // return to the previous state + cursor->ipop(); } result = cursor->Down(); @@ -642,15 +731,15 @@ bool MathedCursor::Down(bool sel) bool is_up = (cx->GetChar() == LM_TC_UP); cursor = mathstk.pop(); cursor->Next(); - result = (is_up) ? true : Down(); + result = is_up ? true : Down(); } else { - result = (p->getArgumentIdx() < p->getMaxArgumentIdx()); + result = p->getArgumentIdx() < p->getMaxArgumentIdx(); if (result) { p->setArgumentIdx(p->getArgumentIdx() + 1); - cursor->SetData(p); + SetCursorData(p); } } - if (!result && !mathstk.Empty()) { + if (!result && !mathstk.empty()) { cursor = mathstk.pop(); return Down(sel); } @@ -675,7 +764,7 @@ void MathedCursor::SetSize(short size) { MathParInset * p = cursor->getPar(); p->UserSetSize(size); - cursor->SetData(p); + SetCursorData(p); } @@ -733,14 +822,14 @@ void MathedCursor::Interpret(string const & s) l = in_word_set(s); if (!l) { - p = MathMacroTable::mathMTable.createMacro(s); + p = new MathMacro(MathMacroTable::provideTemplate(s)); if (!p) { - lyxerr[Debug::MATHED] << "Macro2 " << s << ' ' << tcode << endl; - if (s == "root") { - p = new MathRootInset; - tcode = LM_TC_ACTIVE_INSET; - } else - p = new MathFuncInset(s, LM_OT_UNDEF); + lyxerr[Debug::MATHED] << "Macro2 " << s << ' ' << tcode << endl; + if (s == "root") { + p = new MathRootInset; + tcode = LM_TC_ACTIVE_INSET; + } else + p = new MathFuncInset(s, LM_OT_UNDEF); } else { tcode = static_cast(p)->getTCode(); lyxerr[Debug::MATHED] << "Macro2 " << s << ' ' << tcode << endl; @@ -797,7 +886,7 @@ void MathedCursor::Interpret(string const & s) break; case LM_TK_MACRO: - p = MathMacroTable::mathMTable.createMacro(s); + p = new MathMacro(MathMacroTable::provideTemplate(s)); tcode = static_cast(p)->getTCode(); lyxerr[Debug::MATHED] << "Macro " << s << ' ' << tcode << endl; break; @@ -853,8 +942,9 @@ void MathedCursor::MacroModeClose() macro_mode = false; latexkeys const * l = in_word_set(imacro->GetName()); if (!imacro->GetName().empty() - && (!l || (l && IsMacro(l->token, l->id))) && - !MathMacroTable::mathMTable.createMacro(imacro->GetName())) { + && (!l || (l && IsMacro(l->token, l->id))) && + !MathMacroTable::hasTemplate(imacro->GetName())) + { if (!l) { //imacro->SetName(macrobf); // This guarantees that the string will be removed by destructor @@ -868,7 +958,7 @@ void MathedCursor::MacroModeClose() static_cast(cursor->GetInset())->getAccentCode()); } cursor->Delete(); - if (l || MathMacroTable::mathMTable.createMacro(imacro->GetName())) { + if (l || MathMacroTable::hasTemplate(imacro->GetName())) { Interpret(imacro->GetName()); } imacro->SetName(""); @@ -1066,16 +1156,16 @@ void MathedCursor::SelGetArea(int ** xp, int ** yp, int & np) void MathedCursor::setAccent(int ac) { - if (ac > 0 && accent < 8) { + if (ac > 0 && accent < 8) nestaccent[accent++] = ac; - } else + else accent = 0; // consumed! } int MathedCursor::getAccent() const { - return (accent > 0) ? nestaccent[accent - 1]: 0; + return (accent > 0) ? nestaccent[accent - 1] : 0; } @@ -1188,3 +1278,11 @@ MathedTextCodes MathedCursor::getLastCode() const { return lastcode; } + + +bool MathedCursor::hasData(MathedArray const & ar) +{ + lyxerr << "hasData: ar: " << &ar << " cursor: " << cursor->GetData() << +endl; + return &ar == cursor->GetData(); +}