fix a few of the tabular crashes

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7889 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2003-10-10 09:01:23 +00:00
parent 760829360d
commit 839576adbc
10 changed files with 177 additions and 192 deletions

View File

@ -1,3 +1,13 @@
2003-10-10 André Pönitz <poenitz@gmx.net>
* lyxfunc.C:
* lyxtext.h:
* tabular.C:
* text.C:
* text2.C:
* text3.C: fix some of the tabular crashes
2003-10-09 Lars Gullik Bjønnes <larsbj@lyx.org>
* MenuBackend.C (binding): put debug message into Debug::KBMAP

View File

@ -1300,7 +1300,7 @@ void InsetTabular::resetPos(BufferView * bv) const
}
// we need this only from here on!!!
++in_reset_pos;
static int const offset = ADD_TO_TABULAR_WIDTH + 2;
int const offset = ADD_TO_TABULAR_WIDTH + 2;
int new_x = getCellXPos(actcell);
int old_x = cursorx_;
new_x += offset;
@ -1633,12 +1633,11 @@ void InsetTabular::tabularFeatures(BufferView * bv,
case LyXTabular::SET_PWIDTH:
{
LyXLength const vallen(value);
LyXLength const & tmplen = tabular.getColumnPWidth(actcell);
LyXLength const len(value);
LyXLength const & oldlen = tabular.getColumnPWidth(actcell);
bool const update = (tmplen != vallen);
tabular.setColumnPWidth(actcell, vallen);
if (update) {
tabular.setColumnPWidth(actcell, len);
if (oldlen != len) {
// We need this otherwise we won't resize
// the insettext of the active cell (if any)
// until later (see InsetText::do_resize)
@ -1646,10 +1645,10 @@ void InsetTabular::tabularFeatures(BufferView * bv,
bv->update();
}
if (vallen.zero()
if (len.zero()
&& tabular.getAlignment(actcell, true) == LYX_ALIGN_BLOCK)
tabularFeatures(bv, LyXTabular::ALIGN_CENTER, string());
else if (!vallen.zero()
else if (!len.zero()
&& tabular.getAlignment(actcell, true) != LYX_ALIGN_BLOCK)
tabularFeatures(bv, LyXTabular::ALIGN_BLOCK, string());
break;
@ -1657,12 +1656,10 @@ void InsetTabular::tabularFeatures(BufferView * bv,
case LyXTabular::SET_MPWIDTH:
{
LyXLength const vallen(value);
LyXLength const & tmplen = tabular.getPWidth(actcell);
bool const update = (tmplen != vallen);
tabular.setMColumnPWidth(actcell, vallen);
if (update) {
LyXLength const len(value);
LyXLength const & oldlen = tabular.getPWidth(actcell);
tabular.setMColumnPWidth(actcell, len);
if (oldlen != len) {
// We need this otherwise we won't resize
// the insettext of the active cell (if any)
// until later (see InsetText::do_resize)
@ -1681,7 +1678,6 @@ void InsetTabular::tabularFeatures(BufferView * bv,
unlockInsetInInset(bv, the_locking_inset);
tabular.appendRow(bv->buffer()->params(), actcell);
tabular.setOwner(this);
//tabular.init(bv->buffer()->params(), tabular.rows(), tabular.columns());
updateLocal(bv);
break;
case LyXTabular::APPEND_COLUMN:
@ -1689,7 +1685,6 @@ void InsetTabular::tabularFeatures(BufferView * bv,
unlockInsetInInset(bv, the_locking_inset);
tabular.appendColumn(bv->buffer()->params(), actcell);
tabular.setOwner(this);
//tabular.init(bv->buffer()->params(), tabular.rows(), tabular.columns());
actcell = tabular.getCellNumber(row, column);
updateLocal(bv);
break;
@ -2309,7 +2304,8 @@ bool InsetTabular::cutSelection(BufferParams const & bp)
for (int i = sel_row_start; i <= sel_row_end; ++i)
for (int j = sel_col_start; j <= sel_col_end; ++j)
tabular.getCellInset(tabular.getCellNumber(i, j)).clear(bp.tracking_changes);
tabular.getCellInset(tabular.getCellNumber(i, j))
.clear(bp.tracking_changes);
return true;
}

View File

@ -111,13 +111,13 @@ void InsetText::init()
top_y = 0;
locked = false;
inset_par = paragraphs.end();
inset_par = -1;
inset_pos = 0;
inset_x = 0;
inset_y = 0;
no_selection = true;
the_locking_inset = 0;
old_par = paragraphs.end();
old_par = -1;
in_insetAllowed = false;
mouse_x = 0;
mouse_y = 0;
@ -270,7 +270,8 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
top_baseline = y;
top_y = y - dim_.asc;
if (the_locking_inset && cpar() == inset_par && cpos() == inset_pos) {
if (the_locking_inset
&& text_.cursor.par() == inset_par && cpos() == inset_pos) {
inset_x = cx() - x;
inset_y = cy();
}
@ -311,9 +312,9 @@ void InsetText::updateLocal(BufferView * bv, bool /*mark_dirty*/)
bv->owner()->view_state_changed();
bv->owner()->updateMenubar();
bv->owner()->updateToolbar();
if (old_par != cpar()) {
if (old_par != text_.cursor.par()) {
bv->owner()->setLayout(cpar()->layout()->name());
old_par = cpar();
old_par = text_.cursor.par();
}
}
@ -355,8 +356,8 @@ void InsetText::lockInset(BufferView * bv)
the_locking_inset = 0;
inset_pos = inset_x = inset_y = 0;
inset_boundary = false;
inset_par = paragraphs.end();
old_par = paragraphs.end();
inset_par = -1;
old_par = -1;
text_.setCursorIntern(0, 0);
text_.clearSelection();
finishUndo();
@ -377,7 +378,7 @@ void InsetText::lockInset(BufferView * /*bv*/, UpdatableInset * inset)
inset_x = cx() - top_x;
inset_y = cy();
inset_pos = cpos();
inset_par = cpar();
inset_par = text_.cursor.par();
inset_boundary = cboundary();
}
@ -418,7 +419,7 @@ bool InsetText::lockInsetInInset(BufferView * bv, UpdatableInset * inset)
}
if (the_locking_inset && the_locking_inset == inset) {
if (cpar() == inset_par && cpos() == inset_pos) {
if (text_.cursor.par() == inset_par && cpos() == inset_pos) {
lyxerr[Debug::INSETS] << "OK" << endl;
inset_x = cx() - top_x;
inset_y = cy();
@ -444,7 +445,7 @@ bool InsetText::unlockInsetInInset(BufferView * bv, UpdatableInset * inset,
the_locking_inset = 0;
if (lr)
moveRightIntern(bv, true, false);
old_par = paragraphs.end(); // force layout setting
old_par = -1; // force layout setting
if (scroll())
scroll(bv, 0.0F);
else
@ -521,7 +522,7 @@ void InsetText::lfunMousePress(FuncRequest const & cmd)
// we moved the view we cannot do mouse selection in this case!
if (bv->top_y() != old_top_y)
no_selection = true;
old_par = cpar();
old_par = text_.cursor.par();
// Insert primary selection with middle mouse
// if there is a local selection in the current buffer,
// insert this
@ -551,29 +552,13 @@ bool InsetText::lfunMouseRelease(FuncRequest const & cmd)
int tmp_x = cmd.x;
int tmp_y = cmd.y + dim_.asc - bv->top_y();
InsetOld * inset = getLyXText(bv)->checkInsetHit(tmp_x, tmp_y);
bool ret = false;
if (inset) {
// This code should probably be removed now. Simple insets
// (!highlyEditable) can actually take the localDispatch,
// and turn it into edit() if necessary. But we still
// need to deal properly with the whole relative vs.
// absolute mouse co-ords thing in a realiable, sensible way
#if 0
if (isHighlyEditableInset(inset))
ret = inset->localDispatch(cmd1);
else {
inset_x = cx(bv) - top_x;
inset_y = cy();
cmd1.x = cmd.x - inset_x;
cmd1.y = cmd.x - inset_y;
inset->edit(bv, cmd1.x, cmd1.y, cmd.button());
ret = true;
}
#endif
ret = inset->localDispatch(cmd1);
updateLocal(bv, false);
if (!inset)
return false;
}
// We still need to deal properly with the whole relative vs.
// absolute mouse co-ords thing in a realiable, sensible way
bool ret = inset->localDispatch(cmd1);
updateLocal(bv, false);
return ret;
}
@ -623,8 +608,8 @@ InsetOld::RESULT InsetText::localDispatch(FuncRequest const & cmd)
inset_x = 0;
inset_y = 0;
inset_boundary = false;
inset_par = paragraphs.end();
old_par = paragraphs.end();
inset_par = -1;
old_par = -1;
if (cmd.argument.size()) {
@ -820,61 +805,57 @@ InsetOld::RESULT InsetText::localDispatch(FuncRequest const & cmd)
updflag = true;
break;
case LFUN_PASTE: {
case LFUN_PASTE:
if (!autoBreakRows_) {
if (CutAndPaste::nrOfParagraphs() > 1) {
#ifdef WITH_WARNINGS
#warning FIXME horrendously bad UI
#endif
Alert::error(_("Paste failed"), _("Cannot include more than one paragraph."));
break;
}
}
} else {
replaceSelection(bv->getLyXText());
size_t sel_index = 0;
string const & arg = cmd.argument;
if (isStrUnsignedInt(arg)) {
size_t const paste_arg = strToUnsignedInt(arg);
#warning FIXME Check if the arg is in the domain of available selections.
sel_index = paste_arg;
sel_index = strToUnsignedInt(arg);
}
text_.pasteSelection(sel_index);
// bug 393
text_.clearSelection();
updflag = true;
break;
}
break;
case LFUN_BREAKPARAGRAPH:
if (!autoBreakRows_) {
result = DISPATCHED;
break;
}
} else {
replaceSelection(bv->getLyXText());
text_.breakParagraph(paragraphs, 0);
updflag = true;
}
break;
case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
if (!autoBreakRows_) {
result = DISPATCHED;
break;
}
} else {
replaceSelection(bv->getLyXText());
text_.breakParagraph(paragraphs, 1);
updflag = true;
}
break;
case LFUN_BREAKLINE: {
if (!autoBreakRows_) {
result = DISPATCHED;
break;
}
} else {
replaceSelection(bv->getLyXText());
text_.insertInset(new InsetNewline);
updflag = true;
}
break;
}

View File

@ -276,7 +276,7 @@ private:
///
mutable int top_y;
///
ParagraphList::iterator inset_par;
lyx::paroffset_type inset_par;
///
lyx::pos_type inset_pos;
///
@ -290,7 +290,7 @@ private:
///
UpdatableInset * the_locking_inset;
///
mutable ParagraphList::iterator old_par;
mutable lyx::paroffset_type old_par;
///
// to remember old painted frame dimensions to clear it on the right spot!

View File

@ -888,7 +888,7 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
if (view()->available())
view()->hideCursor();
#if 1
#if 0
{
Cursor cursor;
buildCursor(cursor, *view());
@ -932,28 +932,36 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
if (action == LFUN_UNDO) {
view()->undo();
goto exit_with_message;
} else if (action == LFUN_REDO) {
}
if (action == LFUN_REDO) {
view()->redo();
goto exit_with_message;
} else if (((result=inset->
}
// Hand-over to inset's own dispatch:
localDispatch(FuncRequest(view(), action, argument))) ==
DISPATCHED) ||
(result == DISPATCHED_NOUPDATE))
result = inset->localDispatch(FuncRequest(view(), action, argument));
if (result == DISPATCHED || result == DISPATCHED_NOUPDATE) {
goto exit_with_message;
}
// If UNDISPATCHED, just soldier on
else if (result == FINISHED) {
if (result == FINISHED) {
owner->clearMessage();
goto exit_with_message;
// We do not need special RTL handling here:
// FINISHED means that the cursor should be
// one position after the inset.
} else if (result == FINISHED_RIGHT) {
}
if (result == FINISHED_RIGHT) {
view()->text->cursorRight(view());
moveCursorUpdate();
owner->clearMessage();
goto exit_with_message;
} else if (result == FINISHED_UP) {
}
if (result == FINISHED_UP) {
RowList::iterator const irow = view()->text->cursorIRow();
if (irow != view()->text->firstRow()) {
#if 1
@ -971,7 +979,9 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
}
owner->clearMessage();
goto exit_with_message;
} else if (result == FINISHED_DOWN) {
}
if (result == FINISHED_DOWN) {
RowList::iterator const irow = view()->text->cursorIRow();
if (irow != view()->text->lastRow()) {
#if 1
@ -991,8 +1001,9 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
owner->clearMessage();
goto exit_with_message;
}
#warning I am not sure this is still right, please have a look! (Jug 20020417)
else { // result == UNDISPATCHED
// result == UNDISPATCHED
//setMessage(N_("Text mode"));
switch (action) {
case LFUN_UNKNOWN_ACTION:
@ -1029,7 +1040,6 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
}
}
}
}
switch (action) {
@ -1521,8 +1531,7 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
case LFUN_CHILDOPEN:
{
string const filename =
MakeAbsPath(argument,
owner->buffer()->filePath());
MakeAbsPath(argument, owner->buffer()->filePath());
setMessage(N_("Opening child document ") +
MakeDisplayPath(filename) + "...");
view()->savePosition(0);
@ -1647,8 +1656,7 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
break;
case LFUN_EXTERNAL_EDIT: {
InsetExternal()
.localDispatch(FuncRequest(view(), action, argument));
InsetExternal().localDispatch(FuncRequest(view(), action, argument));
break;
}

View File

@ -506,7 +506,6 @@ public:
///
std::string selectionAsString(Buffer const & buffer, bool label) const;
private:
/** Cursor related data.
Later this variable has to be removed. There should be now internal

View File

@ -407,10 +407,6 @@ void LyXTabular::setOwner(InsetTabular * inset)
}
#warning for some strange reason, cellstruct does not seem to have copy-semantics
// work around using 'swap' only...
void LyXTabular::appendRow(BufferParams const & bp, int cell)
{
++rows_;
@ -458,8 +454,6 @@ void LyXTabular::appendColumn(BufferParams const & bp, int cell)
{
++columns_;
cell_vvector c_info = cell_vvector(rows_, cell_vector(columns_,
cellstruct(bp)));
int const column = column_of_cell(cell);
column_vector::iterator cit = column_info.begin() + column + 1;
column_info.insert(cit, columnstruct());
@ -467,21 +461,16 @@ void LyXTabular::appendColumn(BufferParams const & bp, int cell)
column_info[column + 1] = column_info[column];
for (int i = 0; i < rows_; ++i) {
for (int j = 0; j <= column; ++j)
c_info[i][j] = cell_info[i][j];
for (int j = column + 1; j < columns_; ++j)
c_info[i][j] = cell_info[i][j - 1];
cell_info[i].insert(cell_info[i].begin() + column + 1, cellstruct(bp));
// care about multicolumns
if (c_info[i][column + 1].multicolumn == CELL_BEGIN_OF_MULTICOLUMN)
c_info[i][column + 1].multicolumn = CELL_PART_OF_MULTICOLUMN;
if (cell_info[i][column + 1].multicolumn == CELL_BEGIN_OF_MULTICOLUMN)
cell_info[i][column + 1].multicolumn = CELL_PART_OF_MULTICOLUMN;
if (column + 2 >= columns_
|| c_info[i][column + 2].multicolumn != CELL_PART_OF_MULTICOLUMN)
c_info[i][column + 1].multicolumn = LyXTabular::CELL_NORMAL;
|| cell_info[i][column + 2].multicolumn != CELL_PART_OF_MULTICOLUMN)
cell_info[i][column + 1].multicolumn = LyXTabular::CELL_NORMAL;
}
cell_info = c_info;
//++column;
for (int i = 0; i < rows_; ++i) {
cell_info[i][column + 1].inset.clear(false);

View File

@ -1987,6 +1987,8 @@ ParagraphList::iterator LyXText::getPar(LyXCursor const & cur) const
ParagraphList::iterator LyXText::getPar(int par) const
{
BOOST_ASSERT(par >= 0);
BOOST_ASSERT(par < ownerParagraphs().size());
ParagraphList::iterator pit = ownerParagraphs().begin();
std::advance(pit, par);
return pit;

View File

@ -1161,7 +1161,7 @@ void LyXText::cutSelection(bool doclear, bool realcut)
// and selection.end
// make sure that the depth behind the selection are restored, too
ParagraphList::iterator endpit = getPar(selection.end.par() + 1);
ParagraphList::iterator endpit = boost::next(getPar(selection.end.par()));
ParagraphList::iterator undoendpit = endpit;
ParagraphList::iterator pars_end = ownerParagraphs().end();
@ -1810,8 +1810,13 @@ bool LyXText::deleteEmptyParagraphMechanism(LyXCursor const & old_cursor)
if (selection.set())
return false;
// Don't do anything if the cursor is invalid
if (old_cursor.par() == -1)
return false;
// We allow all kinds of "mumbo-jumbo" when freespacing.
if (getPar(old_cursor)->isFreeSpacing())
ParagraphList::iterator const old_pit = getPar(old_cursor);
if (old_pit->isFreeSpacing())
return false;
/* Ok I'll put some comments here about what is missing.
@ -1838,7 +1843,6 @@ bool LyXText::deleteEmptyParagraphMechanism(LyXCursor const & old_cursor)
// MISSING
// If the pos around the old_cursor were spaces, delete one of them.
ParagraphList::iterator const old_pit = getPar(old_cursor);
if (old_cursor.par() != cursor.par()
|| old_cursor.pos() != cursor.pos()) {

View File

@ -716,23 +716,21 @@ InsetOld::RESULT LyXText::dispatch(FuncRequest const & cmd)
case LFUN_DELETE_SKIP:
// Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
if (!selection.set()) {
LyXCursor cur = cursor;
if (cur.pos() == getPar(cur)->size()) {
if (cursor.pos() == cursorPar()->size()) {
cursorRight(bv);
cur = cursor;
if (cur.pos() == 0
&& !(getPar(cur)->params().spaceTop()
== VSpace (VSpace::NONE))) {
ParagraphParameters & params = cursorPar()->params();
if (cursor.pos() == 0
&& !(params.spaceTop() == VSpace (VSpace::NONE))) {
setParagraph(
getPar(cur)->params().lineTop(),
getPar(cur)->params().lineBottom(),
getPar(cur)->params().pagebreakTop(),
getPar(cur)->params().pagebreakBottom(),
params.lineTop(),
params.lineBottom(),
params.pagebreakTop(),
params.pagebreakBottom(),
VSpace(VSpace::NONE),
getPar(cur)->params().spaceBottom(),
getPar(cur)->params().spacing(),
getPar(cur)->params().align(),
getPar(cur)->params().labelWidthString(), 0);
params.spaceBottom(),
params.spacing(),
params.align(),
params.labelWidthString(), 0);
cursorLeft(bv);
} else {
cursorLeft(bv);
@ -769,20 +767,20 @@ InsetOld::RESULT LyXText::dispatch(FuncRequest const & cmd)
case LFUN_BACKSPACE_SKIP:
// Reverse the effect of LFUN_BREAKPARAGRAPH_SKIP.
if (!selection.set()) {
LyXCursor cur = cursor;
if (cur.pos() == 0
&& !(getPar(cur)->params().spaceTop() == VSpace(VSpace::NONE))) {
ParagraphParameters & params = cursorPar()->params();
if (cursor.pos() == 0 && !(params.spaceTop() == VSpace(VSpace::NONE))) {
setParagraph(
getPar(cur)->params().lineTop(),
getPar(cur)->params().lineBottom(),
getPar(cur)->params().pagebreakTop(),
getPar(cur)->params().pagebreakBottom(),
params.lineTop(),
params.lineBottom(),
params.pagebreakTop(),
params.pagebreakBottom(),
VSpace(VSpace::NONE),
getPar(cur)->params().spaceBottom(),
getPar(cur)->params().spacing(),
getPar(cur)->params().align(),
getPar(cur)->params().labelWidthString(), 0);
params.spaceBottom(),
params.spacing(),
params.align(),
params.labelWidthString(), 0);
} else {
LyXCursor cur = cursor;
backspace();
selection.cursor = cur;
}
@ -817,16 +815,17 @@ InsetOld::RESULT LyXText::dispatch(FuncRequest const & cmd)
LyXCursor cur = cursor;
replaceSelection(bv->getLyXText());
if (cur.pos() == 0) {
if (getPar(cur)->params().spaceTop() == VSpace(VSpace::NONE)) {
ParagraphParameters & params = getPar(cur)->params();
if (params.spaceTop() == VSpace(VSpace::NONE)) {
setParagraph(
getPar(cur)->params().lineTop(),
getPar(cur)->params().lineBottom(),
getPar(cur)->params().pagebreakTop(),
getPar(cur)->params().pagebreakBottom(),
VSpace(VSpace::DEFSKIP), getPar(cur)->params().spaceBottom(),
getPar(cur)->params().spacing(),
getPar(cur)->params().align(),
getPar(cur)->params().labelWidthString(), 1);
params.lineTop(),
params.lineBottom(),
params.pagebreakTop(),
params.pagebreakBottom(),
VSpace(VSpace::DEFSKIP), params.spaceBottom(),
params.spacing(),
params.align(),
params.labelWidthString(), 1);
}
}
else {
@ -969,22 +968,19 @@ InsetOld::RESULT LyXText::dispatch(FuncRequest const & cmd)
bv->update();
break;
case LFUN_PASTE: {
case LFUN_PASTE:
cmd.message(_("Paste"));
replaceSelection(bv->getLyXText());
size_t sel_index = 0;
string const & arg = cmd.argument;
if (isStrUnsignedInt(arg)) {
size_t const paste_arg = strToUnsignedInt(arg);
#warning FIXME Check if the arg is in the domain of available selections.
sel_index = paste_arg;
}
pasteSelection(sel_index);
if (isStrUnsignedInt(cmd.argument))
pasteSelection(strToUnsignedInt(cmd.argument));
else
pasteSelection(0);
clearSelection(); // bug 393
bv->update();
bv->switchKeyMap();
finishUndo();
break;
}
case LFUN_CUT:
cutSelection(true, true);