Backport of this and follow-up fixes of bug 4566 by sts:

URL: http://www.lyx.org/trac/changeset/23804
Log:
* another try on http://bugzilla.lyx.org/show_bug.cgi?id=4566:

  "Eqnarray multiple cells size change erases what they contain"

  We also apply LFUN_MATH_INSERT to every selected cell if a single math inset is inserted. 

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_1_5_X@24085 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jürgen Spitzmüller 2008-04-01 13:59:13 +00:00
parent 8634dbd811
commit dc798a4b34
5 changed files with 113 additions and 65 deletions

View File

@ -404,6 +404,23 @@ docstring grabAndEraseSelection(Cursor & cur)
}
bool multipleCellsSelected(Cursor const & cur)
{
if (!cur.selection() || !cur.inMathed())
return false;
CursorSlice i1 = cur.selBegin();
CursorSlice i2 = cur.selEnd();
if (!i1.inset().asInsetMath())
return false;
if (i1.idx() == i2.idx())
return false;
return true;
}
void switchBetweenClasses(textclass_type c1, textclass_type c2,
InsetText & in, ErrorList & errorlist)
{

View File

@ -106,6 +106,8 @@ void switchBetweenClasses(textclass_type c1, textclass_type c2,
void region(CursorSlice const & i1, CursorSlice const & i2,
Inset::row_type & r1, Inset::row_type & r2,
Inset::col_type & c1, Inset::col_type & c2);
/// Returns true if multiple cells are selected in mathed.
bool multipleCellsSelected(Cursor const & cur);
/// Get the current selection as a string. Does not change the selection.
/// Does only work if the whole selection is in mathed.
docstring grabSelection(Cursor const & cur);

View File

@ -19,6 +19,7 @@
#include "Buffer.h"
#include "buffer_funcs.h"
#include "Cursor.h"
#include "CutAndPaste.h"
#include "debug.h"
#include "BufferView.h"
#include "Text.h"
@ -282,7 +283,14 @@ void recordUndoInset(Cursor & cur, Undo::undo_kind kind)
void recordUndoSelection(Cursor & cur, Undo::undo_kind kind)
{
recordUndo(kind, cur, cur.selBegin().pit(), cur.selEnd().pit());
if (cur.inMathed()) {
if (cap::multipleCellsSelected(cur))
recordUndoInset(cur, kind);
else
recordUndo(cur, kind);
} else
recordUndo(kind, cur, cur.selBegin().pit(),
cur.selEnd().pit());
}

View File

@ -413,66 +413,78 @@ void InsetMathNest::handleFont
// this whole function is a hack and won't work for incremental font
// changes...
if (cur.inset().asInsetMath()->name() == font) {
recordUndoInset(cur, Undo::ATOMIC);
recordUndoSelection(cur);
if (cur.inset().asInsetMath()->name() == font)
cur.handleFont(to_utf8(font));
} else {
CursorSlice i1 = cur.selBegin();
CursorSlice i2 = cur.selEnd();
if (!i1.inset().asInsetMath())
return;
if (i1.idx() == i2.idx()) {
// the easy case where only one cell is selected
recordUndo(cur, Undo::ATOMIC);
cur.handleNest(createInsetMath(font));
else
handleNest(cur, createInsetMath(font), arg);
}
void InsetMathNest::handleNest(Cursor & cur, MathAtom const & nest)
{
handleNest(cur, nest, docstring());
}
void InsetMathNest::handleNest(Cursor & cur, MathAtom const & nest,
docstring const & arg)
{
CursorSlice i1 = cur.selBegin();
CursorSlice i2 = cur.selEnd();
if (!i1.inset().asInsetMath())
return;
if (i1.idx() == i2.idx()) {
// the easy case where only one cell is selected
cur.handleNest(nest);
cur.insert(arg);
return;
}
// multiple selected cells in a simple non-grid inset
if (i1.asInsetMath()->nrows() == 0 || i1.asInsetMath()->ncols() == 0) {
for (idx_type i = i1.idx(); i <= i2.idx(); ++i) {
// select cell
cur.idx() = i;
cur.pos() = 0;
cur.resetAnchor();
cur.pos() = cur.lastpos();
cur.setSelection();
// change font of cell
cur.handleNest(nest);
cur.insert(arg);
return;
// cur is in the font inset now. If the loop continues,
// we need to get outside again for the next cell
if (i + 1 <= i2.idx())
cur.pop_back();
}
// multiple selected cells in a simple non-grid inset
if (i1.asInsetMath()->nrows() == 0 || i1.asInsetMath()->ncols() == 0) {
recordUndoInset(cur);
for (idx_type i = i1.idx(); i <= i2.idx(); ++i) {
// select cell
cur.idx() = i;
cur.pos() = 0;
cur.resetAnchor();
cur.pos() = cur.lastpos();
cur.setSelection();
// change font of cell
cur.handleNest(createInsetMath(font));
cur.insert(arg);
// cur is in the font inset now. If the loop continues,
// we need to get outside again for the next cell
if (i + 1 <= i2.idx())
cur.pop_back();
}
return;
}
// the complicated case with multiple selected cells in a grid
recordUndoInset(cur);
Inset::row_type r1, r2;
Inset::col_type c1, c2;
cap::region(i1, i2, r1, r2, c1, c2);
for (Inset::row_type row = r1; row <= r2; ++row) {
for (Inset::col_type col = c1; col <= c2; ++col) {
// select cell
cur.idx() = i1.asInsetMath()->index(row, col);
cur.pos() = 0;
cur.resetAnchor();
cur.pos() = cur.lastpos();
cur.setSelection();
return;
}
// change font of cell
cur.handleNest(createInsetMath(font));
cur.insert(arg);
// the complicated case with multiple selected cells in a grid
Inset::row_type r1, r2;
Inset::col_type c1, c2;
cap::region(i1, i2, r1, r2, c1, c2);
for (Inset::row_type row = r1; row <= r2; ++row) {
for (Inset::col_type col = c1; col <= c2; ++col) {
// select cell
cur.idx() = i1.asInsetMath()->index(row, col);
cur.pos() = 0;
cur.resetAnchor();
cur.pos() = cur.lastpos();
cur.setSelection();
// cur is in the font inset now. If the loop continues,
// we need to get outside again for the next cell
if (col + 1 <= c2 || row + 1 <= r2)
cur.pop_back();
}
// change font of cell
cur.handleNest(nest);
cur.insert(arg);
// cur is in the font inset now. If the loop continues,
// we need to get outside again for the next cell
if (col + 1 <= c2 || row + 1 <= r2)
cur.pop_back();
}
}
}
@ -480,14 +492,12 @@ void InsetMathNest::handleFont
void InsetMathNest::handleFont2(Cursor & cur, docstring const & arg)
{
recordUndo(cur, Undo::ATOMIC);
recordUndoSelection(cur);
Font font;
bool b;
bv_funcs::string2font(to_utf8(arg), font, b);
if (font.color() != Color::inherit && font.color() != Color::ignore) {
MathAtom at = MathAtom(new InsetMathColor(true, font.color()));
cur.handleNest(at, 0);
}
if (font.color() != Color::inherit && font.color() != Color::ignore)
handleNest(cur, MathAtom(new InsetMathColor(true, font.color())));
}
@ -1029,11 +1039,17 @@ goto_char_backwards:
// handling such that "self-insert" works on "arbitrary stuff" too, and
// math-insert only handles special math things like "matrix".
case LFUN_MATH_INSERT: {
recordUndo(cur, Undo::ATOMIC);
if (cmd.argument() == "^" || cmd.argument() == "_") {
recordUndoSelection(cur);
if (cmd.argument() == "^" || cmd.argument() == "_")
interpretChar(cur, cmd.argument()[0]);
} else
cur.niceInsert(cmd.argument());
else {
MathData ar;
asArray(cmd.argument(), ar);
if (ar.size() == 1 && ar[0]->asNestInset())
handleNest(cur, ar[0]);
else
cur.niceInsert(cmd.argument());
}
break;
}

View File

@ -128,6 +128,11 @@ protected:
docstring const & arg, char const * const font);
///
void handleFont2(Cursor & cur, docstring const & arg);
/// Grab and erase selection and insert the InsetMathNest atom in every
/// previously selected cell, insert the grabbed former data and \c arg
/// in the first cell of the inserted atom.
void handleNest(Cursor & cur, MathAtom const & nest);
void handleNest(Cursor & cur, MathAtom const & nest, docstring const & arg);
/// interpret \p c and insert the result at the current position of
/// of \p cur. Return whether the cursor should stay in the formula.