X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsettabular.C;h=d21030ee98d11ebc7413c5f57dcac73490420171;hb=4a5b7a5952ad2381fcdf4830511293e184c7c5a1;hp=a1a4d929b96ad4cef759e3ac4056897d106311a3;hpb=fc8465aa1f6f29774d2f35d627b40198fa489cb1;p=lyx.git diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index a1a4d929b9..d21030ee98 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -3,18 +3,13 @@ * * LyX, The Document Processor * - * Copyright 2000 The LyX Team. + * Copyright 2001 The LyX Team. * * ====================================================== */ #include -#include -#include - -#include - #ifdef __GNUG__ #pragma implementation #endif @@ -23,6 +18,7 @@ #include "buffer.h" #include "commandtags.h" +#include "lyxfunc.h" #include "debug.h" #include "LaTeXFeatures.h" #include "Painter.h" @@ -30,13 +26,30 @@ #include "lyxtext.h" #include "lyx_gui_misc.h" #include "LyXView.h" -#include "lyxfunc.h" #include "insets/insettext.h" -#include "frontends/Dialogs.h" #include "debug.h" -#include "lyxfunc.h" #include "WorkArea.h" +#include "gettext.h" +#include "language.h" +#include "BufferView.h" +#include "undo_funcs.h" +#include "lyxlength.h" +#include "ParagraphParameters.h" + +#include "frontends/Dialogs.h" +#include "frontends/Alert.h" + +#include "support/LAssert.h" +#include "support/lstrings.h" + +#include +#include +#include +#include +//#include + +using std::vector; using std::ostream; using std::ifstream; using std::max; @@ -44,68 +57,67 @@ using std::endl; using std::swap; using std::max; - namespace { -const int ADD_TO_HEIGHT = 2; -const int ADD_TO_TABULAR_WIDTH = 2; +int const ADD_TO_HEIGHT = 2; +int const ADD_TO_TABULAR_WIDTH = 2; + /// LyXTabular * paste_tabular = 0; -struct tabular_features { - LyXTabular::Feature action; - string feature; +struct TabularFeature { + LyXTabular::Feature action; + string feature; }; -//tabular_features * tabularFeatures = 0; - -tabular_features tabularFeatures[] = -{ - { LyXTabular::APPEND_ROW, "append-row" }, - { LyXTabular::APPEND_COLUMN, "append-column" }, - { LyXTabular::DELETE_ROW, "delete-row" }, - { LyXTabular::DELETE_COLUMN, "delete-column" }, - { LyXTabular::TOGGLE_LINE_TOP, "toggle-line-top" }, - { LyXTabular::TOGGLE_LINE_BOTTOM, "toggle-line-bottom" }, - { LyXTabular::TOGGLE_LINE_LEFT, "toggle-line-left" }, - { LyXTabular::TOGGLE_LINE_RIGHT, "toggle-line-right" }, - { LyXTabular::ALIGN_LEFT, "align-left" }, - { LyXTabular::ALIGN_RIGHT, "align-right" }, - { LyXTabular::ALIGN_CENTER, "align-center" }, - { LyXTabular::VALIGN_TOP, "valign-top" }, - { LyXTabular::VALIGN_BOTTOM, "valign-bottom" }, - { LyXTabular::VALIGN_CENTER, "valign-center" }, - { LyXTabular::M_TOGGLE_LINE_TOP, "m-toggle-line-top" }, - { LyXTabular::M_TOGGLE_LINE_BOTTOM, "m-toggle-line-bottom" }, - { LyXTabular::M_TOGGLE_LINE_LEFT, "m-toggle-line-left" }, - { LyXTabular::M_TOGGLE_LINE_RIGHT, "m-toggle-line-right" }, - { LyXTabular::M_ALIGN_LEFT, "m-align-left" }, - { LyXTabular::M_ALIGN_RIGHT, "m-align-right" }, - { LyXTabular::M_ALIGN_CENTER, "m-align-center" }, - { LyXTabular::M_VALIGN_TOP, "m-valign-top" }, - { LyXTabular::M_VALIGN_BOTTOM, "m-valign-bottom" }, - { LyXTabular::M_VALIGN_CENTER, "m-valign-center" }, - { LyXTabular::MULTICOLUMN, "multicolumn" }, - { LyXTabular::SET_ALL_LINES, "set-all-lines" }, - { LyXTabular::UNSET_ALL_LINES, "unset-all-lines" }, - { LyXTabular::SET_LONGTABULAR, "set-longtabular" }, - { LyXTabular::UNSET_LONGTABULAR, "unset-longtabular" }, - { LyXTabular::SET_PWIDTH, "set-pwidth" }, - { LyXTabular::SET_MPWIDTH, "set-mpwidth" }, - { LyXTabular::SET_ROTATE_TABULAR, "set-rotate-tabular" }, - { LyXTabular::UNSET_ROTATE_TABULAR, "unset-rotate-tabular" }, - { LyXTabular::SET_ROTATE_CELL, "set-rotate-cell" }, - { LyXTabular::UNSET_ROTATE_CELL, "unset-rotate-cell" }, - { LyXTabular::SET_USEBOX, "set-usebox" }, - { LyXTabular::SET_LTHEAD, "set-lthead" }, - { LyXTabular::SET_LTFIRSTHEAD, "set-ltfirsthead" }, - { LyXTabular::SET_LTFOOT, "set-ltfoot" }, - { LyXTabular::SET_LTLASTFOOT, "set-ltlastfoot" }, - { LyXTabular::SET_LTNEWPAGE, "set-ltnewpage" }, - { LyXTabular::SET_SPECIAL_COLUMN, "set-special-column" }, - { LyXTabular::SET_SPECIAL_MULTI, "set-special-multi" }, - { LyXTabular::LAST_ACTION, "" } + +TabularFeature tabularFeature[] = +{ + { LyXTabular::APPEND_ROW, "append-row" }, + { LyXTabular::APPEND_COLUMN, "append-column" }, + { LyXTabular::DELETE_ROW, "delete-row" }, + { LyXTabular::DELETE_COLUMN, "delete-column" }, + { LyXTabular::TOGGLE_LINE_TOP, "toggle-line-top" }, + { LyXTabular::TOGGLE_LINE_BOTTOM, "toggle-line-bottom" }, + { LyXTabular::TOGGLE_LINE_LEFT, "toggle-line-left" }, + { LyXTabular::TOGGLE_LINE_RIGHT, "toggle-line-right" }, + { LyXTabular::ALIGN_LEFT, "align-left" }, + { LyXTabular::ALIGN_RIGHT, "align-right" }, + { LyXTabular::ALIGN_CENTER, "align-center" }, + { LyXTabular::VALIGN_TOP, "valign-top" }, + { LyXTabular::VALIGN_BOTTOM, "valign-bottom" }, + { LyXTabular::VALIGN_CENTER, "valign-center" }, + { LyXTabular::M_TOGGLE_LINE_TOP, "m-toggle-line-top" }, + { LyXTabular::M_TOGGLE_LINE_BOTTOM, "m-toggle-line-bottom" }, + { LyXTabular::M_TOGGLE_LINE_LEFT, "m-toggle-line-left" }, + { LyXTabular::M_TOGGLE_LINE_RIGHT, "m-toggle-line-right" }, + { LyXTabular::M_ALIGN_LEFT, "m-align-left" }, + { LyXTabular::M_ALIGN_RIGHT, "m-align-right" }, + { LyXTabular::M_ALIGN_CENTER, "m-align-center" }, + { LyXTabular::M_VALIGN_TOP, "m-valign-top" }, + { LyXTabular::M_VALIGN_BOTTOM, "m-valign-bottom" }, + { LyXTabular::M_VALIGN_CENTER, "m-valign-center" }, + { LyXTabular::MULTICOLUMN, "multicolumn" }, + { LyXTabular::SET_ALL_LINES, "set-all-lines" }, + { LyXTabular::UNSET_ALL_LINES, "unset-all-lines" }, + { LyXTabular::SET_LONGTABULAR, "set-longtabular" }, + { LyXTabular::UNSET_LONGTABULAR, "unset-longtabular" }, + { LyXTabular::SET_PWIDTH, "set-pwidth" }, + { LyXTabular::SET_MPWIDTH, "set-mpwidth" }, + { LyXTabular::SET_ROTATE_TABULAR, "set-rotate-tabular" }, + { LyXTabular::UNSET_ROTATE_TABULAR, "unset-rotate-tabular" }, + { LyXTabular::SET_ROTATE_CELL, "set-rotate-cell" }, + { LyXTabular::UNSET_ROTATE_CELL, "unset-rotate-cell" }, + { LyXTabular::SET_USEBOX, "set-usebox" }, + { LyXTabular::SET_LTHEAD, "set-lthead" }, + { LyXTabular::SET_LTFIRSTHEAD, "set-ltfirsthead" }, + { LyXTabular::SET_LTFOOT, "set-ltfoot" }, + { LyXTabular::SET_LTLASTFOOT, "set-ltlastfoot" }, + { LyXTabular::SET_LTNEWPAGE, "set-ltnewpage" }, + { LyXTabular::SET_SPECIAL_COLUMN, "set-special-column" }, + { LyXTabular::SET_SPECIAL_MULTI, "set-special-multi" }, + { LyXTabular::LAST_ACTION, "" } }; } // namespace anon @@ -113,2108 +125,2610 @@ tabular_features tabularFeatures[] = bool InsetTabular::hasPasteBuffer() const { - return (paste_tabular != 0); + return (paste_tabular != 0); } InsetTabular::InsetTabular(Buffer const & buf, int rows, int columns) : buffer(&buf) { - if (rows <= 0) - rows = 1; - if (columns <= 0) - columns = 1; - tabular = new LyXTabular(this, rows,columns); - // for now make it always display as display() inset - // just for test!!! - the_locking_inset = 0; - locked = no_selection = cursor_visible = false; - oldcell = -1; - actrow = actcell = 0; - clearSelection(); - need_update = INIT; - no_draw = false; + if (rows <= 0) + rows = 1; + if (columns <= 0) + columns = 1; + tabular.reset(new LyXTabular(this, rows, columns)); + // for now make it always display as display() inset + // just for test!!! + the_locking_inset = 0; + old_locking_inset = 0; + locked = false; + oldcell = -1; + actrow = actcell = 0; + clearSelection(); + need_update = INIT; + in_update = false; + in_reset_pos = false; + inset_x = 0; + inset_y = 0; } -InsetTabular::InsetTabular(InsetTabular const & tab, Buffer const & buf) - : buffer(&buf) +InsetTabular::InsetTabular(InsetTabular const & tab, Buffer const & buf, + bool same_id) + : UpdatableInset(tab, same_id), buffer(&buf) { - tabular = new LyXTabular(this, *(tab.tabular)); - the_locking_inset = 0; - locked = no_selection = cursor_visible = false; - oldcell = -1; - actrow = actcell = 0; - sel_cell_start = sel_cell_end = 0; - need_update = INIT; - no_draw = false; + tabular.reset(new LyXTabular(this, *(tab.tabular), same_id)); + the_locking_inset = 0; + old_locking_inset = 0; + locked = false; + oldcell = -1; + actrow = actcell = 0; + clearSelection(); + need_update = INIT; + in_update = false; + in_reset_pos = false; + inset_x = 0; + inset_y = 0; } InsetTabular::~InsetTabular() { - delete tabular; - hideDialog(); + hideDialog(); } -Inset * InsetTabular::Clone(Buffer const & buf) const +Inset * InsetTabular::clone(Buffer const & buf, bool same_id) const { - InsetTabular * t = new InsetTabular(*this, buf); - delete t->tabular; - t->tabular = tabular->Clone(t); - return t; + return new InsetTabular(*this, buf, same_id); } -void InsetTabular::Write(Buffer const * buf, ostream & os) const +void InsetTabular::write(Buffer const * buf, ostream & os) const { - os << " Tabular" << endl; - tabular->Write(buf, os); + os << " Tabular" << endl; + tabular->Write(buf, os); } -void InsetTabular::Read(Buffer const * buf, LyXLex & lex) +void InsetTabular::read(Buffer const * buf, LyXLex & lex) { - bool old_format = (lex.GetString() == "\\LyXTable"); - string token; + bool const old_format = (lex.getString() == "\\LyXTable"); - if (tabular) - delete tabular; - tabular = new LyXTabular(buf, this, lex); + tabular.reset(new LyXTabular(buf, this, lex)); - need_update = INIT; + need_update = INIT; - if (old_format) - return; + if (old_format) + return; - lex.nextToken(); - token = lex.GetString(); - while (lex.IsOK() && (token != "\\end_inset")) { lex.nextToken(); - token = lex.GetString(); - } - if (token != "\\end_inset") { - lex.printError("Missing \\end_inset at this point. " - "Read: `$$Token'"); - } + string token = lex.getString(); + while (lex.isOK() && (token != "\\end_inset")) { + lex.nextToken(); + token = lex.getString(); + } + if (token != "\\end_inset") { + lex.printError("Missing \\end_inset at this point. " + "Read: `$$Token'"); + } } int InsetTabular::ascent(BufferView *, LyXFont const &) const { - return tabular->GetAscentOfRow(0); + return tabular->GetAscentOfRow(0); } int InsetTabular::descent(BufferView *, LyXFont const &) const { - return tabular->GetHeightOfTabular() - tabular->GetAscentOfRow(0) + 1; + return tabular->GetHeightOfTabular() - tabular->GetAscentOfRow(0) + 1; } int InsetTabular::width(BufferView *, LyXFont const &) const { - return tabular->GetWidthOfTabular() + (2 * ADD_TO_TABULAR_WIDTH); + return tabular->GetWidthOfTabular() + (2 * ADD_TO_TABULAR_WIDTH); } void InsetTabular::draw(BufferView * bv, LyXFont const & font, int baseline, float & x, bool cleared) const { - if (no_draw) - return; + if (nodraw()) { + if (cleared) + need_update = FULL; + return; + } +#if 0 + if (need_update == INIT) { + if (calculate_dimensions_of_cells(bv, font, true)) + bv->text->status = LyXText::CHANGED_IN_DRAW; + need_update = FULL; + } +#endif + + Painter & pain = bv->painter(); + int i; + int j; + int nx; - Painter & pain = bv->painter(); - int i; - int j; - int nx; - - UpdatableInset::draw(bv, font, baseline, x, cleared); - if (!cleared && ((need_update == INIT) || (need_update == FULL) || - (top_x != int(x)) || (top_baseline != baseline))) { - int h = ascent(bv, font) + descent(bv, font); - int tx = display() || !owner() ? 0 : top_x; - int w = tx ? width(bv, font) : pain.paperWidth(); - int ty = baseline - ascent(bv, font); +#if 0 + UpdatableInset::draw(bv, font, baseline, x, cleared); +#else + if (!owner()) + x += static_cast(scroll()); +#endif + if (!cleared && ((need_update == INIT) || (need_update == FULL) || + (top_x != int(x)) || (top_baseline != baseline))) + { + int h = ascent(bv, font) + descent(bv, font); + int const tx = display() || !owner() ? 0 : top_x; + int w = tx ? width(bv, font) : pain.paperWidth(); + int ty = baseline - ascent(bv, font); - if (ty < 0) - ty = 0; - if ((ty + h) > pain.paperHeight()) - h = pain.paperHeight(); - if ((top_x + w) > pain.paperWidth()) - w = pain.paperWidth(); - pain.fillRectangle(tx, ty, w, h); - need_update = FULL; - cleared = true; - } - top_x = int(x); - top_baseline = baseline; - if (bv->text->status == LyXText::CHANGED_IN_DRAW) - return; - bool dodraw; - x += ADD_TO_TABULAR_WIDTH; - if (cleared) { - int cell = 0; - float cx; - first_visible_cell = -1; - for (i = 0; i < tabular->rows(); ++i) { - nx = int(x); - dodraw = ((baseline + tabular->GetDescentOfRow(i)) > 0) && - (baseline - tabular->GetAscentOfRow(i))columns(); ++j) { - if (tabular->IsPartOfMultiColumn(i, j)) - continue; - cx = nx + tabular->GetBeginningOfTextInCell(cell); - if (dodraw) { - if (first_visible_cell < 0) - first_visible_cell = cell; - if (hasSelection()) - DrawCellSelection(pain, nx, baseline, i, j, cell); - tabular->GetCellInset(cell)->draw(bv, font, baseline, cx, - cleared); - DrawCellLines(pain, nx, baseline, i, cell); + if (ty < 0) + ty = 0; + if ((ty + h) > pain.paperHeight()) + h = pain.paperHeight(); + if ((top_x + w) > pain.paperWidth()) + w = pain.paperWidth(); + pain.fillRectangle(tx, ty, w, h, backgroundColor()); + need_update = FULL; + cleared = true; + } + top_x = int(x); + topx_set = true; + top_baseline = baseline; + x += ADD_TO_TABULAR_WIDTH; + if (cleared) { + int cell = 0; + float cx; + first_visible_cell = -1; + for (i = 0; i < tabular->rows(); ++i) { + nx = int(x); + cell = tabular->GetCellNumber(i, 0); + if (!((baseline + tabular->GetDescentOfRow(i)) > 0) && + (baseline - tabular->GetAscentOfRow(i))GetDescentOfRow(i) + + tabular->GetAscentOfRow(i + 1) + + tabular->GetAdditionalHeight(i + 1); + continue; + } + for (j = 0; j < tabular->columns(); ++j) { + if (nx > bv->workWidth()) + break; + if (tabular->IsPartOfMultiColumn(i, j)) + continue; + cx = nx + tabular->GetBeginningOfTextInCell(cell); + if (first_visible_cell < 0) + first_visible_cell = cell; + if (hasSelection()) { + drawCellSelection(pain, nx, baseline, i, j, cell); + } + + tabular->GetCellInset(cell)->draw(bv, font, baseline, cx, cleared); + drawCellLines(pain, nx, baseline, i, cell); + nx += tabular->GetWidthOfColumn(cell); + ++cell; + } + baseline += tabular->GetDescentOfRow(i) + + tabular->GetAscentOfRow(i + 1) + + tabular->GetAdditionalHeight(i + 1); } - nx += tabular->GetWidthOfColumn(cell); - ++cell; - } - baseline += tabular->GetDescentOfRow(i) + - tabular->GetAscentOfRow(i + 1) + - tabular->GetAdditionalHeight(cell); - } - } else if (need_update == CELL) { - int cell = 0; - nx = int(x); - if (the_locking_inset) { - Inset * inset = tabular->GetCellInset(cell); - for (i = 0; (inset != the_locking_inset) && (i < tabular->rows()); - ++i) - { - for (j = 0; (inset != the_locking_inset) && (j < tabular->columns()); ++j) + } else if (need_update == CELL) { + int cell = 0; + nx = int(x); + if (the_locking_inset && + tabular->GetCellInset(actcell) != the_locking_inset) { - if (tabular->IsPartOfMultiColumn(i, j)) - continue; - nx += tabular->GetWidthOfColumn(cell); - ++cell; - inset = tabular->GetCellInset(cell); + Inset * inset = tabular->GetCellInset(cell); + for (i = 0; + inset != the_locking_inset && i < tabular->rows(); + ++i) + { + for (j = 0; + inset != the_locking_inset && j < tabular->columns(); + ++j) + { + if (tabular->IsPartOfMultiColumn(i, j)) + continue; + nx += tabular->GetWidthOfColumn(cell); + ++cell; + inset = tabular->GetCellInset(cell); + } + if (tabular->row_of_cell(cell) > i) { + nx = int(x); + baseline += tabular->GetDescentOfRow(i) + + tabular->GetAscentOfRow(i + 1) + + tabular->GetAdditionalHeight(i + 1); + } + } + } else { + // compute baseline for actual row + for (i = 0; i < actrow; ++i) { + baseline += tabular->GetDescentOfRow(i) + + tabular->GetAscentOfRow(i + 1) + + tabular->GetAdditionalHeight(i + 1); + } + // now compute the right x position + cell = tabular->GetCellNumber(actrow, 0); + for (j = 0; (cell < actcell) && (j < tabular->columns()); ++j) { + if (tabular->IsPartOfMultiColumn(actrow, j)) + continue; + nx += tabular->GetWidthOfColumn(cell); + ++cell; + } } - if (tabular->row_of_cell(cell) > i) { - nx = int(x); - baseline += tabular->GetDescentOfRow(i) + - tabular->GetAscentOfRow(i + 1) + - tabular->GetAdditionalHeight(cell); + i = tabular->row_of_cell(cell); + if (the_locking_inset != tabular->GetCellInset(cell)) { + lyxerr[Debug::INSETTEXT] << "ERROR this shouldn't happen\n"; + return; } - } - } else { - for (i = 0; (cell < actcell) && (i < tabular->rows()); ++i) { - for (j = 0; (cell < actcell) && (j < tabular->columns()); ++j) { - if (tabular->IsPartOfMultiColumn(i, j)) - continue; - nx += tabular->GetWidthOfColumn(cell); - ++cell; - } - if (tabular->row_of_cell(cell) > i) { - nx = int(x); - baseline += tabular->GetDescentOfRow(i) + - tabular->GetAscentOfRow(i + 1) + - tabular->GetAdditionalHeight(cell); + float dx = nx + tabular->GetBeginningOfTextInCell(cell); + float cx = dx; + tabular->GetCellInset(cell)->draw(bv, font, baseline, dx, false); + // + // Here we use rectangular backgroundColor patches to clean up + // within a cell around the cell's red inset box. As follows: + // + // +--------------------+ + // | C | The rectangles are A, B and C + // | A |------------| B | below, origin top left (tx, ty), + // | | inset box | | dimensions w(idth), h(eight). + // +---+------------+---+ x grows rightward, y downward + // | D | + // +--------------------+ + // +#if 0 + // clear only if we didn't have a change + if (bv->text->status() != LyXText::CHANGED_IN_DRAW) { +#endif + // clear before the inset + int tx, ty, w, h; + tx = nx + 1; + ty = baseline - tabular->GetAscentOfRow(i) + 1; + w = int(cx - nx - 1); + h = tabular->GetAscentOfRow(i) + + tabular->GetDescentOfRow(i) - 1; + pain.fillRectangle(tx, ty, w, h, backgroundColor()); + // clear behind the inset + tx = int(cx + the_locking_inset->width(bv,font) + 1); + ty = baseline - tabular->GetAscentOfRow(i) + 1; + w = tabular->GetWidthOfColumn(cell) - + tabular->GetBeginningOfTextInCell(cell) - + the_locking_inset->width(bv,font) - + tabular->GetAdditionalWidth(cell) - 1; + h = tabular->GetAscentOfRow(i) + tabular->GetDescentOfRow(i) - 1; + pain.fillRectangle(tx, ty, w, h, backgroundColor()); + // clear below the inset + tx = nx + 1; + ty = baseline + the_locking_inset->descent(bv, font) + 1; + w = tabular->GetWidthOfColumn(cell) - + tabular->GetAdditionalWidth(cell) - 1; + h = tabular->GetDescentOfRow(i) - + the_locking_inset->descent(bv, font) - 1; + pain.fillRectangle(tx, ty, w, h, backgroundColor()); + // clear above the inset + tx = nx + 1; + ty = baseline - tabular->GetAscentOfRow(i) + 1; + w = tabular->GetWidthOfColumn(cell) - + tabular->GetAdditionalWidth(cell) - 1; + h = tabular->GetAscentOfRow(i) - the_locking_inset->ascent(bv, font); + pain.fillRectangle(tx, ty, w, h, backgroundColor()); +#if 0 } - } - } - i = tabular->row_of_cell(cell); - if (the_locking_inset != tabular->GetCellInset(cell)) { - lyxerr[Debug::INSETS] << "ERROR this shouldn't happen\n"; - return; - } - float dx; - float cx; - cx = dx = nx + tabular->GetBeginningOfTextInCell(cell); - tabular->GetCellInset(cell)->draw(bv,font,baseline, dx, false); - if (bv->text->status == LyXText::CHANGED_IN_DRAW) - return; - // clear only if we didn't have a change - if (need_update == CELL) { - // clear before the inset - pain.fillRectangle( - nx + 1, - baseline - tabular->GetAscentOfRow(i) + 1, - int(cx - nx - 1), - tabular->GetAscentOfRow(i) + - tabular->GetDescentOfRow(i) - 1); - // clear behind the inset - pain.fillRectangle( - int(cx + the_locking_inset->width(bv,font) + 1), - baseline - tabular->GetAscentOfRow(i) + 1, - tabular->GetWidthOfColumn(cell) - - tabular->GetBeginningOfTextInCell(cell) - - the_locking_inset->width(bv,font) - - tabular->GetAdditionalWidth(cell) - 1, - tabular->GetAscentOfRow(i) + - tabular->GetDescentOfRow(i) - 1); - } - } - x -= ADD_TO_TABULAR_WIDTH; - x += width(bv, font); - if (bv->text->status == LyXText::CHANGED_IN_DRAW) - need_update = INIT; - else - need_update = NONE; +#endif + } + x -= ADD_TO_TABULAR_WIDTH; + x += width(bv, font); + if (bv->text->status() == LyXText::CHANGED_IN_DRAW) { + int i = 0; + for(Inset * inset = owner(); inset; ++i) + inset = inset->owner(); + if (calculate_dimensions_of_cells(bv, font, false)) + need_update = INIT; + } else { + need_update = NONE; + } } -void InsetTabular::DrawCellLines(Painter & pain, int x, int baseline, +void InsetTabular::drawCellLines(Painter & pain, int x, int baseline, int row, int cell) const { - int x2 = x + tabular->GetWidthOfColumn(cell); - bool on_off; - - if (!tabular->TopAlreadyDrawed(cell)) { - on_off = !tabular->TopLine(cell); - pain.line(x, baseline - tabular->GetAscentOfRow(row), - x2, baseline - tabular->GetAscentOfRow(row), + int x2 = x + tabular->GetWidthOfColumn(cell); + bool on_off; + + if (!tabular->TopAlreadyDrawed(cell)) { + on_off = !tabular->TopLine(cell); + pain.line(x, baseline - tabular->GetAscentOfRow(row), + x2, baseline - tabular->GetAscentOfRow(row), + on_off ? LColor::tabularonoffline : LColor::tabularline, + on_off ? Painter::line_onoffdash : Painter::line_solid); + } + on_off = !tabular->BottomLine(cell); + pain.line(x,baseline + tabular->GetDescentOfRow(row), + x2, baseline + tabular->GetDescentOfRow(row), on_off ? LColor::tabularonoffline : LColor::tabularline, on_off ? Painter::line_onoffdash : Painter::line_solid); - } - on_off = !tabular->BottomLine(cell); - pain.line(x,baseline + tabular->GetDescentOfRow(row), - x2, baseline + tabular->GetDescentOfRow(row), - on_off ? LColor::tabularonoffline : LColor::tabularline, - on_off ? Painter::line_onoffdash : Painter::line_solid); - if (!tabular->LeftAlreadyDrawed(cell)) { - on_off = !tabular->LeftLine(cell); - pain.line(x, baseline - tabular->GetAscentOfRow(row), - x, baseline + tabular->GetDescentOfRow(row), + if (!tabular->LeftAlreadyDrawed(cell)) { + on_off = !tabular->LeftLine(cell); + pain.line(x, baseline - tabular->GetAscentOfRow(row), + x, baseline + tabular->GetDescentOfRow(row), + on_off ? LColor::tabularonoffline : LColor::tabularline, + on_off ? Painter::line_onoffdash : Painter::line_solid); + } + on_off = !tabular->RightLine(cell); + pain.line(x2 - tabular->GetAdditionalWidth(cell), + baseline - tabular->GetAscentOfRow(row), + x2 - tabular->GetAdditionalWidth(cell), + baseline + tabular->GetDescentOfRow(row), on_off ? LColor::tabularonoffline : LColor::tabularline, on_off ? Painter::line_onoffdash : Painter::line_solid); - } - on_off = !tabular->RightLine(cell); - pain.line(x2 - tabular->GetAdditionalWidth(cell), - baseline - tabular->GetAscentOfRow(row), - x2 - tabular->GetAdditionalWidth(cell), - baseline + tabular->GetDescentOfRow(row), - on_off ? LColor::tabularonoffline : LColor::tabularline, - on_off ? Painter::line_onoffdash : Painter::line_solid); } -void InsetTabular::DrawCellSelection(Painter & pain, int x, int baseline, +void InsetTabular::drawCellSelection(Painter & pain, int x, int baseline, int row, int column, int cell) const { - int cs = tabular->column_of_cell(sel_cell_start); - int ce = tabular->column_of_cell(sel_cell_end); - if (cs > ce) { - ce = cs; - cs = tabular->column_of_cell(sel_cell_end); - } else { - ce = tabular->right_column_of_cell(sel_cell_end); - } - - int rs = tabular->row_of_cell(sel_cell_start); - int re = tabular->row_of_cell(sel_cell_end); - if (rs > re) swap(rs, re); - - if ((column >= cs) && (column <= ce) && (row >= rs) && (row <= re)) { - int w = tabular->GetWidthOfColumn(cell); - int h = tabular->GetAscentOfRow(row) + tabular->GetDescentOfRow(row); - pain.fillRectangle(x, baseline - tabular->GetAscentOfRow(row), - w, h, LColor::selection); - } + lyx::Assert(hasSelection()); + int cs = tabular->column_of_cell(sel_cell_start); + int ce = tabular->column_of_cell(sel_cell_end); + if (cs > ce) { + ce = cs; + cs = tabular->column_of_cell(sel_cell_end); + } else { + ce = tabular->right_column_of_cell(sel_cell_end); + } + + int rs = tabular->row_of_cell(sel_cell_start); + int re = tabular->row_of_cell(sel_cell_end); + if (rs > re) + swap(rs, re); + + if ((column >= cs) && (column <= ce) && (row >= rs) && (row <= re)) { + int w = tabular->GetWidthOfColumn(cell); + int h = tabular->GetAscentOfRow(row) + tabular->GetDescentOfRow(row); + pain.fillRectangle(x, baseline - tabular->GetAscentOfRow(row), + w, h, LColor::selection); + } } void InsetTabular::update(BufferView * bv, LyXFont const & font, bool reinit) { - if (reinit) { - need_update = INIT; - calculate_dimensions_of_cells(bv, font, true); - if (owner()) - owner()->update(bv, font, true); - return; - } - if (the_locking_inset) { - the_locking_inset->update(bv, font, reinit); -// resetPos(bv); -// inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell); -// inset_y = cursor.y(); - } - switch (need_update) { - case INIT: - case FULL: - case CELL: - if (calculate_dimensions_of_cells(bv, font, false)) - need_update = INIT; - break; - case SELECTION: - need_update = INIT; - break; - default: - break; - } + if (in_update) { + if (reinit) { + resetPos(bv); + if (owner()) + owner()->update(bv, font, true); + } + return; + } + in_update = true; + if (reinit) { + need_update = INIT; + if (calculate_dimensions_of_cells(bv, font, true)) + resetPos(bv); + if (owner()) + owner()->update(bv, font, true); + in_update = false; + return; + } + if (the_locking_inset) + the_locking_inset->update(bv, font, reinit); + if (need_update < FULL && + bv->text->status() == LyXText::NEED_MORE_REFRESH) + { + need_update = FULL; + } + + switch (need_update) { + case INIT: + case FULL: + case CELL: + if (calculate_dimensions_of_cells(bv, font, false)) + need_update = INIT; + break; + case SELECTION: + need_update = INIT; + break; + default: + break; + } + in_update = false; } -string const InsetTabular::EditMessage() const +string const InsetTabular::editMessage() const { - return _("Opened Tabular Inset"); + return _("Opened Tabular Inset"); } -void InsetTabular::Edit(BufferView * bv, int x, int y, unsigned int button) +void InsetTabular::edit(BufferView * bv, int x, int y, unsigned int button) { - UpdatableInset::Edit(bv, x, y, button); - - if (!bv->lockInset(this)) { - lyxerr[Debug::INSETS] << "InsetTabular::Cannot lock inset" << endl; - return; - } - locked = true; - the_locking_inset = 0; - inset_x = 0; - inset_y = 0; - setPos(bv, x, y); - sel_cell_start = sel_cell_end = actcell; - bv->text->FinishUndo(); - if (InsetHit(bv, x, y) && (button != 3)) { - ActivateCellInsetAbs(bv, x, y, button); - } -// UpdateLocal(bv, NONE, false); -// bv->getOwner()->getPopups().updateFormTabular(); -} - - -void InsetTabular::InsetUnlock(BufferView * bv) -{ - if (the_locking_inset) { - the_locking_inset->InsetUnlock(bv); + UpdatableInset::edit(bv, x, y, button); + + if (!bv->lockInset(this)) { + lyxerr[Debug::INSETTEXT] << "InsetTabular::Cannot lock inset" << endl; + return; + } + locked = true; the_locking_inset = 0; - } - HideInsetCursor(bv); - no_selection = false; - oldcell = -1; - locked = false; - if (scroll() || hasSelection()) { - sel_cell_start = sel_cell_end = 0; - if (scroll()) { - scroll(bv, 0.0F); + inset_x = 0; + inset_y = 0; + setPos(bv, x, y); + clearSelection(); + finishUndo(); + if (insetHit(bv, x, y) && (button != 3)) { + activateCellInsetAbs(bv, x, y, button); } - UpdateLocal(bv, FULL, false); - } } -void InsetTabular::UpdateLocal(BufferView * bv, UpdateCodes what, - bool mark_dirty) const +void InsetTabular::edit(BufferView * bv, bool front) { - if (need_update < what) // only set this if it has greater update - need_update = what; - if ((what == INIT) && hasSelection()) + UpdatableInset::edit(bv, front); + + if (!bv->lockInset(this)) { + lyxerr[Debug::INSETTEXT] << "InsetTabular::Cannot lock inset" << endl; + return; + } + locked = true; + the_locking_inset = 0; + inset_x = 0; + inset_y = 0; + if (front) + actcell = 0; + else + actcell = tabular->GetNumberOfCells() - 1; clearSelection(); - // Dirty Cast! (Lgb) - if (need_update != NONE) { - bv->updateInset(const_cast(this), mark_dirty); - if (locked) // && (what != NONE)) - resetPos(bv); - } + resetPos(bv); + finishUndo(); } -bool InsetTabular::LockInsetInInset(BufferView * bv, UpdatableInset * inset) +void InsetTabular::insetUnlock(BufferView * bv) { - lyxerr[Debug::INSETS] << "InsetTabular::LockInsetInInset(" <GetCellInset(actcell)) { - lyxerr[Debug::INSETS] << "OK" << endl; - the_locking_inset = tabular->GetCellInset(actcell); - resetPos(bv); - inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell); - inset_y = cursor.y(); - return true; - } else if (the_locking_inset && (the_locking_inset == inset)) { - lyxerr[Debug::INSETS] << "OK" << endl; - resetPos(bv); - inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell); - inset_y = cursor.y(); - } else if (the_locking_inset) { - lyxerr[Debug::INSETS] << "MAYBE" << endl; - return the_locking_inset->LockInsetInInset(bv, inset); - } - lyxerr[Debug::INSETS] << "NOT OK" << endl; - return false; -} - - -bool InsetTabular::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset, - bool lr) -{ - if (!the_locking_inset) - return false; - if (the_locking_inset == inset) { - the_locking_inset->InsetUnlock(bv); - the_locking_inset = 0; - UpdateLocal(bv, CELL, false); - ShowInsetCursor(bv, false); - return true; - } - if (the_locking_inset->UnlockInsetInInset(bv, inset, lr)) { - if (inset->LyxCode() == TABULAR_CODE && - !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE)) - { - bv->owner()->getDialogs()->updateTabular(this); - oldcell = actcell; + if (the_locking_inset) { + the_locking_inset->insetUnlock(bv); + the_locking_inset = 0; + } + hideInsetCursor(bv); + oldcell = -1; + locked = false; + if (scroll(false) || hasSelection()) { + clearSelection(); + if (scroll(false)) { + scroll(bv, 0.0F); + } + updateLocal(bv, FULL, false); + } +} + + +void InsetTabular::updateLocal(BufferView * bv, UpdateCodes what, + bool mark_dirty) const +{ + if (what == INIT) { + LyXFont font; + calculate_dimensions_of_cells(bv, font, true); + } + if (need_update < what) // only set this if it has greater update + need_update = what; +#if 0 // maybe this should not be done! + if ((what == INIT) && hasSelection()) { + clearSelection(); + } +#endif + // Dirty Cast! (Lgb) + if (need_update != NONE) { + bv->updateInset(const_cast(this), mark_dirty); + if (locked) // && (what != NONE)) + resetPos(bv); } - return true; - } - return false; } -bool InsetTabular::UpdateInsetInInset(BufferView * bv, Inset * inset) +bool InsetTabular::lockInsetInInset(BufferView * bv, UpdatableInset * inset) { - if (!the_locking_inset) + lyxerr[Debug::INSETTEXT] << "InsetTabular::LockInsetInInset(" + << inset << "): "; + if (!inset) + return false; + oldcell = -1; + if (inset == tabular->GetCellInset(actcell)) { + lyxerr[Debug::INSETTEXT] << "OK" << endl; + the_locking_inset = tabular->GetCellInset(actcell); + resetPos(bv); + return true; + } else if (!the_locking_inset) { + int const n = tabular->GetNumberOfCells(); + int const id = inset->id(); + for (int i = 0; i < n; ++i) { + InsetText * in = tabular->GetCellInset(i); + if (inset == in) { + actcell = i; + the_locking_inset = in; + locked = true; + resetPos(bv); + return true; + } + if (in->getInsetFromID(id)) { + actcell = i; + in->edit(bv); + return the_locking_inset->lockInsetInInset(bv, inset); + } + } + } else if (the_locking_inset && (the_locking_inset == inset)) { + lyxerr[Debug::INSETTEXT] << "OK" << endl; + resetPos(bv); + } else if (the_locking_inset) { + lyxerr[Debug::INSETTEXT] << "MAYBE" << endl; + return the_locking_inset->lockInsetInInset(bv, inset); + } + lyxerr[Debug::INSETTEXT] << "NOT OK" << endl; return false; - if (the_locking_inset != inset) { - if (!the_locking_inset->UpdateInsetInInset(bv, inset)) - return false; - } - UpdateLocal(bv, CELL, false); - return true; } -unsigned int InsetTabular::InsetInInsetY() +bool InsetTabular::unlockInsetInInset(BufferView * bv, UpdatableInset * inset, + bool lr) { - if (!the_locking_inset) - return 0; + if (!the_locking_inset) + return false; + if (the_locking_inset == inset) { + the_locking_inset->insetUnlock(bv); + the_locking_inset = 0; +#ifdef WITH_WARNINGS +#warning fix scrolling when cellinset has requested a scroll (Jug)!!! +#endif +#if 0 + if (scroll(false)) + scroll(bv, 0.0F); +#endif + updateLocal(bv, CELL, false); + showInsetCursor(bv, false); + return true; + } + if (the_locking_inset->unlockInsetInInset(bv, inset, lr)) { + if (inset->lyxCode() == TABULAR_CODE && + !the_locking_inset->getFirstLockingInsetOfType(TABULAR_CODE)) { + bv->owner()->getDialogs()->updateTabular(this); + oldcell = actcell; + } + return true; + } + return false; +} - return (inset_y + the_locking_inset->InsetInInsetY()); + +bool InsetTabular::updateInsetInInset(BufferView * bv, Inset * inset) +{ + if (!the_locking_inset) + return false; + if (the_locking_inset != inset) { + if (!the_locking_inset->updateInsetInInset(bv, inset)) + return false; + } + updateLocal(bv, CELL, false); + return true; } -UpdatableInset * InsetTabular::GetLockingInset() +unsigned int InsetTabular::insetInInsetY() { - return the_locking_inset ? the_locking_inset->GetLockingInset() : this; + if (!the_locking_inset) + return 0; + return inset_y + the_locking_inset->insetInInsetY(); } -UpdatableInset * InsetTabular::GetFirstLockingInsetOfType(Inset::Code c) +UpdatableInset * InsetTabular::getLockingInset() const { - if (c == LyxCode()) - return this; - if (the_locking_inset) - return the_locking_inset->GetFirstLockingInsetOfType(c); - return 0; + return the_locking_inset ? the_locking_inset->getLockingInset() : + const_cast(this); } -bool InsetTabular::InsertInset(BufferView * bv, Inset * inset) +UpdatableInset * InsetTabular::getFirstLockingInsetOfType(Inset::Code c) { - if (the_locking_inset) - return the_locking_inset->InsertInset(bv, inset); - return false; + if (c == lyxCode()) + return this; + if (the_locking_inset) + return the_locking_inset->getFirstLockingInsetOfType(c); + return 0; } -void InsetTabular::InsetButtonPress(BufferView * bv, int x, int y, int button) +bool InsetTabular::insertInset(BufferView * bv, Inset * inset) { - if (hasSelection() && (button == 3)) - return; + if (the_locking_inset) + return the_locking_inset->insertInset(bv, inset); + return false; +} - if (hasSelection()) { - clearSelection(); - UpdateLocal(bv, SELECTION, false); - } - no_selection = false; +void InsetTabular::insetButtonPress(BufferView * bv, int x, int y, int button) +{ + if (hasSelection() && (button == 3)) + return; + + if (hasSelection()) { + clearSelection(); + updateLocal(bv, SELECTION, false); + } - int const ocell = actcell; - int const orow = actrow; + int const ocell = actcell; + int const orow = actrow; - HideInsetCursor(bv); - setPos(bv, x, y); - if (actrow != orow) - UpdateLocal(bv, NONE, false); - sel_cell_start = sel_cell_end = actcell; - if (button == 3) { - if ((ocell != actcell) && the_locking_inset) { - the_locking_inset->InsetUnlock(bv); - the_locking_inset = 0; + hideInsetCursor(bv); + setPos(bv, x, y); + if (actrow != orow) + updateLocal(bv, NONE, false); + clearSelection(); +#if 0 + if (button == 3) { + if ((ocell != actcell) && the_locking_inset) { + the_locking_inset->insetUnlock(bv); + the_locking_inset = 0; + } + showInsetCursor(bv); + return; } - ShowInsetCursor(bv); - return; - } +#endif - bool const inset_hit = InsetHit(bv, x, y); + bool const inset_hit = insetHit(bv, x, y); - if ((ocell == actcell) && the_locking_inset && inset_hit) { - resetPos(bv); - the_locking_inset->InsetButtonPress(bv, - x - inset_x, y - inset_y, button); - return; - } else if (the_locking_inset) { - the_locking_inset->InsetUnlock(bv); - } - the_locking_inset = 0; - if (button == 2) { - LocalDispatch(bv, LFUN_PASTESELECTION, "paragraph"); - return; - } - if (inset_hit && bv->theLockingInset()) { - if (ActivateCellInsetAbs(bv, x, y, button)) - the_locking_inset->InsetButtonPress(bv, x - inset_x, - y - inset_y, button); - return; - } - ShowInsetCursor(bv); + if ((ocell == actcell) && the_locking_inset && inset_hit) { + resetPos(bv); + the_locking_inset->insetButtonPress(bv, + x - inset_x, y - inset_y, + button); + return; + } else if (the_locking_inset) { + the_locking_inset->insetUnlock(bv); + } + the_locking_inset = 0; + if (button == 2) { + localDispatch(bv, LFUN_PASTESELECTION, "paragraph"); + return; + } + if (inset_hit && bv->theLockingInset()) { + if (activateCellInsetAbs(bv, x, y, button)) + the_locking_inset->insetButtonPress(bv, + x - inset_x, + y - inset_y, + button); + return; + } + showInsetCursor(bv); } -void InsetTabular::InsetButtonRelease(BufferView * bv, - int x, int y, int button) +bool InsetTabular::insetButtonRelease(BufferView * bv, + int x, int y, int button) { - if (button == 3) { - if (the_locking_inset) { - UpdatableInset * i; - if ((i=the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))) { - i->InsetButtonRelease(bv, x, y, button); - return; - } + bool ret = false; + if (the_locking_inset) + ret = the_locking_inset->insetButtonRelease(bv, x - inset_x, + y - inset_y, button); + if (button == 3 && !ret) { + bv->owner()->getDialogs()->showTabular(this); + return true; } - bv->owner()->getDialogs()->showTabular(this); - return; - } - if (the_locking_inset) { - the_locking_inset->InsetButtonRelease(bv, x-inset_x, y-inset_y,button); - return; - } - no_selection = false; + return ret; } -void InsetTabular::InsetMotionNotify(BufferView * bv, int x, int y, int button) +void InsetTabular::insetMotionNotify(BufferView * bv, int x, int y, int button) { - if (the_locking_inset) { - the_locking_inset->InsetMotionNotify(bv, x - inset_x, - y - inset_y, button); - return; - } - if (!no_selection) { - HideInsetCursor(bv); - int const old_cell = actcell; - + if (the_locking_inset) { + the_locking_inset->insetMotionNotify(bv, + x - inset_x, + y - inset_y, + button); + return; + } + + hideInsetCursor(bv); +// int const old_cell = actcell; + setPos(bv, x, y); - sel_cell_end = actcell; - if (sel_cell_end != old_cell) - UpdateLocal(bv, SELECTION, false); - ShowInsetCursor(bv); - } - no_selection = false; + if (!hasSelection()) { + setSelection(actcell, actcell); + } else { + setSelection(sel_cell_start, actcell); + } + updateLocal(bv, SELECTION, false); + showInsetCursor(bv); } -void InsetTabular::InsetKeyPress(XKeyEvent * xke) +void InsetTabular::insetKeyPress(XKeyEvent * xke) { - if (the_locking_inset) { - the_locking_inset->InsetKeyPress(xke); - return; - } + if (the_locking_inset) { + the_locking_inset->insetKeyPress(xke); + return; + } } -UpdatableInset::RESULT InsetTabular::LocalDispatch(BufferView * bv, - kb_action action, - string const & arg) +UpdatableInset::RESULT +InsetTabular::localDispatch(BufferView * bv, kb_action action, + string const & arg) { - // We need to save the value of the_locking_inset as the call to - // the_locking_inset->LocalDispatch might unlock it. - old_locking_inset = the_locking_inset; - no_selection = false; - UpdatableInset::RESULT result = - UpdatableInset::LocalDispatch(bv, action, arg); - if (result == DISPATCHED || result == DISPATCHED_NOUPDATE) { - resetPos(bv); - return result; - } - - if ((action < 0) && arg.empty()) - return FINISHED; - - if (the_locking_inset) { - result=the_locking_inset->LocalDispatch(bv, action, arg); - if (result == DISPATCHED_NOUPDATE) { - int sc = scroll(); - resetPos(bv); - if (sc != scroll()) { // inset has been scrolled - the_locking_inset->ToggleInsetCursor(bv); - UpdateLocal(bv, FULL, false); - the_locking_inset->ToggleInsetCursor(bv); - } - return result; - } else if (result == DISPATCHED) { - the_locking_inset->ToggleInsetCursor(bv); - UpdateLocal(bv, CELL, false); - the_locking_inset->ToggleInsetCursor(bv); - return result; - } else if (result == FINISHED) { - } - } - - bool hs = hasSelection(); - HideInsetCursor(bv); - result=DISPATCHED; - switch (action) { - // --- Cursor Movements --------------------------------------------- - case LFUN_RIGHTSEL: - if (tabular->IsLastCellInRow(actcell)) - break; - moveRight(bv, false); - sel_cell_end = actcell; - UpdateLocal(bv, SELECTION, false); - break; - case LFUN_RIGHT: - result = moveRight(bv); - sel_cell_start = sel_cell_end = actcell; - if (hs) - UpdateLocal(bv, SELECTION, false); - break; - case LFUN_LEFTSEL: - if (tabular->IsFirstCellInRow(actcell)) - break; - moveLeft(bv, false); - sel_cell_end = actcell; - UpdateLocal(bv, SELECTION, false); - break; - case LFUN_LEFT: - result = moveLeft(bv); - sel_cell_start = sel_cell_end = actcell; - if (hs) - UpdateLocal(bv, SELECTION, false); - break; - case LFUN_DOWNSEL: - { - int const ocell = actcell; - moveDown(bv, false); - if ((ocell == sel_cell_end) || - (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell))) - sel_cell_end = tabular->GetCellBelow(sel_cell_end); - else - sel_cell_end = tabular->GetLastCellBelow(sel_cell_end); - UpdateLocal(bv, SELECTION, false); - } - break; - case LFUN_DOWN: - result = moveDown(bv, old_locking_inset != 0); - sel_cell_start = sel_cell_end = actcell; - if (hs) - UpdateLocal(bv, SELECTION, false); - break; - case LFUN_UPSEL: - { - int const ocell = actcell; - moveUp(bv, false); - if ((ocell == sel_cell_end) || - (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell))) - sel_cell_end = tabular->GetCellAbove(sel_cell_end); - else - sel_cell_end = tabular->GetLastCellAbove(sel_cell_end); - UpdateLocal(bv, SELECTION, false); - } - break; - case LFUN_UP: - result = moveUp(bv, old_locking_inset != 0); - sel_cell_start = sel_cell_end = actcell; - if (hs) - UpdateLocal(bv, SELECTION, false); - break; - case LFUN_NEXT: { - int column = actcol; - if (the_locking_inset) { - UnlockInsetInInset(bv, the_locking_inset); - the_locking_inset = 0; + // We need to save the value of the_locking_inset as the call to + // the_locking_inset->LocalDispatch might unlock it. + old_locking_inset = the_locking_inset; + UpdatableInset::RESULT result = + UpdatableInset::localDispatch(bv, action, arg); + if (result == DISPATCHED || result == DISPATCHED_NOUPDATE) { + resetPos(bv); + return result; } - if (bv->text->first + bv->painter().paperHeight() < - (top_baseline + tabular->GetHeightOfTabular())) - { - bv->scrollCB(bv->text->first + bv->painter().paperHeight()); - UpdateLocal(bv, FULL, false); - actcell = tabular->GetCellBelow(first_visible_cell) + column; - } else { - actcell = tabular->GetFirstCellInRow(tabular->rows() - 1) + column; + + if ((action < 0) && arg.empty()) + return FINISHED; + + bool hs = hasSelection(); + + result = DISPATCHED; + // this one have priority over the locked InsetText, if we're not already + // inside another tabular then that one get's priority! + if (getFirstLockingInsetOfType(Inset::TABULAR_CODE) == this) { + switch (action) { + case LFUN_SHIFT_TAB: + case LFUN_TAB: + hideInsetCursor(bv); + unlockInsetInInset(bv, the_locking_inset); + if (action == LFUN_TAB) + moveNextCell(bv, old_locking_inset != 0); + else + movePrevCell(bv, old_locking_inset != 0); + clearSelection(); + if (hs) + updateLocal(bv, SELECTION, false); + if (!the_locking_inset) { + showInsetCursor(bv); + return DISPATCHED_NOUPDATE; + } + return result; + // this to avoid compiler warnings. + default: + break; + } } - resetPos(bv); - UpdateLocal(bv, CURSOR, false); - break; - } - case LFUN_PRIOR: { - int column = actcol; + if (the_locking_inset) { - UnlockInsetInInset(bv, the_locking_inset); - the_locking_inset = 0; - } - if (top_baseline < 0) { - bv->scrollCB(bv->text->first - bv->painter().paperHeight()); - UpdateLocal(bv, FULL, false); - if (top_baseline > 0) - actcell = column; - else - actcell = tabular->GetCellBelow(first_visible_cell) + column; - } else { - actcell = column; + result = the_locking_inset->localDispatch(bv, action, arg); + if (result == DISPATCHED_NOUPDATE) { + int sc = scroll(); + resetPos(bv); + if (sc != scroll()) { // inset has been scrolled + the_locking_inset->toggleInsetCursor(bv); + updateLocal(bv, FULL, false); + the_locking_inset->toggleInsetCursor(bv); + } + return result; + } else if (result == DISPATCHED) { + the_locking_inset->toggleInsetCursor(bv); + updateLocal(bv, CELL, false); + the_locking_inset->toggleInsetCursor(bv); + return result; + } else if (result == FINISHED_UP) { + action = LFUN_UP; + } else if (result == FINISHED_DOWN) { + action = LFUN_DOWN; + } else if (result == FINISHED_RIGHT) { + action = LFUN_RIGHT; + } } - resetPos(bv); - UpdateLocal(bv, CURSOR, false); - break; - } - case LFUN_BACKSPACE: - break; - case LFUN_DELETE: - break; - case LFUN_HOME: - break; - case LFUN_END: - break; - case LFUN_SHIFT_TAB: - case LFUN_TAB: - { - if (the_locking_inset) { - UnlockInsetInInset(bv, the_locking_inset); - the_locking_inset = 0; + + hideInsetCursor(bv); + result = DISPATCHED; + switch (action) { + // --- Cursor Movements ---------------------------------- + case LFUN_RIGHTSEL: { + int const start = hasSelection() ? sel_cell_start : actcell; + if (tabular->IsLastCellInRow(actcell)) { + setSelection(start, actcell); + break; + } + + int end = actcell; + // if we are starting a selection, only select + // the current cell at the beginning + if (hasSelection()) { + moveRight(bv, false); + end = actcell; + } + setSelection(start, end); + updateLocal(bv, SELECTION, false); + break; + } + case LFUN_RIGHT: + result = moveRight(bv); + clearSelection(); + if (hs) + updateLocal(bv, SELECTION, false); + break; + case LFUN_LEFTSEL: { + int const start = hasSelection() ? sel_cell_start : actcell; + if (tabular->IsFirstCellInRow(actcell)) { + setSelection(start, actcell); + break; + } + + int end = actcell; + // if we are starting a selection, only select + // the current cell at the beginning + if (hasSelection()) { + moveLeft(bv, false); + end = actcell; + } + setSelection(start, end); + updateLocal(bv, SELECTION, false); + break; + } + case LFUN_LEFT: + result = moveLeft(bv); + clearSelection(); + if (hs) + updateLocal(bv, SELECTION, false); + break; + case LFUN_DOWNSEL: { + int const start = hasSelection() ? sel_cell_start : actcell; + int const ocell = actcell; + // if we are starting a selection, only select + // the current cell at the beginning + if (hasSelection()) { + moveDown(bv, false); + if ((ocell == sel_cell_end) || + (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell))) + setSelection(start, tabular->GetCellBelow(sel_cell_end)); + else + setSelection(start, tabular->GetLastCellBelow(sel_cell_end)); + } else { + setSelection(start, start); + } + updateLocal(bv, SELECTION, false); } - if (action == LFUN_TAB) - moveNextCell(bv, old_locking_inset != 0); - else - movePrevCell(bv, old_locking_inset != 0); - sel_cell_start = sel_cell_end = actcell; - if (hs) - UpdateLocal(bv, SELECTION, false); - break; - } - case LFUN_LAYOUT_TABULAR: - { - bv->owner()->getDialogs()->showTabular(this); - } - break; - case LFUN_TABULAR_FEATURE: - if (!TabularFeatures(bv, arg)) - result = UNDISPATCHED; - break; - case LFUN_CUT: - if (!copySelection(bv)) - break; - bv->text->SetUndo(bv->buffer(), Undo::DELETE, -#ifndef NEW_INSETS - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_ -#else - bv->text->cursor.par()->previous(), - bv->text->cursor.par()->next() -#endif - ); - cutSelection(); - UpdateLocal(bv, INIT, true); - break; - case LFUN_COPY: - if (!hasSelection()) - break; - bv->text->FinishUndo(); - copySelection(bv); break; - case LFUN_PASTESELECTION: - { - string clip(bv->workarea()->getClipboard()); - - if (clip.empty()) - break; - if (clip.find('\t') != string::npos) { - int cols = 1; - int rows = 1; - int maxCols = 1; - unsigned int len = clip.length(); - string::size_type p = 0; - - while((p < len) && - ((p = clip.find_first_of("\t\n", p)) != string::npos)) - { - switch(clip[p]) { - case '\t': - ++cols; - break; - case '\n': - if ((p+1) < len) - ++rows; - maxCols = max(cols, maxCols); - cols = 1; - break; + case LFUN_DOWN: + result = moveDown(bv, old_locking_inset != 0); + clearSelection(); + if (hs) { + updateLocal(bv, SELECTION, false); } - ++p; - } - maxCols = max(cols, maxCols); - delete paste_tabular; - paste_tabular = new LyXTabular(this, rows, maxCols); - string::size_type op = 0; - int cell = 0; - int cells = paste_tabular->GetNumberOfCells(); - p = cols = 0; - while((cell < cells) && (p < len) && - (p = clip.find_first_of("\t\n", p)) != string::npos) - { - if (p >= len) - break; - switch(clip[p]) { - case '\t': - paste_tabular->GetCellInset(cell)->SetText(clip.substr(op, p-op)); - ++cols; - ++cell; - break; - case '\n': - paste_tabular->GetCellInset(cell)->SetText(clip.substr(op, p-op)); - while(cols++ < maxCols) - ++cell; - cols = 0; - break; + break; + case LFUN_UPSEL: { + int const start = hasSelection() ? sel_cell_start : actcell; + int const ocell = actcell; + // if we are starting a selection, only select + // the current cell at the beginning + if (hasSelection()) { + moveUp(bv, false); + if ((ocell == sel_cell_end) || + (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell))) + setSelection(start, tabular->GetCellAbove(sel_cell_end)); + else + setSelection(start, tabular->GetLastCellAbove(sel_cell_end)); + } else { + setSelection(start, start); } - ++p; - op = p; - } - // check for the last cell if there is no trailing '\n' - if ((cell < cells) && (op < len)) - paste_tabular->GetCellInset(cell)->SetText(clip.substr(op, len-op)); - } else { - // so that the clipboard is used and it goes on to default - // and executes LFUN_PASTESELECTION in insettext! - delete paste_tabular; - paste_tabular = 0; - } - } - case LFUN_PASTE: - if (hasPasteBuffer()) { - bv->text->SetUndo(bv->buffer(), Undo::INSERT, -#ifndef NEW_INSETS - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_ -#else - bv->text->cursor.par()->previous(), - bv->text->cursor.par()->next() -#endif - ); - pasteSelection(bv); - UpdateLocal(bv, INIT, true); - break; - } - // ATTENTION: the function above has to be PASTE and PASTESELECTION!!! - default: - // we try to activate the actual inset and put this event down to - // the insets dispatch function. - result = UNDISPATCHED; - if (the_locking_inset) - break; - no_draw = true; - if (ActivateCellInset(bv)) { - result=the_locking_inset->LocalDispatch(bv, action, arg); - if ((result == UNDISPATCHED) || (result == FINISHED)) { - UnlockInsetInInset(bv, the_locking_inset); - no_draw = false; - the_locking_inset = 0; - return UNDISPATCHED; - } - no_draw = false; - the_locking_inset->ToggleInsetCursor(bv); - UpdateLocal(bv, CELL, false); - the_locking_inset->ToggleInsetCursor(bv); - return result; + updateLocal(bv, SELECTION, false); } break; - } - if (result!=FINISHED) { - if (!the_locking_inset) { - ShowInsetCursor(bv); + case LFUN_UP: + result = moveUp(bv, old_locking_inset != 0); + clearSelection(); + if (hs) + updateLocal(bv, SELECTION, false); + break; + case LFUN_NEXT: { + int column = actcol; + unlockInsetInInset(bv, the_locking_inset); + if (bv->text->first + bv->painter().paperHeight() < + (top_baseline + tabular->GetHeightOfTabular())) + { + bv->scrollCB(bv->text->first + bv->painter().paperHeight()); + updateLocal(bv, FULL, false); + actcell = tabular->GetCellBelow(first_visible_cell) + column; + } else { + actcell = tabular->GetFirstCellInRow(tabular->rows() - 1) + column; + } + resetPos(bv); + updateLocal(bv, CURSOR, false); + break; } - } else - bv->unlockInset(this); - return result; -} - - -int InsetTabular::Latex(Buffer const * buf, ostream & os, - bool fragile, bool fp) const -{ - return tabular->Latex(buf, os, fragile, fp); + case LFUN_PRIOR: { + int column = actcol; + unlockInsetInInset(bv, the_locking_inset); + if (top_baseline < 0) { + bv->scrollCB(bv->text->first - bv->painter().paperHeight()); + updateLocal(bv, FULL, false); + if (top_baseline > 0) + actcell = column; + else + actcell = tabular->GetCellBelow(first_visible_cell) + column; + } else { + actcell = column; + } + resetPos(bv); + updateLocal(bv, CURSOR, false); + break; + } + // none of these make sense for insettabular, + // but we must catch them to prevent any + // selection from being confused + case LFUN_PRIORSEL: + case LFUN_NEXTSEL: + case LFUN_WORDLEFT: + case LFUN_WORDLEFTSEL: + case LFUN_WORDRIGHT: + case LFUN_WORDRIGHTSEL: + case LFUN_DOWN_PARAGRAPH: + case LFUN_DOWN_PARAGRAPHSEL: + case LFUN_UP_PARAGRAPH: + case LFUN_UP_PARAGRAPHSEL: + case LFUN_BACKSPACE: + case LFUN_DELETE: + case LFUN_HOME: + case LFUN_HOMESEL: + case LFUN_END: + case LFUN_ENDSEL: + case LFUN_BEGINNINGBUF: + case LFUN_BEGINNINGBUFSEL: + case LFUN_ENDBUF: + case LFUN_ENDBUFSEL: + break; + case LFUN_LAYOUT_TABULAR: + bv->owner()->getDialogs()->showTabular(this); + break; + case LFUN_TABULAR_FEATURE: + if (!tabularFeatures(bv, arg)) + result = UNDISPATCHED; + break; + case LFUN_CUT: + if (!copySelection(bv)) + break; + setUndo(bv, Undo::DELETE, + bv->text->cursor.par(), + bv->text->cursor.par()->next()); + cutSelection(); + updateLocal(bv, INIT, true); + break; + case LFUN_COPY: + if (!hasSelection()) + break; + finishUndo(); + copySelection(bv); + break; + case LFUN_PASTESELECTION: + { + string const clip(bv->getClipboard()); + + if (clip.empty()) + break; + if (clip.find('\t') != string::npos) { + int cols = 1; + int rows = 1; + int maxCols = 1; + string::size_type len = clip.length(); + string::size_type p = 0; + + while (p < len && + ((p = clip.find_first_of("\t\n", p)) != string::npos)) { + switch (clip[p]) { + case '\t': + ++cols; + break; + case '\n': + if ((p+1) < len) + ++rows; + maxCols = max(cols, maxCols); + cols = 1; + break; + } + ++p; + } + maxCols = max(cols, maxCols); + delete paste_tabular; + paste_tabular = new LyXTabular(this, rows, maxCols); + string::size_type op = 0; + int cell = 0; + int cells = paste_tabular->GetNumberOfCells(); + p = cols = 0; + while ((cell < cells) && (p < len) && + (p = clip.find_first_of("\t\n", p)) != string::npos) { + if (p >= len) + break; + switch (clip[p]) { + case '\t': + paste_tabular->GetCellInset(cell)->setText(clip.substr(op, p-op)); + ++cols; + ++cell; + break; + case '\n': + paste_tabular->GetCellInset(cell)->setText(clip.substr(op, p-op)); + while (cols++ < maxCols) + ++cell; + cols = 0; + break; + } + ++p; + op = p; + } + // check for the last cell if there is no trailing '\n' + if ((cell < cells) && (op < len)) + paste_tabular->GetCellInset(cell)->setText(clip.substr(op, len-op)); + } else { + // so that the clipboard is used and it goes on + // to default + // and executes LFUN_PASTESELECTION in insettext! + delete paste_tabular; + paste_tabular = 0; + } + } + case LFUN_PASTE: + if (hasPasteBuffer()) { + setUndo(bv, Undo::INSERT, + bv->text->cursor.par(), + bv->text->cursor.par()->next()); + pasteSelection(bv); + updateLocal(bv, INIT, true); + break; + } + // ATTENTION: the function above has to be PASTE and PASTESELECTION!!! + default: + // we try to activate the actual inset and put this event down to + // the insets dispatch function. + result = UNDISPATCHED; + if (the_locking_inset) + break; + nodraw(true); + if (activateCellInset(bv)) { + // reset need_update setted in above function! + need_update = NONE; + result = the_locking_inset->localDispatch(bv, action, arg); + if ((result == UNDISPATCHED) || (result >= FINISHED)) { + unlockInsetInInset(bv, the_locking_inset); + nodraw(false); + // we need to update if this was requested before + updateLocal(bv, NONE, false); + return UNDISPATCHED; + } else if (hs) { + clearSelection(); + } + nodraw(false); + updateLocal(bv, CELL, false); + return result; + } + break; + } + if (result < FINISHED) { + if (!the_locking_inset) { + showInsetCursor(bv); + } + } else + bv->unlockInset(this); + return result; } -int InsetTabular::Ascii(Buffer const * buf, ostream & os, int) const +int InsetTabular::latex(Buffer const * buf, ostream & os, + bool fragile, bool fp) const { - // This should be changed to a real ascii export - return tabular->Ascii(buf, os); + return tabular->latex(buf, os, fragile, fp); } -int InsetTabular::Linuxdoc(Buffer const *, ostream &) const +int InsetTabular::ascii(Buffer const * buf, ostream & os, int ll) const { - return 0; + if (ll > 0) + return tabular->ascii(buf, os, (int)parOwner()->params().depth(), + false,0); + return tabular->ascii(buf, os, 0, false,0); } -int InsetTabular::DocBook(Buffer const * buf, ostream & os) const +int InsetTabular::linuxdoc(Buffer const * buf, ostream & os) const { - return tabular->DocBook(buf,os); + os << "ascii(buf,os, + (int)parOwner()->params().depth(), + false, 0); + os << "]]>"; + return ret; } -void InsetTabular::Validate(LaTeXFeatures & features) const +int InsetTabular::docbook(Buffer const * buf, ostream & os) const { - tabular->Validate(features); -} + int ret = 0; + Inset * master; + // if the table is inside a float it doesn't need the informaltable + // wrapper. Search for it. + for(master = owner(); + master && master->lyxCode() != Inset::FLOAT_CODE; + master = master->owner()); -bool InsetTabular::calculate_dimensions_of_cells(BufferView * bv, - LyXFont const & font, - bool reinit) const -{ - int cell = -1; - int maxAsc = 0; - int maxDesc = 0; - InsetText * inset; - bool changed = false; - - // if we have a locking_inset we should have to check only this cell for - // change so I'll try this to have a boost, but who knows ;) - if ((need_update != INIT) && - (the_locking_inset == tabular->GetCellInset(actcell))) { - for(int i = 0; i < tabular->columns(); ++i) { - maxAsc = max(tabular->GetCellInset(actrow, i)->ascent(bv, font), - maxAsc); - maxDesc = max(tabular->GetCellInset(actrow, i)->descent(bv, font), - maxDesc); - } - changed = tabular->SetWidthOfCell(actcell, the_locking_inset->width(bv, font)); - changed = tabular->SetAscentOfRow(actrow, maxAsc + ADD_TO_HEIGHT) || changed; - changed = tabular->SetDescentOfRow(actrow, maxDesc + ADD_TO_HEIGHT) || changed; - return changed; - } - for (int i = 0; i < tabular->rows(); ++i) { - maxAsc = 0; - maxDesc = 0; - for (int j= 0; j < tabular->columns(); ++j) { - if (tabular->IsPartOfMultiColumn(i,j)) - continue; - ++cell; - inset = tabular->GetCellInset(cell); - if (!reinit) - inset->update(bv, font, false); - maxAsc = max(maxAsc, inset->ascent(bv, font)); - maxDesc = max(maxDesc, inset->descent(bv, font)); - changed = tabular->SetWidthOfCell(cell, inset->width(bv, font)) || changed; + if (!master) { + os << "\n"; + ret++; + } + ret+= tabular->docBook(buf,os); + if (!master) { + os << "\n"; + ret++; } - changed = tabular->SetAscentOfRow(i, maxAsc + ADD_TO_HEIGHT) || changed; - changed = tabular->SetDescentOfRow(i, maxDesc + ADD_TO_HEIGHT) || changed; - } - return changed; + return ret; } -void InsetTabular::GetCursorPos(BufferView *, - int & x, int & y) const +void InsetTabular::validate(LaTeXFeatures & features) const { - x = cursor.x() - top_x; - y = cursor.y(); + tabular->Validate(features); } -void InsetTabular::ToggleInsetCursor(BufferView * bv) -{ - if (the_locking_inset) { - the_locking_inset->ToggleInsetCursor(bv); - return; - } +bool InsetTabular::calculate_dimensions_of_cells(BufferView * bv, + LyXFont const & font, + bool reinit) const +{ + int cell = -1; + int maxAsc = 0; + int maxDesc = 0; + InsetText * inset; + bool changed = false; + + // if we have a locking_inset we should have to check only this cell for + // change so I'll try this to have a boost, but who knows ;) + if ((need_update != INIT) && + (the_locking_inset == tabular->GetCellInset(actcell))) { + for(int i = 0; i < tabular->columns(); ++i) { + maxAsc = max(tabular->GetCellInset(actrow, i)->ascent(bv, font), + maxAsc); + maxDesc = max(tabular->GetCellInset(actrow, i)->descent(bv, font), + maxDesc); + } + changed = tabular->SetWidthOfCell(actcell, the_locking_inset->width(bv, font)); + changed = tabular->SetAscentOfRow(actrow, maxAsc + ADD_TO_HEIGHT) || changed; + changed = tabular->SetDescentOfRow(actrow, maxDesc + ADD_TO_HEIGHT) || changed; + return changed; + } + for (int i = 0; i < tabular->rows(); ++i) { + maxAsc = 0; + maxDesc = 0; + for (int j = 0; j < tabular->columns(); ++j) { + if (tabular->IsPartOfMultiColumn(i,j)) + continue; + ++cell; + inset = tabular->GetCellInset(cell); + if (!reinit && !tabular->GetPWidth(cell).zero()) + inset->update(bv, font, false); + maxAsc = max(maxAsc, inset->ascent(bv, font)); + maxDesc = max(maxDesc, inset->descent(bv, font)); + changed = tabular->SetWidthOfCell(cell, inset->width(bv, font)) || changed; + } + changed = tabular->SetAscentOfRow(i, maxAsc + ADD_TO_HEIGHT) || changed; + changed = tabular->SetDescentOfRow(i, maxDesc + ADD_TO_HEIGHT) || changed; + } + if (changed) + tabular->reinit(); + return changed; +} - LyXFont font; // = the_locking_inset->GetFont(par, cursor.pos); - int const asc = lyxfont::maxAscent(font); - int const desc = lyxfont::maxDescent(font); - - if (cursor_visible) - bv->hideLockedInsetCursor(); - else - bv->showLockedInsetCursor(cursor.x(), cursor.y(), asc, desc); - cursor_visible = !cursor_visible; +void InsetTabular::getCursorPos(BufferView * bv, int & x, int & y) const +{ + if (the_locking_inset) { + the_locking_inset->getCursorPos(bv, x, y); + return; + } + x = cursor_.x() - top_x; + y = cursor_.y(); } -void InsetTabular::ShowInsetCursor(BufferView * bv, bool show) +void InsetTabular::toggleInsetCursor(BufferView * bv) { - if (!cursor_visible) { - LyXFont font; // = GetFont(par, cursor.pos); - + if (nodraw()) { + if (isCursorVisible()) + bv->hideLockedInsetCursor(); + return; + } + if (the_locking_inset) { + the_locking_inset->toggleInsetCursor(bv); + return; + } + + LyXFont font; // = the_locking_inset->GetFont(par, cursor.pos); + int const asc = lyxfont::maxAscent(font); int const desc = lyxfont::maxDescent(font); - bv->fitLockedInsetCursor(cursor.x(), cursor.y(), asc, desc); - if (show) - bv->showLockedInsetCursor(cursor.x(), cursor.y(), asc, desc); - cursor_visible = true; - } + + if (isCursorVisible()) + bv->hideLockedInsetCursor(); + else + bv->showLockedInsetCursor(cursor_.x(), cursor_.y(), asc, desc); + toggleCursorVisible(); } -void InsetTabular::HideInsetCursor(BufferView * bv) +void InsetTabular::showInsetCursor(BufferView * bv, bool show) { - if (cursor_visible) { - bv->hideLockedInsetCursor(); - cursor_visible = false; - } -// if (cursor_visible) -// ToggleInsetCursor(bv); + if (nodraw()) + return; + if (!isCursorVisible()) { + LyXFont font; // = GetFont(par, cursor.pos); + + int const asc = lyxfont::maxAscent(font); + int const desc = lyxfont::maxDescent(font); + bv->fitLockedInsetCursor(cursor_.x(), cursor_.y(), asc, desc); + if (show) + bv->showLockedInsetCursor(cursor_.x(), cursor_.y(), asc, desc); + setCursorVisible(true); + } +} + + +void InsetTabular::hideInsetCursor(BufferView * bv) +{ + if (isCursorVisible()) { + bv->hideLockedInsetCursor(); + setCursorVisible(false); + } +} + + +void InsetTabular::fitInsetCursor(BufferView * bv) const +{ + if (the_locking_inset) { + the_locking_inset->fitInsetCursor(bv); + return; + } + LyXFont font; + + int const asc = lyxfont::maxAscent(font); + int const desc = lyxfont::maxDescent(font); + bv->fitLockedInsetCursor(cursor_.x(), cursor_.y(), asc, desc); } void InsetTabular::setPos(BufferView * bv, int x, int y) const { - cursor.y(0); + cursor_.y(0); - actcell = actrow = actcol = 0; - int ly = tabular->GetDescentOfRow(actrow); - - // first search the right row - while((ly < y) && (actrow < tabular->rows())) { - cursor.y(cursor.y() + tabular->GetDescentOfRow(actrow) + - tabular->GetAscentOfRow(actrow + 1) + - tabular->GetAdditionalHeight(tabular->GetCellNumber(actrow + 1, - actcol))); - ++actrow; - ly = cursor.y() + tabular->GetDescentOfRow(actrow); - } - actcell = tabular->GetCellNumber(actrow, actcol); - - // now search the right column - int lx = tabular->GetWidthOfColumn(actcell) - - tabular->GetAdditionalWidth(actcell); -#if 0 -#warning Jürgen, can you rewrite this to _not_ use the sequencing operator. (Lgb) - for (; !tabular->IsLastCellInRow(actcell) && (lx < x); - ++actcell,lx += tabular->GetWidthOfColumn(actcell) + - tabular->GetAdditionalWidth(actcell - 1)); -#else - // Jürgen, you should check that this is correct. (Lgb) - for (; !tabular->IsLastCellInRow(actcell) && lx < x; ++actcell) { - lx += tabular->GetWidthOfColumn(actcell + 1) - + tabular->GetAdditionalWidth(actcell); - } - -#endif - cursor.x(lx - tabular->GetWidthOfColumn(actcell) + top_x + 2); - resetPos(bv); + actcell = actrow = actcol = 0; + int ly = tabular->GetDescentOfRow(actrow); + + // first search the right row + while ((ly < y) && ((actrow+1) < tabular->rows())) { + cursor_.y(cursor_.y() + tabular->GetDescentOfRow(actrow) + + tabular->GetAscentOfRow(actrow + 1) + + tabular->GetAdditionalHeight(actrow + 1)); + ++actrow; + ly = cursor_.y() + tabular->GetDescentOfRow(actrow); + } + actcell = tabular->GetCellNumber(actrow, actcol); + + // now search the right column + int lx = tabular->GetWidthOfColumn(actcell) - + tabular->GetAdditionalWidth(actcell); + for (; !tabular->IsLastCellInRow(actcell) && lx < x; ++actcell) { + lx += tabular->GetWidthOfColumn(actcell + 1) + + tabular->GetAdditionalWidth(actcell); + } + cursor_.x(lx - tabular->GetWidthOfColumn(actcell) + top_x + 2); + resetPos(bv); } int InsetTabular::getCellXPos(int cell) const { - int c = cell; - - for (; !tabular->IsFirstCellInRow(c); --c) - ; - int lx = tabular->GetWidthOfColumn(cell); - for (; c < cell; ++c) { - lx += tabular->GetWidthOfColumn(c); - } - return (lx - tabular->GetWidthOfColumn(cell) + top_x); + int c = cell; + + for (; !tabular->IsFirstCellInRow(c); --c) + ; + int lx = tabular->GetWidthOfColumn(cell); + for (; c < cell; ++c) { + lx += tabular->GetWidthOfColumn(c); + } + return (lx - tabular->GetWidthOfColumn(cell) + top_x); } void InsetTabular::resetPos(BufferView * bv) const { - if (!locked) - return; - actcol = tabular->column_of_cell(actcell); - - int cell = 0; - actrow = 0; - cursor.y(0); - for (; (cell < actcell) && !tabular->IsLastRow(cell); ++cell) { - if (tabular->IsLastCellInRow(cell)) { - cursor.y(cursor.y() + tabular->GetDescentOfRow(actrow) + - tabular->GetAscentOfRow(actrow + 1) + - tabular->GetAdditionalHeight(cell + 1)); - ++actrow; - } - } - static int const offset = ADD_TO_TABULAR_WIDTH + 2; - int new_x = getCellXPos(actcell); - int old_x = cursor.x(); - new_x += offset; - cursor.x(new_x); +#warning This should be fixed in the right manner (20011128 Jug) + // fast hack to fix infinite repaintings! + if (in_reset_pos) + return; + + int cell = 0; + actcol = tabular->column_of_cell(actcell); + actrow = 0; + cursor_.y(0); + for (; (cell < actcell) && !tabular->IsLastRow(cell); ++cell) { + if (tabular->IsLastCellInRow(cell)) { + cursor_.y(cursor_.y() + tabular->GetDescentOfRow(actrow) + + tabular->GetAscentOfRow(actrow + 1) + + tabular->GetAdditionalHeight(actrow + 1)); + ++actrow; + } + } + if (!locked || nodraw()) { + if (the_locking_inset) + inset_y = cursor_.y(); + return; + } + // we need this only from here on!!! + in_reset_pos = true; + static int const offset = ADD_TO_TABULAR_WIDTH + 2; + int new_x = getCellXPos(actcell); + int old_x = cursor_.x(); + new_x += offset; + cursor_.x(new_x); // cursor.x(getCellXPos(actcell) + offset); - if (scroll() && (tabular->GetWidthOfTabular() < bv->workWidth()-20)) - scroll(bv, 0.0F); - else if (the_locking_inset && - (tabular->GetWidthOfColumn(actcell) > bv->workWidth()-20)) - { - int xx = cursor.x() - offset + bv->text->GetRealCursorX(bv); - if (xx > (bv->workWidth()-20)) - scroll(bv, -(xx - bv->workWidth() + 60)); - else if (xx < 20) { - if (xx < 0) - xx = -xx + 60; - else - xx = 60; - scroll(bv, xx); - } - } else if (((cursor.x() - offset) > 20) && - ((cursor.x()-offset+tabular->GetWidthOfColumn(actcell)) > - (bv->workWidth()-20))) - { - scroll(bv, -tabular->GetWidthOfColumn(actcell)-20); - UpdateLocal(bv, FULL, false); - } else if ((cursor.x() - offset) < 20) { - scroll(bv, 20 - cursor.x() + offset); - UpdateLocal(bv, FULL, false); - } else if (scroll() && (top_x > 20) && - ((top_x+tabular->GetWidthOfTabular()) > (bv->workWidth()-20))) { - scroll(bv, old_x - cursor.x()); - } - if ((!the_locking_inset || - !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE)) && - (actcell != oldcell)) { - InsetTabular * inset = const_cast(this); - bv->owner()->getDialogs()->updateTabular(inset); - oldcell = actcell; - } + if ((actcol < tabular->columns()-1) && scroll(false) && + (tabular->GetWidthOfTabular() < bv->workWidth()-20)) + { + scroll(bv, 0.0F); + updateLocal(bv, FULL, false); + } else if (the_locking_inset && + (tabular->GetWidthOfColumn(actcell) > bv->workWidth()-20)) + { + int xx = cursor_.x() - offset + bv->text->getRealCursorX(bv); + if (xx > (bv->workWidth()-20)) { + scroll(bv, -(xx - bv->workWidth() + 60)); + updateLocal(bv, FULL, false); + } else if (xx < 20) { + if (xx < 0) + xx = -xx + 60; + else + xx = 60; + scroll(bv, xx); + updateLocal(bv, FULL, false); + } + } else if ((cursor_.x() - offset) > 20 && + (cursor_.x() - offset + tabular->GetWidthOfColumn(actcell)) + > (bv->workWidth() - 20)) { + scroll(bv, -tabular->GetWidthOfColumn(actcell) - 20); + updateLocal(bv, FULL, false); + } else if ((cursor_.x() - offset) < 20) { + scroll(bv, 20 - cursor_.x() + offset); + updateLocal(bv, FULL, false); + } else if (scroll(false) && top_x > 20 && + (top_x + tabular->GetWidthOfTabular()) > (bv->workWidth() - 20)) { + scroll(bv, old_x - cursor_.x()); + updateLocal(bv, FULL, false); + } + if (the_locking_inset) { + inset_x = cursor_.x() - top_x + tabular->GetBeginningOfTextInCell(actcell); + inset_y = cursor_.y(); + } + if ((!the_locking_inset || + !the_locking_inset->getFirstLockingInsetOfType(TABULAR_CODE)) && + actcell != oldcell) { + InsetTabular * inset = const_cast(this); + bv->owner()->getDialogs()->updateTabular(inset); + oldcell = actcell; + } + in_reset_pos = false; } UpdatableInset::RESULT InsetTabular::moveRight(BufferView * bv, bool lock) { - if (lock && !old_locking_inset) { - if (ActivateCellInset(bv)) - return DISPATCHED; - } else { - bool moved = isRightToLeft(bv) ? movePrevCell(bv) : moveNextCell(bv); - if (!moved) - return FINISHED; - if (lock && ActivateCellInset(bv)) - return DISPATCHED; - } - resetPos(bv); - return DISPATCHED_NOUPDATE; + if (lock && !old_locking_inset) { + if (activateCellInset(bv)) + return DISPATCHED; + } else { + bool moved = isRightToLeft(bv) + ? movePrevCell(bv) : moveNextCell(bv); + if (!moved) + return FINISHED_RIGHT; + if (lock && activateCellInset(bv)) + return DISPATCHED; + } + resetPos(bv); + return DISPATCHED_NOUPDATE; } UpdatableInset::RESULT InsetTabular::moveLeft(BufferView * bv, bool lock) { - bool moved = isRightToLeft(bv) ? moveNextCell(bv) : movePrevCell(bv); - if (!moved) - return FINISHED; - if (lock) { // behind the inset - if (ActivateCellInset(bv, 0, 0, 0, true)) - return DISPATCHED; - } - resetPos(bv); - return DISPATCHED_NOUPDATE; + bool moved = isRightToLeft(bv) ? moveNextCell(bv) : movePrevCell(bv); + if (!moved) + return FINISHED; + if (lock) { // behind the inset + if (activateCellInset(bv, 0, 0, 0, true)) + return DISPATCHED; + } + resetPos(bv); + return DISPATCHED_NOUPDATE; } UpdatableInset::RESULT InsetTabular::moveUp(BufferView * bv, bool lock) { - int const ocell = actcell; - actcell = tabular->GetCellAbove(actcell); - if (actcell == ocell) // we moved out of the inset - return FINISHED; - resetPos(bv); - if (lock) { - int x = 0; - int y = 0; - if (old_locking_inset) { - old_locking_inset->GetCursorPos(bv, x, y); - x -= cursor.x() + tabular->GetBeginningOfTextInCell(actcell); + int const ocell = actcell; + actcell = tabular->GetCellAbove(actcell); + if (actcell == ocell) // we moved out of the inset + return FINISHED_UP; + resetPos(bv); + if (lock) { + int x = 0; + int y = 0; + if (old_locking_inset) { + old_locking_inset->getCursorPos(bv, x, y); + x -= cursor_.x() + tabular->GetBeginningOfTextInCell(actcell); + } + if (activateCellInset(bv, x, 0)) + return DISPATCHED; } - if (ActivateCellInset(bv, x, 0)) - return DISPATCHED; - } - return DISPATCHED_NOUPDATE; + return DISPATCHED_NOUPDATE; } UpdatableInset::RESULT InsetTabular::moveDown(BufferView * bv, bool lock) { - int const ocell = actcell; - actcell = tabular->GetCellBelow(actcell); - if (actcell == ocell) // we moved out of the inset - return FINISHED; - resetPos(bv); - if (lock) { - int x = 0; - int y = 0; - if (old_locking_inset) { - old_locking_inset->GetCursorPos(bv, x, y); - x -= cursor.x() + tabular->GetBeginningOfTextInCell(actcell); + int const ocell = actcell; + actcell = tabular->GetCellBelow(actcell); + if (actcell == ocell) // we moved out of the inset + return FINISHED_DOWN; + resetPos(bv); + if (lock) { + int x = 0; + int y = 0; + if (old_locking_inset) { + old_locking_inset->getCursorPos(bv, x, y); + x -= cursor_.x() + tabular->GetBeginningOfTextInCell(actcell); + } + if (activateCellInset(bv, x, 0)) + return DISPATCHED; } - if (ActivateCellInset(bv, x, 0)) - return DISPATCHED; - } - return DISPATCHED_NOUPDATE; + return DISPATCHED_NOUPDATE; } bool InsetTabular::moveNextCell(BufferView * bv, bool lock) { - if (isRightToLeft(bv)) { - if (tabular->IsFirstCellInRow(actcell)) { - int row = tabular->row_of_cell(actcell); - if (row == tabular->rows() - 1) - return false; - actcell = tabular->GetLastCellInRow(row); - actcell = tabular->GetCellBelow(actcell); + if (isRightToLeft(bv)) { + if (tabular->IsFirstCellInRow(actcell)) { + int row = tabular->row_of_cell(actcell); + if (row == tabular->rows() - 1) + return false; + actcell = tabular->GetLastCellInRow(row); + actcell = tabular->GetCellBelow(actcell); + } else { + if (!actcell) + return false; + --actcell; + } } else { - if (!actcell) - return false; - --actcell; + if (tabular->IsLastCell(actcell)) + return false; + ++actcell; } - } else { - if (tabular->IsLastCell(actcell)) - return false; - ++actcell; - } - if (lock) { - bool rtl = tabular->GetCellInset(actcell)->par-> - isRightToLeftPar(bv->buffer()->params); - ActivateCellInset(bv, 0, 0, 0, !rtl); - } - resetPos(bv); - return true; + if (lock) { + bool rtl = tabular->GetCellInset(actcell)->paragraph()-> + isRightToLeftPar(bv->buffer()->params); + activateCellInset(bv, 0, 0, 0, !rtl); + } + resetPos(bv); + return true; } bool InsetTabular::movePrevCell(BufferView * bv, bool lock) { - if (isRightToLeft(bv)) { - if (tabular->IsLastCellInRow(actcell)) { - int row = tabular->row_of_cell(actcell); - if (row == 0) - return false; - actcell = tabular->GetFirstCellInRow(row); - actcell = tabular->GetCellAbove(actcell); + if (isRightToLeft(bv)) { + if (tabular->IsLastCellInRow(actcell)) { + int row = tabular->row_of_cell(actcell); + if (row == 0) + return false; + actcell = tabular->GetFirstCellInRow(row); + actcell = tabular->GetCellAbove(actcell); + } else { + if (tabular->IsLastCell(actcell)) + return false; + ++actcell; + } } else { - if (tabular->IsLastCell(actcell)) - return false; - ++actcell; + if (!actcell) // first cell + return false; + --actcell; } - } else { - if (!actcell) // first cell - return false; - --actcell; - } - if (lock) { - bool rtl = tabular->GetCellInset(actcell)->par-> - isRightToLeftPar(bv->buffer()->params); - ActivateCellInset(bv, 0, 0, 0, !rtl); - } - resetPos(bv); - return true; + if (lock) { + bool rtl = tabular->GetCellInset(actcell)->paragraph()-> + isRightToLeftPar(bv->buffer()->params); + activateCellInset(bv, 0, 0, 0, !rtl); + } + resetPos(bv); + return true; } -bool InsetTabular::Delete() +bool InsetTabular::deletable() const { - return true; + return true; } -void InsetTabular::SetFont(BufferView * bv, LyXFont const & font, bool tall) +void InsetTabular::setFont(BufferView * bv, LyXFont const & font, bool tall, + bool selectall) { - if (the_locking_inset) - the_locking_inset->SetFont(bv, font, tall); + if (selectall) { + setSelection(0, tabular->GetNumberOfCells() - 1); + } + if (hasSelection()) { + setUndo(bv, Undo::EDIT, + bv->text->cursor.par(), + bv->text->cursor.par()->next()); + bool frozen = undo_frozen; + if (!frozen) + freezeUndo(); + // apply the fontchange on the whole selection + int sel_row_start; + int sel_row_end; + int sel_col_start; + int sel_col_end; + getSelection(sel_row_start, sel_row_end, sel_col_start, sel_col_end); + for(int i = sel_row_start; i <= sel_row_end; ++i) { + for(int j = sel_col_start; j <= sel_col_end; ++j) { + tabular->GetCellInset(i, j)->setFont(bv, font, tall, true); + } + } + if (!frozen) + unFreezeUndo(); + updateLocal(bv, INIT, true); + } + if (the_locking_inset) + the_locking_inset->setFont(bv, font, tall); } -bool InsetTabular::TabularFeatures(BufferView * bv, string const & what) +bool InsetTabular::tabularFeatures(BufferView * bv, string const & what) { - LyXTabular::Feature action = LyXTabular::LAST_ACTION; + LyXTabular::Feature action = LyXTabular::LAST_ACTION; + + int i = 0; + for (; tabularFeature[i].action != LyXTabular::LAST_ACTION; ++i) { + string const tmp = tabularFeature[i].feature; + + if (tmp == what.substr(0, tmp.length())) { + //if (!compare(tabularFeatures[i].feature.c_str(), what.c_str(), + //tabularFeatures[i].feature.length())) { + action = tabularFeature[i].action; + break; + } + } + if (action == LyXTabular::LAST_ACTION) + return false; + + string const val = + frontStrip(what.substr(tabularFeature[i].feature.length())); + tabularFeatures(bv, action, val); + return true; +} - int i = 0; - for (; tabularFeatures[i].action != LyXTabular::LAST_ACTION; ++i) { - string const tmp = tabularFeatures[i].feature; - - if (tmp == what.substr(0, tmp.length())) { - //if (!compare(tabularFeatures[i].feature.c_str(), what.c_str(), - //tabularFeatures[i].feature.length())) { - action = tabularFeatures[i].action; - break; +static void checkLongtableSpecial(LyXTabular::ltType & ltt, + string const & special, bool & flag) +{ + if (special == "dl_above") { + ltt.topDL = flag; + ltt.set = false; + } else if (special == "dl_below") { + ltt.bottomDL = flag; + ltt.set = false; + } else if (special == "empty") { + ltt.empty = flag; + ltt.set = false; + } else if (flag) { + ltt.empty = false; + ltt.set = true; } - } - if (action == LyXTabular::LAST_ACTION) - return false; +} - string const val = - frontStrip(what.substr(tabularFeatures[i].feature.length())); - TabularFeatures(bv, action, val); - return true; -} - - -void InsetTabular::TabularFeatures(BufferView * bv, - LyXTabular::Feature feature, - string const & value) -{ - int i; - int j; - int sel_col_start; - int sel_col_end; - int sel_row_start; - int sel_row_end; - int setLines = 0; - LyXAlignment setAlign = LYX_ALIGN_LEFT; - LyXTabular::VAlignment setVAlign = LyXTabular::LYX_VALIGN_TOP; - int lineSet; - bool what; - - switch (feature) { - case LyXTabular::M_ALIGN_LEFT: - case LyXTabular::ALIGN_LEFT: - setAlign=LYX_ALIGN_LEFT; - break; - case LyXTabular::M_ALIGN_RIGHT: - case LyXTabular::ALIGN_RIGHT: - setAlign=LYX_ALIGN_RIGHT; - break; - case LyXTabular::M_ALIGN_CENTER: - case LyXTabular::ALIGN_CENTER: - setAlign=LYX_ALIGN_CENTER; - break; - case LyXTabular::M_VALIGN_TOP: - case LyXTabular::VALIGN_TOP: - setVAlign=LyXTabular::LYX_VALIGN_TOP; - break; - case LyXTabular::M_VALIGN_BOTTOM: - case LyXTabular::VALIGN_BOTTOM: - setVAlign=LyXTabular::LYX_VALIGN_BOTTOM; - break; - case LyXTabular::M_VALIGN_CENTER: - case LyXTabular::VALIGN_CENTER: - setVAlign=LyXTabular::LYX_VALIGN_CENTER; - break; - default: - break; - } - if (hasSelection()) { - sel_col_start = tabular->column_of_cell(sel_cell_start); - sel_col_end = tabular->column_of_cell(sel_cell_end); - if (sel_col_start > sel_col_end) { - sel_col_end = sel_col_start; - sel_col_start = tabular->column_of_cell(sel_cell_end); + +void InsetTabular::tabularFeatures(BufferView * bv, + LyXTabular::Feature feature, + string const & value) +{ + int sel_col_start; + int sel_col_end; + int sel_row_start; + int sel_row_end; + bool setLines = false; + LyXAlignment setAlign = LYX_ALIGN_LEFT; + LyXTabular::VAlignment setVAlign = LyXTabular::LYX_VALIGN_TOP; + + switch (feature) { + case LyXTabular::M_ALIGN_LEFT: + case LyXTabular::ALIGN_LEFT: + setAlign = LYX_ALIGN_LEFT; + break; + case LyXTabular::M_ALIGN_RIGHT: + case LyXTabular::ALIGN_RIGHT: + setAlign = LYX_ALIGN_RIGHT; + break; + case LyXTabular::M_ALIGN_CENTER: + case LyXTabular::ALIGN_CENTER: + setAlign = LYX_ALIGN_CENTER; + break; + case LyXTabular::M_VALIGN_TOP: + case LyXTabular::VALIGN_TOP: + setVAlign = LyXTabular::LYX_VALIGN_TOP; + break; + case LyXTabular::M_VALIGN_BOTTOM: + case LyXTabular::VALIGN_BOTTOM: + setVAlign = LyXTabular::LYX_VALIGN_BOTTOM; + break; + case LyXTabular::M_VALIGN_CENTER: + case LyXTabular::VALIGN_CENTER: + setVAlign = LyXTabular::LYX_VALIGN_CENTER; + break; + default: + break; + } + if (hasSelection()) { + getSelection(sel_row_start, sel_row_end, sel_col_start, sel_col_end); } else { - sel_col_end = tabular->right_column_of_cell(sel_cell_end); + sel_col_start = sel_col_end = tabular->column_of_cell(actcell); + sel_row_start = sel_row_end = tabular->row_of_cell(actcell); } + setUndo(bv, Undo::FINISH, + bv->text->cursor.par(), + bv->text->cursor.par()->next()); + + int row = tabular->row_of_cell(actcell); + int column = tabular->column_of_cell(actcell); + bool flag = true; + LyXTabular::ltType ltt; - sel_row_start = tabular->row_of_cell(sel_cell_start); - sel_row_end = tabular->row_of_cell(sel_cell_end); - if (sel_row_start > sel_row_end) { - //int tmp = sel_row_start; - //sel_row_start = sel_row_end; - //sel_row_end = tmp; - swap(sel_row_start, sel_row_end); - } - } else { - sel_col_start = sel_col_end = tabular->column_of_cell(actcell); - sel_row_start = sel_row_end = tabular->row_of_cell(actcell); - } - bv->text->SetUndo(bv->buffer(), Undo::FINISH, -#ifndef NEW_INSETS - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_, - bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_ -#else - bv->text->cursor.par()->previous(), - bv->text->cursor.par()->next() -#endif - ); - - int row = tabular->row_of_cell(actcell); - int column = tabular->column_of_cell(actcell); - bool flag = true; - - switch (feature) { - case LyXTabular::SET_PWIDTH: - { - bool const update = (tabular->GetColumnPWidth(actcell) != value); - tabular->SetColumnPWidth(actcell,value); - if (update) { - for (int i=0; i < tabular->rows(); ++i) { - tabular->GetCellInset(tabular->GetCellNumber(i, column))-> - resizeLyXText(bv); - } - UpdateLocal(bv, INIT, true); - } - } - break; - case LyXTabular::SET_MPWIDTH: - { - bool const update = (tabular->GetPWidth(actcell) != value); - tabular->SetMColumnPWidth(actcell,value); - if (update) { - for (int i=0; i < tabular->rows(); ++i) { - tabular->GetCellInset(tabular->GetCellNumber(i, column))-> - resizeLyXText(bv); - } - UpdateLocal(bv, INIT, true); - } - } - break; - case LyXTabular::SET_SPECIAL_COLUMN: - case LyXTabular::SET_SPECIAL_MULTI: - tabular->SetAlignSpecial(actcell,value,feature); - break; - case LyXTabular::APPEND_ROW: - // append the row into the tabular - UnlockInsetInInset(bv, the_locking_inset); - tabular->AppendRow(actcell); - UpdateLocal(bv, INIT, true); - break; - case LyXTabular::APPEND_COLUMN: - // append the column into the tabular - UnlockInsetInInset(bv, the_locking_inset); - tabular->AppendColumn(actcell); - actcell = tabular->GetCellNumber(row, column); - UpdateLocal(bv, INIT, true); - break; - case LyXTabular::DELETE_ROW: - UnlockInsetInInset(bv, the_locking_inset); - tabular->DeleteRow(tabular->row_of_cell(actcell)); - if ((row+1) > tabular->rows()) - --row; - actcell = tabular->GetCellNumber(row, column); - clearSelection(); - UpdateLocal(bv, INIT, true); - break; - case LyXTabular::DELETE_COLUMN: - UnlockInsetInInset(bv, the_locking_inset); - tabular->DeleteColumn(tabular->column_of_cell(actcell)); - if ((column+1) > tabular->columns()) - --column; - actcell = tabular->GetCellNumber(row, column); - clearSelection(); - UpdateLocal(bv, INIT, true); - break; - case LyXTabular::M_TOGGLE_LINE_TOP: - flag = false; - case LyXTabular::TOGGLE_LINE_TOP: - lineSet = !tabular->TopLine(actcell, flag); - for (i=sel_row_start; i<=sel_row_end; ++i) - for (j=sel_col_start; j<=sel_col_end; ++j) - tabular->SetTopLine(tabular->GetCellNumber(i,j),lineSet, flag); - UpdateLocal(bv, INIT, true); - break; - - case LyXTabular::M_TOGGLE_LINE_BOTTOM: - flag = false; - case LyXTabular::TOGGLE_LINE_BOTTOM: - lineSet = !tabular->BottomLine(actcell, flag); - for (i=sel_row_start; i<=sel_row_end; ++i) - for (j=sel_col_start; j<=sel_col_end; ++j) - tabular->SetBottomLine(tabular->GetCellNumber(i,j),lineSet, - flag); - UpdateLocal(bv, INIT, true); - break; + switch (feature) { + case LyXTabular::SET_PWIDTH: + { + LyXLength const vallen(value); + LyXLength const & tmplen = tabular->GetColumnPWidth(actcell); - case LyXTabular::M_TOGGLE_LINE_LEFT: - flag = false; - case LyXTabular::TOGGLE_LINE_LEFT: - lineSet = !tabular->LeftLine(actcell, flag); - for (i=sel_row_start; i<=sel_row_end; ++i) - for (j=sel_col_start; j<=sel_col_end; ++j) - tabular->SetLeftLine(tabular->GetCellNumber(i,j),lineSet, - flag); - UpdateLocal(bv, INIT, true); - break; - - case LyXTabular::M_TOGGLE_LINE_RIGHT: - flag = false; - case LyXTabular::TOGGLE_LINE_RIGHT: - lineSet = !tabular->RightLine(actcell, flag); - for (i=sel_row_start; i<=sel_row_end; ++i) - for (j=sel_col_start; j<=sel_col_end; ++j) - tabular->SetRightLine(tabular->GetCellNumber(i,j),lineSet, - flag); - UpdateLocal(bv, INIT, true); - break; - case LyXTabular::M_ALIGN_LEFT: - case LyXTabular::M_ALIGN_RIGHT: - case LyXTabular::M_ALIGN_CENTER: - flag = false; - case LyXTabular::ALIGN_LEFT: - case LyXTabular::ALIGN_RIGHT: - case LyXTabular::ALIGN_CENTER: - for (i = sel_row_start; i <= sel_row_end; ++i) - for (j = sel_col_start; j <= sel_col_end; ++j) - tabular->SetAlignment(tabular->GetCellNumber(i, j), setAlign, - flag); - UpdateLocal(bv, INIT, true); - break; - case LyXTabular::M_VALIGN_TOP: - case LyXTabular::M_VALIGN_BOTTOM: - case LyXTabular::M_VALIGN_CENTER: - flag = false; - case LyXTabular::VALIGN_TOP: - case LyXTabular::VALIGN_BOTTOM: - case LyXTabular::VALIGN_CENTER: - for (i = sel_row_start; i <= sel_row_end; ++i) - for (j = sel_col_start; j <= sel_col_end; ++j) - tabular->SetVAlignment(tabular->GetCellNumber(i, j), - setVAlign, flag); - UpdateLocal(bv, INIT, true); - break; - case LyXTabular::MULTICOLUMN: - { - if (sel_row_start != sel_row_end) { - WriteAlert(_("Impossible Operation!"), - _("Multicolumns can only be horizontally."), - _("Sorry.")); - return; - } - // just multicol for one Single Cell - if (!hasSelection()) { - // check wether we are completly in a multicol - if (tabular->IsMultiColumn(actcell)) { - tabular->UnsetMultiColumn(actcell); - UpdateLocal(bv, INIT, true); - } else { - tabular->SetMultiColumn(actcell, 1); - UpdateLocal(bv, CELL, true); - } - return; - } - // we have a selection so this means we just add all this - // cells to form a multicolumn cell - int s_start; - int s_end; - - if (sel_cell_start > sel_cell_end) { - s_start = sel_cell_end; - s_end = sel_cell_start; - } else { - s_start = sel_cell_start; - s_end = sel_cell_end; + bool const update = (tmplen != vallen); + tabular->SetColumnPWidth(actcell, vallen); + if (update) { + int cell; + for (int i = 0; i < tabular->rows(); ++i) { + cell = tabular->GetCellNumber(i,column); + tabular->GetCellInset(cell)->resizeLyXText(bv); + } + updateLocal(bv, INIT, true); + } } - tabular->SetMultiColumn(s_start, s_end - s_start + 1); - actcell = s_start; - sel_cell_end = sel_cell_start; - UpdateLocal(bv, INIT, true); - break; - } - case LyXTabular::SET_ALL_LINES: - setLines = 1; - case LyXTabular::UNSET_ALL_LINES: - for (i=sel_row_start; i<=sel_row_end; ++i) - for (j=sel_col_start; j<=sel_col_end; ++j) - tabular->SetAllLines(tabular->GetCellNumber(i,j), setLines); - UpdateLocal(bv, INIT, true); - break; - case LyXTabular::SET_LONGTABULAR: - tabular->SetLongTabular(true); - UpdateLocal(bv, INIT, true); // because this toggles displayed - break; - case LyXTabular::UNSET_LONGTABULAR: - tabular->SetLongTabular(false); - UpdateLocal(bv, INIT, true); // because this toggles displayed - break; - case LyXTabular::SET_ROTATE_TABULAR: - tabular->SetRotateTabular(true); - break; - case LyXTabular::UNSET_ROTATE_TABULAR: - tabular->SetRotateTabular(false); - break; - case LyXTabular::SET_ROTATE_CELL: - for (i=sel_row_start; i<=sel_row_end; ++i) - for (j=sel_col_start; j<=sel_col_end; ++j) - tabular->SetRotateCell(tabular->GetCellNumber(i,j),true); - break; - case LyXTabular::UNSET_ROTATE_CELL: - for (i = sel_row_start; i <= sel_row_end; ++i) - for (j = sel_col_start; j <= sel_col_end; ++j) - tabular->SetRotateCell(tabular->GetCellNumber(i, j), false); - break; - case LyXTabular::SET_USEBOX: - { - LyXTabular::BoxType val = LyXTabular::BoxType(strToInt(value)); - if (val == tabular->GetUsebox(actcell)) - val = LyXTabular::BOX_NONE; - for (i = sel_row_start; i <= sel_row_end; ++i) - for (j = sel_col_start; j <= sel_col_end; ++j) - tabular->SetUsebox(tabular->GetCellNumber(i, j), val); - break; - } - case LyXTabular::SET_LTFIRSTHEAD: - tabular->SetLTHead(actcell, true); - break; - case LyXTabular::SET_LTHEAD: - tabular->SetLTHead(actcell, false); break; - case LyXTabular::SET_LTFOOT: - tabular->SetLTFoot(actcell, false); - break; - case LyXTabular::SET_LTLASTFOOT: - tabular->SetLTFoot(actcell, true); - break; - case LyXTabular::SET_LTNEWPAGE: - what = !tabular->GetLTNewPage(actcell); - tabular->SetLTNewPage(actcell, what); - break; - // dummy stuff just to avoid warnings - case LyXTabular::LAST_ACTION: + 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) { + for (int i = 0; i < tabular->rows(); ++i) { + tabular->GetCellInset(tabular->GetCellNumber(i, column))-> + resizeLyXText(bv); + } + updateLocal(bv, INIT, true); + } + } break; - } + case LyXTabular::SET_SPECIAL_COLUMN: + case LyXTabular::SET_SPECIAL_MULTI: + tabular->SetAlignSpecial(actcell,value,feature); + updateLocal(bv, FULL, true); + break; + case LyXTabular::APPEND_ROW: + // append the row into the tabular + unlockInsetInInset(bv, the_locking_inset); + tabular->AppendRow(actcell); + updateLocal(bv, INIT, true); + break; + case LyXTabular::APPEND_COLUMN: + // append the column into the tabular + unlockInsetInInset(bv, the_locking_inset); + tabular->AppendColumn(actcell); + actcell = tabular->GetCellNumber(row, column); + updateLocal(bv, INIT, true); + break; + case LyXTabular::DELETE_ROW: + unlockInsetInInset(bv, the_locking_inset); + for(int i = sel_row_start; i <= sel_row_end; ++i) { + tabular->DeleteRow(sel_row_start); + } + if (sel_row_start >= tabular->rows()) + --sel_row_start; + actcell = tabular->GetCellNumber(sel_row_start, column); + clearSelection(); + updateLocal(bv, INIT, true); + break; + case LyXTabular::DELETE_COLUMN: + unlockInsetInInset(bv, the_locking_inset); + for(int i = sel_col_start; i <= sel_col_end; ++i) { + tabular->DeleteColumn(sel_col_start); + } + if (sel_col_start >= tabular->columns()) + --sel_col_start; + actcell = tabular->GetCellNumber(row, sel_col_start); + clearSelection(); + updateLocal(bv, INIT, true); + break; + case LyXTabular::M_TOGGLE_LINE_TOP: + flag = false; + case LyXTabular::TOGGLE_LINE_TOP: + { + bool lineSet = !tabular->TopLine(actcell, flag); + for (int i = sel_row_start; i <= sel_row_end; ++i) + for (int j = sel_col_start; j <= sel_col_end; ++j) + tabular->SetTopLine( + tabular->GetCellNumber(i, j), + lineSet, flag); + updateLocal(bv, INIT, true); + break; + } + + case LyXTabular::M_TOGGLE_LINE_BOTTOM: + flag = false; + case LyXTabular::TOGGLE_LINE_BOTTOM: + { + bool lineSet = !tabular->BottomLine(actcell, flag); + for (int i = sel_row_start; i <= sel_row_end; ++i) + for (int j = sel_col_start; j <= sel_col_end; ++j) + tabular->SetBottomLine( + tabular->GetCellNumber(i, j), + lineSet, + flag); + updateLocal(bv, INIT, true); + break; + } + + case LyXTabular::M_TOGGLE_LINE_LEFT: + flag = false; + case LyXTabular::TOGGLE_LINE_LEFT: + { + bool lineSet = !tabular->LeftLine(actcell, flag); + for (int i = sel_row_start; i <= sel_row_end; ++i) + for (int j = sel_col_start; j <= sel_col_end; ++j) + tabular->SetLeftLine( + tabular->GetCellNumber(i,j), + lineSet, + flag); + updateLocal(bv, INIT, true); + break; + } + + case LyXTabular::M_TOGGLE_LINE_RIGHT: + flag = false; + case LyXTabular::TOGGLE_LINE_RIGHT: + { + bool lineSet = !tabular->RightLine(actcell, flag); + for (int i = sel_row_start; i <= sel_row_end; ++i) + for (int j = sel_col_start; j <= sel_col_end; ++j) + tabular->SetRightLine( + tabular->GetCellNumber(i,j), + lineSet, + flag); + updateLocal(bv, INIT, true); + break; + } + + case LyXTabular::M_ALIGN_LEFT: + case LyXTabular::M_ALIGN_RIGHT: + case LyXTabular::M_ALIGN_CENTER: + flag = false; + case LyXTabular::ALIGN_LEFT: + case LyXTabular::ALIGN_RIGHT: + case LyXTabular::ALIGN_CENTER: + for (int i = sel_row_start; i <= sel_row_end; ++i) + for (int j = sel_col_start; j <= sel_col_end; ++j) + tabular->SetAlignment( + tabular->GetCellNumber(i, j), + setAlign, + flag); + updateLocal(bv, INIT, true); + break; + case LyXTabular::M_VALIGN_TOP: + case LyXTabular::M_VALIGN_BOTTOM: + case LyXTabular::M_VALIGN_CENTER: + flag = false; + case LyXTabular::VALIGN_TOP: + case LyXTabular::VALIGN_BOTTOM: + case LyXTabular::VALIGN_CENTER: + for (int i = sel_row_start; i <= sel_row_end; ++i) + for (int j = sel_col_start; j <= sel_col_end; ++j) + tabular->SetVAlignment( + tabular->GetCellNumber(i, j), + setVAlign, flag); + updateLocal(bv, INIT, true); + break; + case LyXTabular::MULTICOLUMN: + { + if (sel_row_start != sel_row_end) { + Alert::alert(_("Impossible Operation!"), + _("Multicolumns can only be horizontally."), + _("Sorry.")); + return; + } + // just multicol for one Single Cell + if (!hasSelection()) { + // check wether we are completly in a multicol + if (tabular->IsMultiColumn(actcell)) { + tabular->UnsetMultiColumn(actcell); + updateLocal(bv, INIT, true); + } else { + tabular->SetMultiColumn(actcell, 1); + updateLocal(bv, CELL, true); + } + return; + } + // we have a selection so this means we just add all this + // cells to form a multicolumn cell + int s_start; + int s_end; + + if (sel_cell_start > sel_cell_end) { + s_start = sel_cell_end; + s_end = sel_cell_start; + } else { + s_start = sel_cell_start; + s_end = sel_cell_end; + } + tabular->SetMultiColumn(s_start, s_end - s_start + 1); + actcell = s_start; + clearSelection(); + updateLocal(bv, INIT, true); + break; + } + case LyXTabular::SET_ALL_LINES: + setLines = true; + case LyXTabular::UNSET_ALL_LINES: + for (int i = sel_row_start; i <= sel_row_end; ++i) + for (int j = sel_col_start; j <= sel_col_end; ++j) + tabular->SetAllLines( + tabular->GetCellNumber(i,j), setLines); + updateLocal(bv, INIT, true); + break; + case LyXTabular::SET_LONGTABULAR: + tabular->SetLongTabular(true); + updateLocal(bv, INIT, true); // because this toggles displayed + break; + case LyXTabular::UNSET_LONGTABULAR: + tabular->SetLongTabular(false); + updateLocal(bv, INIT, true); // because this toggles displayed + break; + case LyXTabular::SET_ROTATE_TABULAR: + tabular->SetRotateTabular(true); + break; + case LyXTabular::UNSET_ROTATE_TABULAR: + tabular->SetRotateTabular(false); + break; + case LyXTabular::SET_ROTATE_CELL: + for (int i = sel_row_start; i <= sel_row_end; ++i) + for (int j = sel_col_start; j<=sel_col_end; ++j) + tabular->SetRotateCell( + tabular->GetCellNumber(i, j), + true); + break; + case LyXTabular::UNSET_ROTATE_CELL: + for (int i = sel_row_start; i <= sel_row_end; ++i) + for (int j = sel_col_start; j <= sel_col_end; ++j) + tabular->SetRotateCell( + tabular->GetCellNumber(i, j), false); + break; + case LyXTabular::SET_USEBOX: + { + LyXTabular::BoxType val = LyXTabular::BoxType(strToInt(value)); + if (val == tabular->GetUsebox(actcell)) + val = LyXTabular::BOX_NONE; + for (int i = sel_row_start; i <= sel_row_end; ++i) + for (int j = sel_col_start; j <= sel_col_end; ++j) + tabular->SetUsebox( + tabular->GetCellNumber(i, j), val); + break; + } + case LyXTabular::UNSET_LTFIRSTHEAD: + flag = false; + case LyXTabular::SET_LTFIRSTHEAD: + (void)tabular->GetRowOfLTFirstHead(row, ltt); + checkLongtableSpecial(ltt, value, flag); + tabular->SetLTHead(row, flag, ltt, true); + break; + case LyXTabular::UNSET_LTHEAD: + flag = false; + case LyXTabular::SET_LTHEAD: + (void)tabular->GetRowOfLTHead(row, ltt); + checkLongtableSpecial(ltt, value, flag); + tabular->SetLTHead(row, flag, ltt, false); + break; + case LyXTabular::UNSET_LTFOOT: + flag = false; + case LyXTabular::SET_LTFOOT: + (void)tabular->GetRowOfLTFoot(row, ltt); + checkLongtableSpecial(ltt, value, flag); + tabular->SetLTFoot(row, flag, ltt, false); + break; + case LyXTabular::UNSET_LTLASTFOOT: + flag = false; + case LyXTabular::SET_LTLASTFOOT: + (void)tabular->GetRowOfLTLastFoot(row, ltt); + checkLongtableSpecial(ltt, value, flag); + tabular->SetLTFoot(row, flag, ltt, true); + break; + case LyXTabular::SET_LTNEWPAGE: + { + bool what = !tabular->GetLTNewPage(row); + tabular->SetLTNewPage(row, what); + break; + } + // dummy stuff just to avoid warnings + case LyXTabular::LAST_ACTION: + break; + } } -bool InsetTabular::ActivateCellInset(BufferView * bv, int x, int y, int button, +bool InsetTabular::activateCellInset(BufferView * bv, int x, int y, int button, bool behind) { - UpdatableInset * inset = - static_cast(tabular->GetCellInset(actcell)); - LyXFont font(LyXFont::ALL_SANE); - if (behind) { - x = inset->x() + inset->width(bv, font); - y = inset->descent(bv, font); - } - //inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell); - //inset_y = cursor.y(); - inset->Edit(bv, x, y, button); - if (!the_locking_inset) - return false; - UpdateLocal(bv, CELL, false); - return (the_locking_inset != 0); + UpdatableInset * inset = + static_cast(tabular->GetCellInset(actcell)); + LyXFont font(LyXFont::ALL_SANE); + if (behind) { + x = inset->x() + inset->width(bv, font); + y = inset->descent(bv, font); + } + //inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell); + //inset_y = cursor.y(); + inset->edit(bv, x, y, button); + if (!the_locking_inset) + return false; + updateLocal(bv, CELL, false); + return (the_locking_inset != 0); } -bool InsetTabular::ActivateCellInsetAbs(BufferView * bv, int x, int y, +bool InsetTabular::activateCellInsetAbs(BufferView * bv, int x, int y, int button) { - inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell); - inset_y = cursor.y(); - return ActivateCellInset(bv, x - inset_x, y - inset_y, button); + inset_x = cursor_.x() + - top_x + tabular->GetBeginningOfTextInCell(actcell); + inset_y = cursor_.y(); + return activateCellInset(bv, x - inset_x, y - inset_y, button); } -bool InsetTabular::InsetHit(BufferView *, int x, int) const +bool InsetTabular::insetHit(BufferView *, int x, int) const { - return x + top_x > cursor.x() + tabular->GetBeginningOfTextInCell(actcell); + return (x + top_x) + > (cursor_.x() + tabular->GetBeginningOfTextInCell(actcell)); } // This returns paperWidth() if the cell-width is unlimited or the width // in pixels if we have a pwidth for this cell. -int InsetTabular::GetMaxWidthOfCell(Painter &, int cell) const +int InsetTabular::getMaxWidthOfCell(BufferView * bv, int cell) const { - string const s = tabular->GetPWidth(cell); + LyXLength const len = tabular->GetPWidth(cell); + + if (len.zero()) + return -1; + return len.inPixels(latexTextWidth(bv), bv->text->defaultHeight()); +} + - if (s.empty()) - return -1; - return VSpace(s).inPixels(0, 0); +int InsetTabular::getMaxWidth(BufferView * bv, + UpdatableInset const * inset) const +{ + int cell = tabular->GetCellFromInset(inset, actcell); + + if (cell == -1) { + lyxerr << "Own inset not found, shouldn't really happen!" + << endl; + return -1; + } + + int w = getMaxWidthOfCell(bv, cell); + if (w > 0) { + // because the inset then subtracts it's top_x and owner->x() + w += (inset->x() - top_x); + } + + return w; } -int InsetTabular::getMaxWidth(Painter & pain, - UpdatableInset const * inset) const +void InsetTabular::deleteLyXText(BufferView * bv, bool recursive) const { - int const n = tabular->GetNumberOfCells(); - int cell = 0; - for (; cell < n; ++cell) { - if (tabular->GetCellInset(cell) == inset) - break; - } - if (cell >= n) - return -1; - int w = GetMaxWidthOfCell(pain, cell); - if (w > 0) - // because the inset then subtracts it's top_x and owner->x() - w += (inset->x() - top_x); - return w; + resizeLyXText(bv, recursive); } -void InsetTabular::resizeLyXText(BufferView *) const +void InsetTabular::resizeLyXText(BufferView * bv, bool force) const { - need_update = FULL; + if (force) { + for(int i = 0; i < tabular->rows(); ++i) { + for(int j = 0; j < tabular->columns(); ++j) { + tabular->GetCellInset(i, j)->resizeLyXText(bv, true); + } + } + } + need_update = FULL; } -LyXText * InsetTabular::getLyXText(BufferView const * bv, bool const recursive) const +LyXText * InsetTabular::getLyXText(BufferView const * bv, + bool const recursive) const { - if (the_locking_inset) - return the_locking_inset->getLyXText(bv, recursive); - return Inset::getLyXText(bv, recursive); + if (the_locking_inset) + return the_locking_inset->getLyXText(bv, recursive); +#if 0 + // if we're locked lock the actual insettext and return it's LyXText!!! + if (locked) { + UpdatableInset * inset = + static_cast(tabular->GetCellInset(actcell)); + inset->edit(const_cast(bv), 0, 0, 0); + return the_locking_inset->getLyXText(bv, recursive); + } +#endif + return Inset::getLyXText(bv, recursive); } -void InsetTabular::OpenLayoutDialog(BufferView * bv) const +bool InsetTabular::showInsetDialog(BufferView * bv) const { - if (the_locking_inset) { - InsetTabular * i = static_cast - (the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE)); - if (i) { - i->OpenLayoutDialog(bv); - return; + if (!the_locking_inset || !the_locking_inset->showInsetDialog(bv)) + bv->owner()->getDialogs() + ->showTabular(const_cast(this)); + return true; +} + + +void InsetTabular::openLayoutDialog(BufferView * bv) const +{ + if (the_locking_inset) { + InsetTabular * i = static_cast + (the_locking_inset->getFirstLockingInsetOfType(TABULAR_CODE)); + if (i) { + i->openLayoutDialog(bv); + return; + } } - } - bv->owner()->getDialogs()->showTabular(const_cast(this)); + bv->owner()->getDialogs()->showTabular( + const_cast(this)); } + // -// functions returns: -// 0 ... disabled -// 1 ... enabled -// 2 ... toggled on -// 3 ... toggled off +// function returns an object as defined in func_status.h: +// states OK, Unknown, Disabled, On, Off. // -LyXFunc::func_status InsetTabular::getStatus(string const & what) const -{ - int action = LyXTabular::LAST_ACTION; - LyXFunc::func_status status = LyXFunc::OK; - - int i = 0; - for (; tabularFeatures[i].action != LyXTabular::LAST_ACTION; ++i) { - string const tmp = tabularFeatures[i].feature; - if (tmp == what.substr(0, tmp.length())) { - //if (!compare(tabularFeatures[i].feature.c_str(), what.c_str(), - // tabularFeatures[i].feature.length())) { - action = tabularFeatures[i].action; - break; - } - } - if (action == LyXTabular::LAST_ACTION) - return LyXFunc::Unknown; - - string const argument = frontStrip(what.substr(tabularFeatures[i].feature.length())); - - int sel_row_start; - int sel_row_end; - int dummy; - bool flag = true; - - if (hasSelection()) { - sel_row_start = tabular->row_of_cell(sel_cell_start); - sel_row_end = tabular->row_of_cell(sel_cell_end); - if (sel_row_start > sel_row_end) { - //int tmp = sel_row_start; - //sel_row_start = sel_row_end; - //sel_row_end = tmp; - swap(sel_row_start, sel_row_end); - } - } else { - sel_row_start = sel_row_end = tabular->row_of_cell(actcell); - } - - switch (action) { - case LyXTabular::SET_PWIDTH: - case LyXTabular::SET_MPWIDTH: - case LyXTabular::SET_SPECIAL_COLUMN: - case LyXTabular::SET_SPECIAL_MULTI: - status |= LyXFunc::Disabled; - return status; +FuncStatus InsetTabular::getStatus(string const & what) const +{ + int action = LyXTabular::LAST_ACTION; + FuncStatus status; + + int i = 0; + for (; tabularFeature[i].action != LyXTabular::LAST_ACTION; ++i) { + string const tmp = tabularFeature[i].feature; + if (tmp == what.substr(0, tmp.length())) { + //if (!compare(tabularFeatures[i].feature.c_str(), what.c_str(), + // tabularFeatures[i].feature.length())) { + action = tabularFeature[i].action; + break; + } + } + if (action == LyXTabular::LAST_ACTION) { + status.clear(); + return status.unknown(true); + } + + string const argument = frontStrip(what.substr(tabularFeature[i].feature.length())); + + int sel_row_start; + int sel_row_end; + int dummy; + LyXTabular::ltType dummyltt; + bool flag = true; + + if (hasSelection()) { + getSelection(sel_row_start, sel_row_end, dummy, dummy); + } else { + sel_row_start = sel_row_end = tabular->row_of_cell(actcell); + } - case LyXTabular::APPEND_ROW: - case LyXTabular::APPEND_COLUMN: - case LyXTabular::DELETE_ROW: - case LyXTabular::DELETE_COLUMN: - case LyXTabular::SET_ALL_LINES: - case LyXTabular::UNSET_ALL_LINES: - status |= LyXFunc::OK; + switch (action) { + case LyXTabular::SET_PWIDTH: + case LyXTabular::SET_MPWIDTH: + case LyXTabular::SET_SPECIAL_COLUMN: + case LyXTabular::SET_SPECIAL_MULTI: + return status.disabled(true); + + case LyXTabular::APPEND_ROW: + case LyXTabular::APPEND_COLUMN: + case LyXTabular::DELETE_ROW: + case LyXTabular::DELETE_COLUMN: + case LyXTabular::SET_ALL_LINES: + case LyXTabular::UNSET_ALL_LINES: + return status.clear(); + + case LyXTabular::MULTICOLUMN: + status.setOnOff(tabular->IsMultiColumn(actcell)); + break; + case LyXTabular::M_TOGGLE_LINE_TOP: + flag = false; + case LyXTabular::TOGGLE_LINE_TOP: + status.setOnOff(tabular->TopLine(actcell, flag)); + break; + case LyXTabular::M_TOGGLE_LINE_BOTTOM: + flag = false; + case LyXTabular::TOGGLE_LINE_BOTTOM: + status.setOnOff(tabular->BottomLine(actcell, flag)); + break; + case LyXTabular::M_TOGGLE_LINE_LEFT: + flag = false; + case LyXTabular::TOGGLE_LINE_LEFT: + status.setOnOff(tabular->LeftLine(actcell, flag)); + break; + case LyXTabular::M_TOGGLE_LINE_RIGHT: + flag = false; + case LyXTabular::TOGGLE_LINE_RIGHT: + status.setOnOff(tabular->RightLine(actcell, flag)); + break; + case LyXTabular::M_ALIGN_LEFT: + flag = false; + case LyXTabular::ALIGN_LEFT: + status.setOnOff(tabular->GetAlignment(actcell, flag) == LYX_ALIGN_LEFT); + break; + case LyXTabular::M_ALIGN_RIGHT: + flag = false; + case LyXTabular::ALIGN_RIGHT: + status.setOnOff(tabular->GetAlignment(actcell, flag) == LYX_ALIGN_RIGHT); + break; + case LyXTabular::M_ALIGN_CENTER: + flag = false; + case LyXTabular::ALIGN_CENTER: + status.setOnOff(tabular->GetAlignment(actcell, flag) == LYX_ALIGN_CENTER); + break; + case LyXTabular::M_VALIGN_TOP: + flag = false; + case LyXTabular::VALIGN_TOP: + status.setOnOff(tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_TOP); + break; + case LyXTabular::M_VALIGN_BOTTOM: + flag = false; + case LyXTabular::VALIGN_BOTTOM: + status.setOnOff(tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_BOTTOM); + break; + case LyXTabular::M_VALIGN_CENTER: + flag = false; + case LyXTabular::VALIGN_CENTER: + status.setOnOff(tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_CENTER); + break; + case LyXTabular::SET_LONGTABULAR: + status.setOnOff(tabular->IsLongTabular()); + break; + case LyXTabular::UNSET_LONGTABULAR: + status.setOnOff(!tabular->IsLongTabular()); + break; + case LyXTabular::SET_ROTATE_TABULAR: + status.setOnOff(tabular->GetRotateTabular()); + break; + case LyXTabular::UNSET_ROTATE_TABULAR: + status.setOnOff(!tabular->GetRotateTabular()); + break; + case LyXTabular::SET_ROTATE_CELL: + status.setOnOff(tabular->GetRotateCell(actcell)); + break; + case LyXTabular::UNSET_ROTATE_CELL: + status.setOnOff(!tabular->GetRotateCell(actcell)); + break; + case LyXTabular::SET_USEBOX: + status.setOnOff(strToInt(argument) == tabular->GetUsebox(actcell)); + break; + case LyXTabular::SET_LTFIRSTHEAD: + status.setOnOff(tabular->GetRowOfLTHead(sel_row_start, dummyltt)); + break; + case LyXTabular::SET_LTHEAD: + status.setOnOff(tabular->GetRowOfLTHead(sel_row_start, dummyltt)); + break; + case LyXTabular::SET_LTFOOT: + status.setOnOff(tabular->GetRowOfLTFoot(sel_row_start, dummyltt)); + break; + case LyXTabular::SET_LTLASTFOOT: + status.setOnOff(tabular->GetRowOfLTFoot(sel_row_start, dummyltt)); + break; + case LyXTabular::SET_LTNEWPAGE: + status.setOnOff(tabular->GetLTNewPage(sel_row_start)); + break; + default: + status.clear(); + status.disabled(true); + break; + } return status; +} - case LyXTabular::MULTICOLUMN: - if (tabular->IsMultiColumn(actcell)) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::M_TOGGLE_LINE_TOP: - flag = false; - case LyXTabular::TOGGLE_LINE_TOP: - if (tabular->TopLine(actcell, flag)) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::M_TOGGLE_LINE_BOTTOM: - flag = false; - case LyXTabular::TOGGLE_LINE_BOTTOM: - if (tabular->BottomLine(actcell, flag)) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::M_TOGGLE_LINE_LEFT: - flag = false; - case LyXTabular::TOGGLE_LINE_LEFT: - if (tabular->LeftLine(actcell, flag)) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::M_TOGGLE_LINE_RIGHT: - flag = false; - case LyXTabular::TOGGLE_LINE_RIGHT: - if (tabular->RightLine(actcell, flag)) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::M_ALIGN_LEFT: - flag = false; - case LyXTabular::ALIGN_LEFT: - if (tabular->GetAlignment(actcell, flag) == LYX_ALIGN_LEFT) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::M_ALIGN_RIGHT: - flag = false; - case LyXTabular::ALIGN_RIGHT: - if (tabular->GetAlignment(actcell, flag) == LYX_ALIGN_RIGHT) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::M_ALIGN_CENTER: - flag = false; - case LyXTabular::ALIGN_CENTER: - if (tabular->GetAlignment(actcell, flag) == LYX_ALIGN_CENTER) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::M_VALIGN_TOP: - flag = false; - case LyXTabular::VALIGN_TOP: - if (tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_TOP) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::M_VALIGN_BOTTOM: - flag = false; - case LyXTabular::VALIGN_BOTTOM: - if (tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_BOTTOM) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::M_VALIGN_CENTER: - flag = false; - case LyXTabular::VALIGN_CENTER: - if (tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_CENTER) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::SET_LONGTABULAR: - if (tabular->IsLongTabular()) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::UNSET_LONGTABULAR: - if (!tabular->IsLongTabular()) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::SET_ROTATE_TABULAR: - if (tabular->GetRotateTabular()) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::UNSET_ROTATE_TABULAR: - if (!tabular->GetRotateTabular()) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::SET_ROTATE_CELL: - if (tabular->GetRotateCell(actcell)) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::UNSET_ROTATE_CELL: - if (!tabular->GetRotateCell(actcell)) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::SET_USEBOX: - if (strToInt(argument) == tabular->GetUsebox(actcell)) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::SET_LTFIRSTHEAD: - if (tabular->GetRowOfLTHead(actcell, dummy)) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::SET_LTHEAD: - if (tabular->GetRowOfLTHead(actcell, dummy)) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::SET_LTFOOT: - if (tabular->GetRowOfLTFoot(actcell, dummy)) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::SET_LTLASTFOOT: - if (tabular->GetRowOfLTFoot(actcell, dummy)) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - case LyXTabular::SET_LTNEWPAGE: - if (tabular->GetLTNewPage(actcell)) - status |= LyXFunc::ToggleOn; - else - status |= LyXFunc::ToggleOff; - break; - default: - status = LyXFunc::Disabled; - break; - } - return status; + +vector const InsetTabular::getLabelList() const +{ + return tabular->getLabelList(); } bool InsetTabular::copySelection(BufferView * bv) { - if (!hasSelection()) - return false; - delete paste_tabular; - - int sel_col_start; - int sel_col_end; - int sel_row_start; - int sel_row_end; - - sel_col_start = tabular->column_of_cell(sel_cell_start); - sel_col_end = tabular->column_of_cell(sel_cell_end); - if (sel_col_start > sel_col_end) { - sel_col_start = sel_col_end; - sel_col_end = tabular->right_column_of_cell(sel_cell_start); - } else { - sel_col_end = tabular->right_column_of_cell(sel_cell_end); - } - int columns = sel_col_end - sel_col_start + 1; - - sel_row_start = tabular->row_of_cell(sel_cell_start); - sel_row_end = tabular->row_of_cell(sel_cell_end); - if (sel_row_start > sel_row_end) { - //int tmp tmp = sel_row_start; - //sel_row_start = sel_row_end; - //sel_row_end = tmp; - swap(sel_row_start, sel_row_end); - } - int rows = sel_row_end - sel_row_start + 1; - - paste_tabular = new LyXTabular(this, *tabular); // rows, columns); - int i; - for (i=0; i < sel_row_start; ++i) - paste_tabular->DeleteRow(0); - while(paste_tabular->rows() > rows) - paste_tabular->DeleteRow(rows); - paste_tabular->SetTopLine(0, true, true); - paste_tabular->SetBottomLine(paste_tabular->GetFirstCellInRow(rows-1), - true, true); - for (i=0; i < sel_col_start; ++i) - paste_tabular->DeleteColumn(0); - while(paste_tabular->columns() > columns) - paste_tabular->DeleteColumn(columns); - paste_tabular->SetLeftLine(0, true, true); - paste_tabular->SetRightLine(paste_tabular->GetLastCellInRow(0),true, true); - - ostringstream sstr; - paste_tabular->Ascii(bv->buffer(), sstr); - bv->stuffClipboard(sstr.str().c_str()); - return true; + if (!hasSelection()) + return false; + + int sel_col_start = tabular->column_of_cell(sel_cell_start); + int sel_col_end = tabular->column_of_cell(sel_cell_end); + if (sel_col_start > sel_col_end) { + sel_col_start = sel_col_end; + sel_col_end = tabular->right_column_of_cell(sel_cell_start); + } else { + sel_col_end = tabular->right_column_of_cell(sel_cell_end); + } + int const columns = sel_col_end - sel_col_start + 1; + + int sel_row_start = tabular->row_of_cell(sel_cell_start); + int sel_row_end = tabular->row_of_cell(sel_cell_end); + if (sel_row_start > sel_row_end) { + swap(sel_row_start, sel_row_end); + } + int const rows = sel_row_end - sel_row_start + 1; + + delete paste_tabular; + paste_tabular = new LyXTabular(this, *tabular); // rows, columns); + for (int i = 0; i < sel_row_start; ++i) + paste_tabular->DeleteRow(0); + while (paste_tabular->rows() > rows) + paste_tabular->DeleteRow(rows); + paste_tabular->SetTopLine(0, true, true); + paste_tabular->SetBottomLine(paste_tabular->GetFirstCellInRow(rows - 1), + true, true); + for (int i = 0; i < sel_col_start; ++i) + paste_tabular->DeleteColumn(0); + while (paste_tabular->columns() > columns) + paste_tabular->DeleteColumn(columns); + paste_tabular->SetLeftLine(0, true, true); + paste_tabular->SetRightLine(paste_tabular->GetLastCellInRow(0), + true, true); + + ostringstream sstr; + paste_tabular->ascii(bv->buffer(), sstr, + (int)parOwner()->params().depth(), true, '\t'); + bv->stuffClipboard(sstr.str().c_str()); + return true; } bool InsetTabular::pasteSelection(BufferView * bv) { - if (!paste_tabular) - return false; + if (!paste_tabular) + return false; - for (int r1 = 0, r2 = actrow; - (r1 < paste_tabular->rows()) && (r2 < tabular->rows()); - ++r1, ++r2) - { - for(int c1 = 0, c2 = actcol; - (c1 < paste_tabular->columns()) && (c2 < tabular->columns()); - ++c1, ++c2) - { - if (paste_tabular->IsPartOfMultiColumn(r1,c1) && - tabular->IsPartOfMultiColumn(r2,c2)) - continue; - if (paste_tabular->IsPartOfMultiColumn(r1,c1)) { - --c2; - continue; - } - if (tabular->IsPartOfMultiColumn(r2,c2)) { - --c1; - continue; - } - int n1 = paste_tabular->GetCellNumber(r1, c1); - int n2 = tabular->GetCellNumber(r2, c2); - *(tabular->GetCellInset(n2)) = *(paste_tabular->GetCellInset(n1)); - tabular->GetCellInset(n2)->setOwner(this); - tabular->GetCellInset(n2)->deleteLyXText(bv); - } - } - return true; + for (int r1 = 0, r2 = actrow; + (r1 < paste_tabular->rows()) && (r2 < tabular->rows()); + ++r1, ++r2) { + for(int c1 = 0, c2 = actcol; + (c1 < paste_tabular->columns()) && (c2 < tabular->columns()); + ++c1, ++c2) { + if (paste_tabular->IsPartOfMultiColumn(r1,c1) && + tabular->IsPartOfMultiColumn(r2,c2)) + continue; + if (paste_tabular->IsPartOfMultiColumn(r1,c1)) { + --c2; + continue; + } + if (tabular->IsPartOfMultiColumn(r2,c2)) { + --c1; + continue; + } + int const n1 = paste_tabular->GetCellNumber(r1, c1); + int const n2 = tabular->GetCellNumber(r2, c2); + *(tabular->GetCellInset(n2)) = *(paste_tabular->GetCellInset(n1)); + tabular->GetCellInset(n2)->setOwner(this); + tabular->GetCellInset(n2)->deleteLyXText(bv); + } + } + return true; } bool InsetTabular::cutSelection() { - if (!hasSelection()) - return false; + if (!hasSelection()) + return false; + + int sel_col_start = tabular->column_of_cell(sel_cell_start); + int sel_col_end = tabular->column_of_cell(sel_cell_end); + if (sel_col_start > sel_col_end) { + sel_col_start = sel_col_end; + sel_col_end = tabular->right_column_of_cell(sel_cell_start); + } else { + sel_col_end = tabular->right_column_of_cell(sel_cell_end); + } + int sel_row_start = tabular->row_of_cell(sel_cell_start); + int sel_row_end = tabular->row_of_cell(sel_cell_end); + if (sel_row_start > sel_row_end) { + swap(sel_row_start, sel_row_end); + } + if (sel_cell_start > sel_cell_end) { + swap(sel_cell_start, sel_cell_end); + } + 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(); + } + } + return true; +} - int sel_col_start; - int sel_col_end; - int sel_row_start; - int sel_row_end; - - sel_col_start = tabular->column_of_cell(sel_cell_start); - sel_col_end = tabular->column_of_cell(sel_cell_end); - if (sel_col_start > sel_col_end) { - sel_col_start = sel_col_end; - sel_col_end = tabular->right_column_of_cell(sel_cell_start); - } else { - sel_col_end = tabular->right_column_of_cell(sel_cell_end); - } - sel_row_start = tabular->row_of_cell(sel_cell_start); - sel_row_end = tabular->row_of_cell(sel_cell_end); - if (sel_row_start > sel_row_end) { - //int tmp = sel_row_start; - //sel_row_start = sel_row_end; - //sel_row_end = tmp; - swap(sel_row_start, sel_row_end); - } - if (sel_cell_start > sel_cell_end) { - //int tmp = sel_cell_start; - //sel_cell_start = sel_cell_end; - //sel_cell_end = tmp; - swap(sel_cell_start, sel_cell_end); - } - 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(); - } - } - return true; -} - -bool InsetTabular::isRightToLeft(BufferView *bv ) + +bool InsetTabular::isRightToLeft(BufferView * bv) { return bv->getParentLanguage(this)->RightToLeft(); } + + +bool InsetTabular::nodraw() const +{ + if (!UpdatableInset::nodraw() && the_locking_inset) + return the_locking_inset->nodraw(); + return UpdatableInset::nodraw(); +} + + +int InsetTabular::scroll(bool recursive) const +{ + int sx = UpdatableInset::scroll(false); + + if (recursive && the_locking_inset) + sx += the_locking_inset->scroll(recursive); + + return sx; +} + + +bool InsetTabular::doClearArea() const +{ + return !locked || (need_update & (FULL|INIT)); +} + + +void InsetTabular::getSelection(int & srow, int & erow, + int & scol, int & ecol) const +{ + int const start = hasSelection() ? sel_cell_start : actcell; + int const end = hasSelection() ? sel_cell_end : actcell; + + srow = tabular->row_of_cell(start); + erow = tabular->row_of_cell(end); + if (srow > erow) { + swap(srow, erow); + } + + scol = tabular->column_of_cell(start); + ecol = tabular->column_of_cell(end); + if (scol > ecol) { + swap(scol, ecol); + } else { + ecol = tabular->right_column_of_cell(end); + } +} + + +Paragraph * InsetTabular::getParFromID(int id) const +{ + Paragraph * result; + for(int i = 0; i < tabular->rows(); ++i) { + for(int j = 0; j < tabular->columns(); ++j) { + if ((result = tabular->GetCellInset(i, j)->getParFromID(id))) + return result; + } + } + return 0; +} + + +Paragraph * InsetTabular::firstParagraph() const +{ + if (the_locking_inset) + return the_locking_inset->firstParagraph(); + return 0; +} + + +Paragraph * InsetTabular::getFirstParagraph(int i) const +{ + return (i < tabular->GetNumberOfCells()) + ? tabular->GetCellInset(i)->getFirstParagraph(0) + : 0; +} + + +LyXCursor const & InsetTabular::cursor(BufferView * bv) const +{ + if (the_locking_inset) + return the_locking_inset->cursor(bv); + return Inset::cursor(bv); +} + + +Inset * InsetTabular::getInsetFromID(int id_arg) const +{ + if (id_arg == id()) + return const_cast(this); + + Inset * result; + for(int i = 0; i < tabular->rows(); ++i) { + for(int j = 0; j < tabular->columns(); ++j) { + if ((result = tabular->GetCellInset(i, j)->getInsetFromID(id_arg))) + return result; + } + } + return 0; +} + + +string const +InsetTabular::selectNextWordToSpellcheck(BufferView * bv, float & value) const +{ + nodraw(true); + if (the_locking_inset) { + string const str(the_locking_inset->selectNextWordToSpellcheck(bv, value)); + if (!str.empty()) { + nodraw(false); + return str; + } + if (tabular->IsLastCell(actcell)) { + bv->unlockInset(const_cast(this)); + nodraw(false); + return string(); + } + ++actcell; + } + // otherwise we have to lock the next inset and ask for it's selecttion + UpdatableInset * inset = + static_cast(tabular->GetCellInset(actcell)); + inset->edit(bv, 0, 0, 0); + string const str(selectNextWordInt(bv, value)); + nodraw(false); + if (!str.empty()) + resetPos(bv); + return str; +} + + +string InsetTabular::selectNextWordInt(BufferView * bv, float & value) const +{ + // when entering this function the inset should be ALWAYS locked! + lyx::Assert(the_locking_inset); + + string const str(the_locking_inset->selectNextWordToSpellcheck(bv, value)); + if (!str.empty()) + return str; + + if (tabular->IsLastCell(actcell)) { + bv->unlockInset(const_cast(this)); + return string(); + } + + // otherwise we have to lock the next inset and ask for it's selecttion + UpdatableInset * inset = + static_cast(tabular->GetCellInset(++actcell)); + inset->edit(bv); + return selectNextWordInt(bv, value); +} + + +void InsetTabular::selectSelectedWord(BufferView * bv) +{ + if (the_locking_inset) { + the_locking_inset->selectSelectedWord(bv); + return; + } + return; +} + + +void InsetTabular::toggleSelection(BufferView * bv, bool kill_selection) +{ + if (the_locking_inset) { + the_locking_inset->toggleSelection(bv, kill_selection); + } +} + + +bool InsetTabular::searchForward(BufferView * bv, string const & str, + bool cs, bool mw) +{ + nodraw(true); + if (the_locking_inset) { + if (the_locking_inset->searchForward(bv, str, cs, mw)) { + nodraw(false); + updateLocal(bv, CELL, false); + return true; + } + if (tabular->IsLastCell(actcell)) { + nodraw(false); + bv->unlockInset(const_cast(this)); + return false; + } + ++actcell; + } + // otherwise we have to lock the next inset and search there + UpdatableInset * inset = + static_cast(tabular->GetCellInset(actcell)); + inset->edit(bv); + bool const ret = searchForward(bv, str, cs, mw); + nodraw(false); + updateLocal(bv, CELL, false); + return ret; +} + + +bool InsetTabular::searchBackward(BufferView * bv, string const & str, + bool cs, bool mw) +{ + nodraw(true); + if (the_locking_inset) { + if (the_locking_inset->searchBackward(bv, str, cs, mw)) { + nodraw(false); + updateLocal(bv, CELL, false); + return true; + } + if (!actcell) { // we are already in the first cell + nodraw(false); + bv->unlockInset(const_cast(this)); + return false; + } + --actcell; + } + // otherwise we have to lock the next inset and search there + UpdatableInset * inset = + static_cast(tabular->GetCellInset(actcell)); + inset->edit(bv, false); + bool const ret = searchBackward(bv, str, cs, mw); + nodraw(false); + updateLocal(bv, CELL, false); + return ret; +} + + +bool InsetTabular::insetAllowed(Inset::Code code) const +{ + if (the_locking_inset) + return the_locking_inset->insetAllowed(code); + return false; +} + + +bool InsetTabular::forceDefaultParagraphs(Inset const * in) const +{ + const int cell = tabular->GetCellFromInset(in, actcell); + + if (cell != -1) + return tabular->GetPWidth(cell).zero(); + + // well we didn't obviously find it so maybe our owner knows more + if (owner()) + return owner()->forceDefaultParagraphs(in); + // if we're here there is really something strange going on!!! + return false; +}