]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetTabular.cpp
Fix crash after undo following replacement of a multicell selection (#8973).
[lyx.git] / src / insets / InsetTabular.cpp
index 120eb13d315f06036ae65f94d45beaa55045bb42..b12474344606c04db87920a5ca81e3f92c5408a4 100644 (file)
@@ -780,6 +780,8 @@ void Tabular::moveColumn(col_type col, ColDirection direction)
        if (direction == Tabular::LEFT)
                col = col - 1;
 
+       std::swap(column_info[col], column_info[col + 1]);
+
        for (row_type r = 0; r < nrows(); ++r) {
                std::swap(cell_info[r][col], cell_info[r][col + 1]);
                std::swap(cell_info[r][col].left_line, cell_info[r][col + 1].left_line);
@@ -802,6 +804,8 @@ void Tabular::moveRow(row_type row, RowDirection direction)
        if (direction == Tabular::UP)
                row = row - 1;
 
+       std::swap(row_info[row], row_info[row + 1]);
+
        for (col_type c = 0; c < ncols(); ++c) {
                std::swap(cell_info[row][c], cell_info[row + 1][c]);
                std::swap(cell_info[row][c].top_line, cell_info[row + 1][c].top_line);
@@ -1527,14 +1531,13 @@ void Tabular::read(Lexer & lex)
 
        l_getline(is, line);
        if (!prefixIs(line, "<lyxtabular ") && !prefixIs(line, "<Tabular ")) {
-               LASSERT(false, /**/);
-               return;
+               LASSERT(false, return);
        }
 
        int version;
        if (!getTokenValue(line, "version", version))
                return;
-       LASSERT(version >= 2, /**/);
+       LATTEST(version >= 2);
 
        int rows_arg;
        if (!getTokenValue(line, "rows", rows_arg))
@@ -1683,8 +1686,7 @@ Tabular::idx_type Tabular::setMultiColumn(idx_type cell, idx_type number,
        cs.multicolumn = CELL_BEGIN_OF_MULTICOLUMN;
        if (column_info[col].alignment != LYX_ALIGN_DECIMAL)
                cs.alignment = column_info[col].alignment;
-       if (col > 0)
-               setRightLine(cell, right_border);
+       setRightLine(cell, right_border);
 
        for (idx_type i = 1; i < number; ++i) {
                CellData & cs1 = cellInfo(cell + i);
@@ -1867,8 +1869,8 @@ Tabular::idx_type Tabular::cellBelow(idx_type cell) const
 
 Tabular::idx_type Tabular::cellIndex(row_type row, col_type column) const
 {
-       LASSERT(column != npos && column < ncols()
-               && row != npos && row < nrows(), /**/);
+       LASSERT(column != npos && column < ncols(), column = 0);
+       LASSERT(row != npos && row < nrows(), row = 0);
        return cell_info[row][column].cellno;
 }
 
@@ -2099,14 +2101,14 @@ void Tabular::setRowDescent(row_type row, int height)
 
 int Tabular::rowAscent(row_type row) const
 {
-       LASSERT(row < nrows(), /**/);
+       LASSERT(row < nrows(), row = 0);
        return row_info[row].ascent;
 }
 
 
 int Tabular::rowDescent(row_type row) const
 {
-       LASSERT(row < nrows(), /**/);
+       LASSERT(row < nrows(), row = 0);
        return row_info[row].descent;
 }
 
@@ -2123,16 +2125,16 @@ int Tabular::height() const
 
 bool Tabular::isPartOfMultiColumn(row_type row, col_type column) const
 {
-       LASSERT(row < nrows(), /**/);
-       LASSERT(column < ncols(), /**/);
+       LASSERT(row < nrows(), return false);
+       LASSERT(column < ncols(), return false);
        return cell_info[row][column].multicolumn == CELL_PART_OF_MULTICOLUMN;
 }
 
 
 bool Tabular::isPartOfMultiRow(row_type row, col_type column) const
 {
-       LASSERT(row < nrows(), /**/);
-       LASSERT(column < ncols(), /**/);
+       LASSERT(row < nrows(), return false);
+       LASSERT(column < ncols(), return false);
        return cell_info[row][column].multirow == CELL_PART_OF_MULTIROW;
 }
 
@@ -2448,6 +2450,16 @@ void Tabular::TeXLongtableHeaderFooter(otexstream & os,
        if (!is_long_tabular)
                return;
 
+       // caption handling
+       // output caption which is in no header or footer
+       if (haveLTCaption()) {
+               for (row_type r = 0; r < nrows(); ++r) {
+                       if (row_info[r].caption &&
+                           !row_info[r].endfirsthead && !row_info[r].endhead &&
+                           !row_info[r].endfoot && !row_info[r].endlastfoot)
+                               TeXRow(os, r, runparams);
+               }
+       }
        // output first header info
        if (haveLTFirstHead()) {
                if (endfirsthead.topDL)
@@ -3420,6 +3432,12 @@ docstring InsetTableCell::asString(bool intoInsets)
 }
 
 
+void InsetTableCell::addToToc(DocIterator const & di, bool output_active) const
+{
+       InsetText::iterateForToc(di, output_active);
+}
+
+
 docstring InsetTableCell::xhtml(XHTMLStream & xs, OutputParams const & rp) const
 {
        if (!isFixedWidth)
@@ -3480,6 +3498,13 @@ bool InsetTabular::insetAllowed(InsetCode code) const
 }
 
 
+bool InsetTabular::allowsCaptionVariation(std::string const & newtype) const
+{
+       return tabular.is_long_tabular &&
+               (newtype == "Standard" || newtype == "LongTableNoNumber");
+}
+
+
 void InsetTabular::write(ostream & os) const
 {
        os << "Tabular" << endl;
@@ -3549,10 +3574,7 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        //lyxerr << "InsetTabular::metrics: " << mi.base.bv << " width: " <<
        //      mi.base.textwidth << "\n";
-       if (!mi.base.bv) {
-               LYXERR0("need bv");
-               LASSERT(false, /**/);
-       }
+       LBUFERR(mi.base.bv);
 
        for (row_type r = 0; r < tabular.nrows(); ++r) {
                int maxasc = 0;
@@ -3835,9 +3857,13 @@ void InsetTabular::drawCellLines(PainterInfo & pi, int x, int y,
 
        // Right
        x -= tabular.interColumnSpace(cell);
+       col_type next_cell_col = col + 1;
+       while (next_cell_col < tabular.ncols() 
+               && tabular.isMultiColumn(tabular.cellIndex(row, next_cell_col)))
+               next_cell_col++;
        drawline = tabular.rightLine(cell)
-                  || (col + 1 < tabular.ncols()
-                      && tabular.leftLine(tabular.cellIndex(row, col + 1)));
+                  || (next_cell_col < tabular.ncols()
+                      && tabular.leftLine(tabular.cellIndex(row, next_cell_col)));
        pi.pain.line(x + w, y, x + w, y + h,
                drawline ? linecolor : gridcolor,
                drawline ? Painter::line_solid : Painter::line_onoffdash);
@@ -3877,8 +3903,12 @@ void InsetTabular::updateBuffer(ParIterator const & it, UpdateType utype)
        // In a longtable, tell captions what the current float is
        Counters & cnts = buffer().masterBuffer()->params().documentClass().counters();
        string const saveflt = cnts.current_float();
-       if (tabular.is_long_tabular)
+       if (tabular.is_long_tabular) {
                cnts.current_float("table");
+               // in longtables, we only step the counter once
+               cnts.step(from_ascii("table"), utype);
+               cnts.isLongtable(true);
+       }
 
        ParIterator it2 = it;
        it2.forwardPos();
@@ -3887,18 +3917,20 @@ void InsetTabular::updateBuffer(ParIterator const & it, UpdateType utype)
                buffer().updateBuffer(it2, utype);
 
        //reset afterwards
-       if (tabular.is_long_tabular)
+       if (tabular.is_long_tabular) {
                cnts.current_float(saveflt);
+               cnts.isLongtable(false);
+       }
 }
 
 
-void InsetTabular::addToToc(DocIterator const & cpit) const
+void InsetTabular::addToToc(DocIterator const & cpit, bool output_active) const
 {
        DocIterator dit = cpit;
        dit.forwardPos();
        size_t const end = dit.nargs();
        for ( ; dit.idx() < end; dit.top().forwardIdx())
-               cell(dit.idx())->addToToc(dit);
+               cell(dit.idx())->addToToc(dit, output_active);
 }
 
 
@@ -4296,8 +4328,16 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                if (cur.selIsMultiCell()) {
                        cur.recordUndoInset(DELETE_UNDO);
                        cutSelection(cur);
-               }
-               cell(cur.idx())->dispatch(cur, cmd);
+                       BufferView * bv = &cur.bv();
+                       docstring::const_iterator cit = cmd.argument().begin();
+                       docstring::const_iterator const end = cmd.argument().end();
+                       for (; cit != end; ++cit)
+                               bv->translateAndInsert(*cit, getText(cur.idx()), cur);
+       
+                       cur.resetAnchor();
+                       bv->bookmarkEditPosition();
+               } else
+                       cell(cur.idx())->dispatch(cur, cmd);
                break;
 
        case LFUN_CHAR_DELETE_BACKWARD:
@@ -4322,7 +4362,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_CLIPBOARD_PASTE:
        case LFUN_PRIMARY_SELECTION_PASTE: {
                docstring const clip = (act == LFUN_CLIPBOARD_PASTE) ?
-                       theClipboard().getAsText() :
+                       theClipboard().getAsText(Clipboard::PlainTextType) :
                        theSelection().get();
                if (clip.empty())
                        break;
@@ -4370,9 +4410,11 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_FONT_SIZE:
        case LFUN_FONT_UNDERLINE:
        case LFUN_FONT_STRIKEOUT:
-       case LFUN_FONT_UULINE:
-       case LFUN_FONT_UWAVE:
+       case LFUN_FONT_UNDERUNDERLINE:
+       case LFUN_FONT_UNDERWAVE:
        case LFUN_LANGUAGE:
+       case LFUN_PARAGRAPH_PARAMS_APPLY:
+       case LFUN_PARAGRAPH_PARAMS:
        case LFUN_WORD_CAPITALIZE:
        case LFUN_WORD_UPCASE:
        case LFUN_WORD_LOWCASE:
@@ -4730,7 +4772,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
                        break;
 
                case Tabular::UNSET_LTFIRSTHEAD:
-                       status.setEnabled(sel_row_start == sel_row_end && !tabular.ltCaption(sel_row_start));
+                       status.setEnabled(sel_row_start == sel_row_end);
                        status.setOnOff(!tabular.getRowOfLTFirstHead(sel_row_start, dummyltt));
                        break;
 
@@ -4740,7 +4782,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
                        break;
 
                case Tabular::UNSET_LTHEAD:
-                       status.setEnabled(sel_row_start == sel_row_end && !tabular.ltCaption(sel_row_start));
+                       status.setEnabled(sel_row_start == sel_row_end);
                        status.setOnOff(!tabular.getRowOfLTHead(sel_row_start, dummyltt));
                        break;
 
@@ -4750,7 +4792,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
                        break;
 
                case Tabular::UNSET_LTFOOT:
-                       status.setEnabled(sel_row_start == sel_row_end && !tabular.ltCaption(sel_row_start));
+                       status.setEnabled(sel_row_start == sel_row_end);
                        status.setOnOff(!tabular.getRowOfLTFoot(sel_row_start, dummyltt));
                        break;
 
@@ -4760,7 +4802,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
                        break;
 
                case Tabular::UNSET_LTLASTFOOT:
-                       status.setEnabled(sel_row_start == sel_row_end && !tabular.ltCaption(sel_row_start));
+                       status.setEnabled(sel_row_start == sel_row_end);
                        status.setOnOff(!tabular.getRowOfLTLastFoot(sel_row_start, dummyltt));
                        break;
 
@@ -6095,7 +6137,8 @@ void InsetTabular::cutSelection(Cursor & cur)
 
 bool InsetTabular::isRightToLeft(Cursor & cur) const
 {
-       LASSERT(cur.depth() > 1, /**/);
+       // LASSERT: It might be better to abandon this Buffer.
+       LASSERT(cur.depth() > 1, return false);
        Paragraph const & parentpar = cur[cur.depth() - 2].paragraph();
        pos_type const parentpos = cur[cur.depth() - 2].pos();
        return parentpar.getFontSettings(buffer().params(),