"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:
André Pönitz 2002-10-29 08:23:32 +00:00
parent f522618723
commit f46dfd626e
11 changed files with 134 additions and 51 deletions

View File

@ -126,7 +126,13 @@ 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);
if (mathcursor->par()->name() == font) {
mathcursor->handleFont(font);
updateLocal(bv, true);
} else {
bool sel = mathcursor->selection();
if (sel)
updateLocal(bv, true);
@ -135,6 +141,7 @@ void InsetFormulaBase::handleFont
if (!sel)
updateLocal(bv, false);
}
}
// Check if uses AMS macros
@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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);
}
}

View File

@ -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?

View File

@ -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;
///

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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)
{

View File

@ -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];