See attached. Andre'
-- Those who desire to give up Freedom in order to gain Security, will not have, nor do they deserve, either one. (T. Jefferson)
Index: formulabase.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/formulabase.C,v retrieving revision 1.222 diff -u -p -r1.222 formulabase.C --- formulabase.C 25 Oct 2002 06:44:40 -0000 1.222 +++ formulabase.C 28 Oct 2002 19:38:12 -0000 @@ -126,14 +126,21 @@ void InsetFormulaBase::mutateToText() void InsetFormulaBase::handleFont (BufferView * bv, string const & arg, string const & font) { + // this whole function is a hack and won't work for incremental font + // changes... bv->lockedInsetStoreUndo(Undo::EDIT); - bool sel = mathcursor->selection(); - if (sel) + if (mathcursor->par()->name() == font) { + mathcursor->handleFont(font); updateLocal(bv, true); - mathcursor->handleNest(createMathInset(font)); - mathcursor->insert(arg); - if (!sel) - updateLocal(bv, false); + } else { + bool sel = mathcursor->selection(); + if (sel) + updateLocal(bv, true); + mathcursor->handleNest(createMathInset(font)); + mathcursor->insert(arg); + if (!sel) + updateLocal(bv, false); + } } @@ -627,11 +634,11 @@ Inset::RESULT InsetFormulaBase::localDis break; case LFUN_MATH_MODE: - if (mathcursor->currentMode()) - handleFont(bv, cmd.argument, "textrm"); - else { + if (mathcursor->currentMode() == MathInset::TEXT_MODE) { mathcursor->niceInsert(MathAtom(new MathHullInset("simple"))); updateLocal(bv, true); + } else { + handleFont(bv, cmd.argument, "textrm"); } //bv->owner()->message(_("math text mode toggled")); break; @@ -785,7 +792,7 @@ Inset::RESULT InsetFormulaBase::localDis result = UNDISPATCHED; } - mathcursor->normalize(); + mathcursor->normalize2(); mathcursor->touch(); lyx::Assert(mathcursor); Index: math_cursor.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_cursor.C,v retrieving revision 1.326 diff -u -p -r1.326 math_cursor.C --- math_cursor.C 24 Oct 2002 06:45:29 -0000 1.326 +++ math_cursor.C 28 Oct 2002 19:38:12 -0000 @@ -35,6 +35,7 @@ #include "math_charinset.h" #include "math_extern.h" #include "math_factory.h" +#include "math_fontinset.h" #include "math_gridinset.h" #include "math_iterator.h" #include "math_macroarg.h" @@ -107,10 +108,10 @@ bool MathCursor::popLeft() //cerr << "Leaving atom to the left\n"; if (depth() <= 1) { if (depth() == 1) - par()->notifyCursorLeaves(); + par()->notifyCursorLeaves(idx()); return false; } - par()->notifyCursorLeaves(); + par()->notifyCursorLeaves(idx()); Cursor_.pop_back(); return true; } @@ -121,10 +122,10 @@ bool MathCursor::popRight() //cerr << "Leaving atom "; par()->write(cerr, false); cerr << " right\n"; if (depth() <= 1) { if (depth() == 1) - par()->notifyCursorLeaves(); + par()->notifyCursorLeaves(idx()); return false; } - par()->notifyCursorLeaves(); + par()->notifyCursorLeaves(idx()); Cursor_.pop_back(); posRight(); return true; @@ -665,6 +666,15 @@ MathCursor::pos_type MathCursor::pos() c } +void MathCursor::adjust(pos_type from, size_type size) +{ + if (cursor().pos_ > from) + cursor().pos_ += size; + if (Anchor_.back().pos_ > from) + Anchor_.back().pos_ += size; +} + + MathCursor::pos_type & MathCursor::pos() { return cursor().pos_; @@ -780,21 +790,13 @@ void MathCursor::normalize() dump("error 4"); } pos() = min(pos(), size()); +} - // remove empty scripts if possible - if (1) { - for (pos_type i = 0; i < size(); ++i) { - MathScriptInset * p = array()[i].nucleus()->asScriptInset(); - if (p) { - p->removeEmptyScripts(); - if (!p->hasUp() && !p->hasDown() && p->nuc().size() == 1) - array()[i] = p->nuc()[0]; - } - } - } - // fix again position - pos() = min(pos(), size()); +void MathCursor::normalize2() +{ + // do standard stuff + normalize(); } @@ -1430,6 +1432,40 @@ MathInset::mode_type MathCursor::current return res; } return MathInset::UNDECIDED_MODE; +} + + +void MathCursor::handleFont(string const & font) +{ + string safe; + if (selection()) { + macroModeClose(); + safe = grabAndEraseSelection(); + } + + if (array().size()) { + // something left in the cell + if (pos() == 0) { + // cursor in first position + popLeft(); + } else if (pos() == array().size()) { + // cursor in last position + popRight(); + } else { + // cursor in between. split cell + MathArray::iterator bt = array().begin(); + MathAtom at = createMathInset(font); + at.nucleus()->cell(0) = MathArray(bt, bt + pos()); + cursor().cell().erase(bt, bt + pos()); + popLeft(); + plainInsert(at); + } + } else { + // nothing left in the cell + pullArg(); + plainErase(); + } + insert(safe); } Index: math_cursor.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_cursor.h,v retrieving revision 1.136 diff -u -p -r1.136 math_cursor.h --- math_cursor.h 22 Oct 2002 17:31:32 -0000 1.136 +++ math_cursor.h 28 Oct 2002 19:38:12 -0000 @@ -114,6 +114,8 @@ public: void popToEnclosingHull(); /// go up to the hull inset void popToHere(MathInset const * p); + /// adjust position after deletion/insertion + void adjust(pos_type from, size_type size); /// InsetFormulaBase * formula() const; /// current offset in the current cell @@ -173,6 +175,8 @@ public: /// make sure cursor position is valid void normalize(); + /// valid position plus no empty scripts + void normalize2(); /// mark current cursor trace for redraw void touch(); /// @@ -238,11 +242,12 @@ public: /// hack for reveal codes void markInsert(); void markErase(); - //void handleExtern(string const & arg); - -private: /// injects content of a cell into parent void pullArg(); + /// split font inset etc + void handleFont(string const & font); + +private: /// moves cursor index one cell to the left bool idxLeft(); /// moves cursor index one cell to the right Index: math_data.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_data.C,v retrieving revision 1.21 diff -u -p -r1.21 math_data.C --- math_data.C 15 Oct 2002 06:21:58 -0000 1.21 +++ math_data.C 28 Oct 2002 19:38:12 -0000 @@ -6,11 +6,10 @@ #include "math_data.h" #include "math_inset.h" +#include "math_cursor.h" #include "math_deliminset.h" -#include "math_charinset.h" +#include "math_fontinset.h" #include "math_scriptinset.h" -#include "math_stringinset.h" -#include "math_matrixinset.h" #include "math_mathmlstream.h" #include "math_support.h" #include "math_replace.h" @@ -384,4 +383,33 @@ void MathArray::setXY(int x, int y) cons { xo_ = x; yo_ = y; +} + + +void MathArray::notifyCursorLeaves() +{ + // do not recurse! + + // remove base-only "scripts" + for (pos_type i = 0; i + 1 < size(); ++i) { + MathScriptInset * p = operator[](i).nucleus()->asScriptInset(); + if (p && p->cell(0).empty() && p->cell(1).empty()) { + MathArray ar = p->nuc(); + erase(i); + insert(i, ar); + mathcursor->adjust(i, ar.size() - 1); + } + } + + // glue adjacent font insets of the same kind + for (pos_type i = 0; i + 1 < size(); ++i) { + MathFontInset * p = operator[](i).nucleus()->asFontInset(); + MathFontInset const * q = operator[](i + 1)->asFontInset(); + if (p && q && p->name() == q->name()) { + p->cell(0).append(q->cell(0)); + erase(i + 1); + } + mathcursor->adjust(i, -1); + } + } Index: math_data.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_data.h,v retrieving revision 1.17 diff -u -p -r1.17 math_data.h --- math_data.h 11 Sep 2002 08:26:02 -0000 1.17 +++ math_data.h 28 Oct 2002 19:38:12 -0000 @@ -158,6 +158,8 @@ public: void center(int & x, int & y) const; /// adjust (x,y) to point on boundary on a straight line from the center void towards(int & x, int & y) const; + /// clean up if necessary + void notifyCursorLeaves(); private: /// is this an exact match at this position? Index: math_fontinset.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_fontinset.h,v retrieving revision 1.6 diff -u -p -r1.6 math_fontinset.h --- math_fontinset.h 11 Sep 2002 08:26:02 -0000 1.6 +++ math_fontinset.h 28 Oct 2002 19:38:12 -0000 @@ -22,6 +22,10 @@ public: explicit MathFontInset(latexkeys const * key); /// MathInset * clone() const; + /// + MathFontInset * asFontInset() { return this; } + /// + MathFontInset const * asFontInset() const { return this; } /// are we in math mode, text mode, or unsure? mode_type currentMode() const; /// Index: math_inset.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_inset.h,v retrieving revision 1.148 diff -u -p -r1.148 math_inset.h --- math_inset.h 28 Oct 2002 17:15:19 -0000 1.148 +++ math_inset.h 28 Oct 2002 19:38:12 -0000 @@ -53,6 +53,7 @@ class MathCharInset; class MathDelimInset; class MathGridInset; class MathFracInset; +class MathFontInset; class MathHullInset; class MathMatrixInset; class MathNestInset; @@ -200,6 +201,8 @@ public: virtual MathDelimInset const * asDelimInset() const { return 0; } virtual MathFracInset * asFracInset() { return 0; } virtual MathFracInset const * asFracInset() const { return 0; } + virtual MathFontInset * asFontInset() { return 0; } + virtual MathFontInset const * asFontInset() const { return 0; } virtual MathGridInset * asGridInset() { return 0; } virtual MathGridInset const * asGridInset() const { return 0; } virtual MathHullInset * asHullInset() { return 0; } @@ -228,7 +231,7 @@ public: /// is the a relational operator (used for splitting equations) virtual bool isRelOp() const { return false; } /// -1: text mode, 1: math mode, 0 undecided - enum mode_type {UNDECIDED_MODE, TEXT_MODE, MATH_MODE, VERBATIM_MODE}; + enum mode_type {UNDECIDED_MODE, TEXT_MODE, MATH_MODE}; /// Dispatch result codes, see inset/inset.h enum result_type { UNDISPATCHED = 0, DISPATCHED, DISPATCHED_NOUPDATE, @@ -263,7 +266,7 @@ public: /// access to the lock (only nest array have one) virtual void lock(bool) {} /// get notification when the cursor leaves this inset - virtual void notifyCursorLeaves() {} + virtual void notifyCursorLeaves(idx_type) {} /// write LaTeX and Lyx code virtual void write(WriteStream & os) const; Index: math_nestinset.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_nestinset.C,v retrieving revision 1.59 diff -u -p -r1.59 math_nestinset.C --- math_nestinset.C 15 Oct 2002 06:21:59 -0000 1.59 +++ math_nestinset.C 28 Oct 2002 19:38:12 -0000 @@ -311,8 +311,10 @@ void MathNestInset::normalize(NormalStre } -void MathNestInset::notifyCursorLeaves() -{} +void MathNestInset::notifyCursorLeaves(idx_type idx) +{ + cell(idx).notifyCursorLeaves(); +} MathInset::result_type MathNestInset::dispatch Index: math_nestinset.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_nestinset.h,v retrieving revision 1.34 diff -u -p -r1.34 math_nestinset.h --- math_nestinset.h 15 Aug 2002 10:02:53 -0000 1.34 +++ math_nestinset.h 28 Oct 2002 19:38:12 -0000 @@ -70,7 +70,7 @@ public: /// access to the lock void lock(bool); /// get notification when the cursor leaves this inset - void notifyCursorLeaves(); + void notifyCursorLeaves(idx_type); /// direct access to the cell MathArray & cell(idx_type); Index: math_scriptinset.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_scriptinset.C,v retrieving revision 1.75 diff -u -p -r1.75 math_scriptinset.C --- math_scriptinset.C 28 Oct 2002 10:47:24 -0000 1.75 +++ math_scriptinset.C 28 Oct 2002 19:38:12 -0000 @@ -273,16 +273,6 @@ bool MathScriptInset::hasLimits() const } -void MathScriptInset::removeEmptyScripts() -{ - for (int i = 0; i <= 1; ++i) - if (script_[i] && cell(i).size() == 0) { - cell(i).clear(); - script_[i] = false; - } -} - - void MathScriptInset::removeScript(bool up) { cell(up).clear(); @@ -484,6 +474,18 @@ void MathScriptInset::infoize(std::ostre os << "Scripts"; if (limits_) os << (limits_ == 1 ? ", Displayed limits" : ", Inlined limits"); +} + + +void MathScriptInset::notifyCursorLeaves(idx_type idx) +{ + MathNestInset::notifyCursorLeaves(idx); + + // remove empty scripts if possible + if (idx != 2 && script_[idx] && cell(idx).empty()) { + cell(idx).clear(); + script_[idx] = false; + } } Index: math_scriptinset.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/math_scriptinset.h,v retrieving revision 1.46 diff -u -p -r1.46 math_scriptinset.h --- math_scriptinset.h 11 Sep 2002 08:26:02 -0000 1.46 +++ math_scriptinset.h 28 Oct 2002 19:38:12 -0000 @@ -87,8 +87,6 @@ public: bool has(bool up) const; /// remove script void removeScript(bool up); - /// remove script - void removeEmptyScripts(); /// make sure a script is accessible void ensure(bool up); /// @@ -115,6 +113,8 @@ private: int ndes() const; /// where do we have to draw the scripts? bool hasLimits() const; + /// clean up empty cells + void notifyCursorLeaves(idx_type idx); /// possible subscript (index 0) and superscript (index 1) bool script_[2];