From f46dfd626e7509b635848213973325700e993f9a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Tue, 29 Oct 2002 08:23:32 +0000 Subject: [PATCH] "Better" font handling. I've not found a cause for John's crash, but I'd put in a safety belt which should produce error messages instead. So please report any message saying "this schould not really happen". git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@5538 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/mathed/formulabase.C | 25 ++++++++----- src/mathed/math_cursor.C | 70 +++++++++++++++++++++++++---------- src/mathed/math_cursor.h | 9 +++-- src/mathed/math_data.C | 34 +++++++++++++++-- src/mathed/math_data.h | 2 + src/mathed/math_fontinset.h | 4 ++ src/mathed/math_inset.h | 7 +++- src/mathed/math_nestinset.C | 6 ++- src/mathed/math_nestinset.h | 2 +- src/mathed/math_scriptinset.C | 22 ++++++----- src/mathed/math_scriptinset.h | 4 +- 11 files changed, 134 insertions(+), 51 deletions(-) diff --git a/src/mathed/formulabase.C b/src/mathed/formulabase.C index 0fce71e577..a50f6a84a8 100644 --- a/src/mathed/formulabase.C +++ b/src/mathed/formulabase.C @@ -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::localDispatch(FuncRequest const & cmd) 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; diff --git a/src/mathed/math_cursor.C b/src/mathed/math_cursor.C index 00433ff403..f24655af01 100644 --- a/src/mathed/math_cursor.C +++ b/src/mathed/math_cursor.C @@ -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,18 @@ MathCursor::pos_type MathCursor::pos() const } +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; + // just to be on the safe side + // theoretically unecessary + normalize(); +} + + MathCursor::pos_type & MathCursor::pos() { return cursor().pos_; @@ -780,21 +793,6 @@ 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()); } @@ -1433,6 +1431,40 @@ MathInset::mode_type MathCursor::currentMode() const } +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); +} + + void releaseMathCursor(BufferView * bv) { if (!mathcursor) diff --git a/src/mathed/math_cursor.h b/src/mathed/math_cursor.h index f53b79891f..ad440f3f92 100644 --- a/src/mathed/math_cursor.h +++ b/src/mathed/math_cursor.h @@ -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 @@ -238,11 +240,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 diff --git a/src/mathed/math_data.C b/src/mathed/math_data.C index c53341d35e..e4b9c50dda 100644 --- a/src/mathed/math_data.C +++ b/src/mathed/math_data.C @@ -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" @@ -385,3 +384,32 @@ void MathArray::setXY(int x, int y) const 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); + } + +} diff --git a/src/mathed/math_data.h b/src/mathed/math_data.h index be003e6082..d3cbf993f0 100644 --- a/src/mathed/math_data.h +++ b/src/mathed/math_data.h @@ -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? diff --git a/src/mathed/math_fontinset.h b/src/mathed/math_fontinset.h index fbd838baf3..7d331e9c5b 100644 --- a/src/mathed/math_fontinset.h +++ b/src/mathed/math_fontinset.h @@ -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; /// diff --git a/src/mathed/math_inset.h b/src/mathed/math_inset.h index b847533983..823faf515f 100644 --- a/src/mathed/math_inset.h +++ b/src/mathed/math_inset.h @@ -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; diff --git a/src/mathed/math_nestinset.C b/src/mathed/math_nestinset.C index 9dd85d446a..85c41832da 100644 --- a/src/mathed/math_nestinset.C +++ b/src/mathed/math_nestinset.C @@ -311,8 +311,10 @@ void MathNestInset::normalize(NormalStream & os) const } -void MathNestInset::notifyCursorLeaves() -{} +void MathNestInset::notifyCursorLeaves(idx_type idx) +{ + cell(idx).notifyCursorLeaves(); +} MathInset::result_type MathNestInset::dispatch diff --git a/src/mathed/math_nestinset.h b/src/mathed/math_nestinset.h index ea8edc8562..851ade9af2 100644 --- a/src/mathed/math_nestinset.h +++ b/src/mathed/math_nestinset.h @@ -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); diff --git a/src/mathed/math_scriptinset.C b/src/mathed/math_scriptinset.C index ebd2dab51e..61bfd9fe01 100644 --- a/src/mathed/math_scriptinset.C +++ b/src/mathed/math_scriptinset.C @@ -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(); @@ -487,6 +477,18 @@ void MathScriptInset::infoize(std::ostream & os) const } +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; + } +} + + MathInset::result_type MathScriptInset::dispatch (FuncRequest const & cmd, idx_type & idx, pos_type & pos) { diff --git a/src/mathed/math_scriptinset.h b/src/mathed/math_scriptinset.h index 9bb6806109..baf9099f7f 100644 --- a/src/mathed/math_scriptinset.h +++ b/src/mathed/math_scriptinset.h @@ -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]; -- 2.39.5