mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-26 11:16:55 +00:00
"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
This commit is contained in:
parent
f522618723
commit
f46dfd626e
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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?
|
||||
|
@ -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;
|
||||
///
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user