]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetTabular.cpp
InsetTabular.cpp: fix #6585 also for wrapped floats - thanks Vincent
[lyx.git] / src / insets / InsetTabular.cpp
index 0ae20f124631c7de986cb515b70fc346e794ef55..39819a3cd211ad52002956027946e2feff89e203 100644 (file)
@@ -523,11 +523,11 @@ InsetTableCell splitCell(InsetTableCell & head, docstring const align_d, bool &
 
        pit_type const psize = head.paragraphs().front().size();
        hassep = dit;
-       if (hassep)
+       if (hassep) {
                head.paragraphs().front().eraseChars(dit.pos(), psize, false);
-
-       tail.paragraphs().front().eraseChars(0, 
-               dit.pos() < psize ? dit.pos() + 1 : psize, false);
+               tail.paragraphs().front().eraseChars(0, 
+                       dit.pos() < psize ? dit.pos() + 1 : psize, false);
+       }
 
        return tail;
 }
@@ -580,7 +580,7 @@ Tabular::CellData::CellData(CellData const & cs)
          rotate(cs.rotate),
          align_special(cs.align_special),
          p_width(cs.p_width),
-         inset(dynamic_cast<InsetTableCell *>(cs.inset->clone()))
+         inset(static_cast<InsetTableCell *>(cs.inset->clone()))
 {
 }
 
@@ -919,7 +919,7 @@ int Tabular::interColumnSpace(idx_type cell) const
 }
 
 
-int Tabular::columnWidth(idx_type cell) const
+int Tabular::cellWidth(idx_type cell) const
 {
        int w = 0;
        col_type const span = columnSpan(cell);
@@ -961,12 +961,14 @@ bool Tabular::updateColumnWidths()
                int new_width = 0;
                for(row_type r = 0; r < nrows(); ++r) {
                        idx_type const i = cellIndex(r, c);
-                       if (columnSpan(i) == 1)
-                               if (getAlignment(i) == LYX_ALIGN_DECIMAL)
+                       if (columnSpan(i) == 1) {
+                               if (getAlignment(i) == LYX_ALIGN_DECIMAL
+                                       && cell_info[r][c].decimal_width!=0)
                                        new_width = max(new_width, cellInfo(i).width 
                                                + max_dwidth[c] - cellInfo(i).decimal_width);
                                else
                                        new_width = max(new_width, cellInfo(i).width);
+                       }
                }
 
                if (column_info[c].width != new_width) {
@@ -1005,13 +1007,6 @@ int Tabular::width() const
 }
 
 
-void Tabular::setCellWidth(idx_type cell, int new_width)
-{
-       cellInfo(cell).width = new_width + 2 * WIDTH_OF_LINE 
-               + interColumnSpace(cell);
-}
-
-
 void Tabular::setAlignment(idx_type cell, LyXAlignment align,
                              bool onlycolumn)
 {
@@ -1241,36 +1236,32 @@ Length const Tabular::getPWidth(idx_type cell) const
 }
 
 
-int Tabular::cellWidth(idx_type cell) const
-{
-       return cellInfo(cell).width;
-}
-
-
 int Tabular::textHOffset(idx_type cell) const
 {
        // the LaTeX Way :-(
        int x = WIDTH_OF_LINE;
 
+       int const w = cellWidth(cell) - cellInfo(cell).width;
+
        switch (getAlignment(cell)) {
        case LYX_ALIGN_CENTER:
-               x += (columnWidth(cell) - cellWidth(cell)) / 2;
+               x += w / 2;
                break;
        case LYX_ALIGN_RIGHT:
-               x += columnWidth(cell) - cellWidth(cell);
-               // + interColumnSpace(cell);
+               x += w;
                break;
        case LYX_ALIGN_DECIMAL: {
                // we center when no decimal point
                if (cellInfo(cell).decimal_width == 0) {
-                       x += (columnWidth(cell) - cellWidth(cell)) / 2;
+                       x += w / 2;
                        break;
                }
                col_type const c = cellColumn(cell);
                int max_dhoffset = 0;
                for(row_type r = 0; r < row_info.size() ; ++r) {
                        idx_type const i = cellIndex(r, c);
-                       if (getAlignment(i) == LYX_ALIGN_DECIMAL)
+                       if (getAlignment(i) == LYX_ALIGN_DECIMAL
+                               && cellInfo(i).decimal_width != 0)
                                max_dhoffset = max(max_dhoffset, cellInfo(i).decimal_hoffset);
                }
                x += max_dhoffset - cellInfo(cell).decimal_hoffset;
@@ -2004,29 +1995,29 @@ int Tabular::TeXTopHLine(odocstream & os, row_type row, string const lang) const
                }
        } else if (row == 0) {
                for (col_type c = 0; c < ncols(); ++c) {
-                       for ( ; c < ncols() && !topline[c]; ++c) {}
-
-                       col_type offset = 0;
-                       for (col_type j = 0 ; j < c; ++j)
-                               if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
-                                       ++offset;
-
-                       //babel makes the "-" character an active one, so we have to suppress this here
-                       //see http://groups.google.com/group/comp.text.tex/browse_thread/thread/af769424a4a0f289#
-                       if (lang == "slovak" || lang == "czech")
-                               os << "\\expandafter" << (use_booktabs ? "\\cmidrule" : "\\cline") 
-                                  << "\\expandafter{\\expandafter" << c + 1 + offset << "\\string-";
-                       else
-                               os << (use_booktabs ? "\\cmidrule{" : "\\cline{") << c + 1 + offset << '-';
-
-                       col_type cstart = c;
-                       for ( ; c < ncols() && topline[c]; ++c) {}
-
-                       for (col_type j = cstart ; j < c ; ++j)
-                               if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
-                                       ++offset;
-
-                       os << c + offset << "} ";
+                       if (topline[c]) {
+                               col_type offset = 0;
+                               for (col_type j = 0 ; j < c; ++j)
+                                       if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
+                                               ++offset;
+                               
+                               //babel makes the "-" character an active one, so we have to suppress this here
+                               //see http://groups.google.com/group/comp.text.tex/browse_thread/thread/af769424a4a0f289#
+                               if (lang == "slovak" || lang == "czech")
+                                       os << "\\expandafter" << (use_booktabs ? "\\cmidrule" : "\\cline") 
+                                       << "\\expandafter{\\expandafter" << c + 1 + offset << "\\string-";
+                               else
+                                       os << (use_booktabs ? "\\cmidrule{" : "\\cline{") << c + 1 + offset << '-';
+                               
+                               col_type cstart = c;
+                               for ( ; c < ncols() && topline[c]; ++c) {}
+                               
+                               for (col_type j = cstart ; j < c ; ++j)
+                                       if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
+                                               ++offset;
+                               
+                               os << c + offset << "} ";
+                       }
                }
        }
        os << "\n";
@@ -2077,29 +2068,29 @@ int Tabular::TeXBottomHLine(odocstream & os, row_type row, string const lang) co
                        os << "\\hline ";
        } else {
                for (col_type c = 0; c < ncols(); ++c) {
-                       for ( ; c < ncols() && !bottomline[c]; ++c) {}
-
-                       col_type offset = 0;
-                       for (col_type j = 0 ; j < c; ++j)
-                               if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
-                                       ++offset;
-
-                       //babel makes the "-" character an active one, so we have to suppress this here
-                       //see http://groups.google.com/group/comp.text.tex/browse_thread/thread/af769424a4a0f289#
-                       if (lang == "slovak" || lang == "czech")
-                               os << "\\expandafter" << (use_booktabs ? "\\cmidrule" : "\\cline") 
-                                  << "\\expandafter{\\expandafter" << c + 1 + offset << "\\string-";
-                       else
-                               os << (use_booktabs ? "\\cmidrule{" : "\\cline{") << c + 1 + offset << '-';
-
-                       col_type cstart = c;
-                       for ( ; c < ncols() && bottomline[c]; ++c) {}
-
-                       for (col_type j = cstart ; j < c ; ++j)
-                               if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
-                                       ++offset;
-
-                       os << c + offset << "} ";
+                       if (bottomline[c]) {
+                               col_type offset = 0;
+                               for (col_type j = 0 ; j < c; ++j)
+                                       if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
+                                               ++offset;
+                               
+                               //babel makes the "-" character an active one, so we have to suppress this here
+                               //see http://groups.google.com/group/comp.text.tex/browse_thread/thread/af769424a4a0f289#
+                               if (lang == "slovak" || lang == "czech")
+                                       os << "\\expandafter" << (use_booktabs ? "\\cmidrule" : "\\cline")
+                                       << "\\expandafter{\\expandafter" << c + 1 + offset << "\\string-";
+                               else
+                                       os << (use_booktabs ? "\\cmidrule{" : "\\cline{") << c + 1 + offset << '-';
+                               
+                               col_type cstart = c;
+                               for ( ; c < ncols() && bottomline[c]; ++c) {}
+                               
+                               for (col_type j = cstart ; j < c ; ++j)
+                                       if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
+                                               ++offset;
+                               
+                               os << c + offset << "} ";
+                       }
                }
        }
        os << "\n";
@@ -2137,7 +2128,7 @@ int Tabular::TeXCellPreamble(odocstream & os, idx_type cell,
 
        // we center in multicol when no decimal point
        ismulticol |= ((column_info[c].alignment == LYX_ALIGN_DECIMAL)
-               && (cellInfo(cell).decimal_width == 0) || isMultiRow(cell));
+               && (cellInfo(cell).decimal_width == 0));
 
        // up counter by 1 for each decimally aligned col since they use 2 latex cols
        int latexcolspan = columnSpan(cell);
@@ -2210,7 +2201,6 @@ int Tabular::TeXCellPreamble(odocstream & os, idx_type cell,
                        os << from_ascii(getPWidth(cell).asLatexString());
                else
                        // we need to set a default value
-                       // needs to be discussed
                        os << "*";
                os << "}{";
        } // end if ismultirow
@@ -2466,7 +2456,7 @@ int Tabular::TeXRow(odocstream & os, row_type row,
                                    : OutputParams::ALIGNED;
 
                if (getAlignment(cell) == LYX_ALIGN_DECIMAL
-                       && cellInfo(cell).decimal_width != 0 && !isMultiRow(cell)) {
+                       && cellInfo(cell).decimal_width != 0) {
                        // copy cell and split in 2
                        InsetTableCell head = InsetTableCell(*cellInset(cell).get());
                        head.getText(0)->setMacrocontextPosition(
@@ -3254,10 +3244,11 @@ void InsetTabular::setBuffer(Buffer & buf)
 
 bool InsetTabular::insetAllowed(InsetCode code) const
 {
-       switch (code)
-       {
+       switch (code) {
+       case FLOAT_CODE:
        case MARGIN_CODE:
        case MATHMACRO_CODE:
+       case WRAP_CODE:
                return false;
 
        case CAPTION_CODE:
@@ -3322,7 +3313,7 @@ int InsetTabular::columnFromX(Cursor & cur, int x) const
        int w = xo(cur.bv()) + ADD_TO_TABULAR_WIDTH;
        col_type c = 0;
        for (; c < tabular.ncols() && x > w; ++c)
-               w += tabular.columnWidth(c);
+               w += tabular.cellWidth(c);
        return c - 1;
 }
 
@@ -3353,7 +3344,8 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
                        tabular.cellInset(cell)->metrics(m, dim);
                        if (!p_width.zero())
                                dim.wid = m.base.textwidth;
-                       tabular.setCellWidth(cell, dim.wid);
+                       tabular.cellInfo(cell).width = dim.wid + 2 * WIDTH_OF_LINE 
+                               + tabular.interColumnSpace(cell);
 
                        // FIXME(?): do we need a second metrics call?
                        TextMetrics const & tm = 
@@ -3362,9 +3354,7 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
                        // determine horiz offset because of decimal align (if necessary)
                        int decimal_hoffset = 0;
                        int decimal_width = 0;
-                       if ((tabular.column_info[c].alignment == LYX_ALIGN_DECIMAL)
-                               && !tabular.isMultiColumn(cell)
-                               && !tabular.isMultiRow(cell)) {
+                       if (tabular.getAlignment(cell) == LYX_ALIGN_DECIMAL) {
                                // make a copy which we will split in 2
                                InsetTableCell head = InsetTableCell(*tabular.cellInset(cell).get());
                                head.getText(0)->setMacrocontextPosition(
@@ -3476,7 +3466,7 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const
                        idx = tabular.cellIndex(r, c);
                        
                        if (tabular.isPartOfMultiRow(r, c)) {
-                               nx += tabular.columnWidth(idx);
+                               nx += tabular.cellWidth(idx);
                                continue;
                        }
 
@@ -3489,8 +3479,8 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const
                        // Cache the Inset position.
                        bv->coordCache().insets().add(cell(idx).get(), cx, cy);
                        cell(idx)->draw(pi, cx, cy);
-                       drawCellLines(pi.pain, nx, y, r, idx, pi.change_);
-                       nx += tabular.columnWidth(idx);
+                       drawCellLines(pi, nx, y, r, idx);
+                       nx += tabular.cellWidth(idx);
                        pi.selected = original_selection_state;
                }
 
@@ -3537,10 +3527,10 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
                                idx_type const cell = tabular.cellIndex(r, c);
 
                                if (tabular.isPartOfMultiRow(r, c)) {
-                                       xx += tabular.columnWidth(cell);
+                                       xx += tabular.cellWidth(cell);
                                        continue;
                                }
-                               int const w = tabular.columnWidth(cell);
+                               int const w = tabular.cellWidth(cell);
                                int const h = tabular.cellHeight(cell);
                                int const yy = y - tabular.rowAscent(r);
                                if (isCellSelected(cur, r, c))
@@ -3560,25 +3550,25 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
 }
 
 
-void InsetTabular::drawCellLines(Painter & pain, int x, int y,
-                                                                row_type row, idx_type cell, Change const & change) const
+void InsetTabular::drawCellLines(PainterInfo & pi, int x, int y,
+                                row_type row, idx_type cell) const
 {
        y -= tabular.rowAscent(row);
-       int const w = tabular.columnWidth(cell);
+       int const w = tabular.cellWidth(cell);
        int const h = tabular.cellHeight(cell);
-       Color linecolor = change.changed() ? change.color() : Color_tabularline;
-       Color gridcolor = change.changed() ? change.color() : Color_tabularonoffline;
+       Color const linecolor = pi.textColor(Color_tabularline);
+       Color const gridcolor = pi.textColor(Color_tabularonoffline);
 
        // Top
        bool drawline = tabular.topLine(cell)
                || (row > 0 && tabular.bottomLine(tabular.cellAbove(cell)));
-       pain.line(x, y, x + w, y,
+       pi.pain.line(x, y, x + w, y,
                drawline ? linecolor : gridcolor,
                drawline ? Painter::line_solid : Painter::line_onoffdash);
 
        // Bottom
        drawline = tabular.bottomLine(cell);
-       pain.line(x, y + h, x + w, y + h,
+       pi.pain.line(x, y + h, x + w, y + h,
                drawline ? linecolor : gridcolor,
                drawline ? Painter::line_solid : Painter::line_onoffdash);
 
@@ -3586,7 +3576,7 @@ void InsetTabular::drawCellLines(Painter & pain, int x, int y,
        col_type const col = tabular.cellColumn(cell);
        drawline = tabular.leftLine(cell)
                || (col > 0 && tabular.rightLine(tabular.cellIndex(row, col - 1)));
-       pain.line(x, y, x, y + h,
+       pi.pain.line(x, y, x, y + h,
                drawline ? linecolor : gridcolor,
                drawline ? Painter::line_solid : Painter::line_onoffdash);
 
@@ -3595,7 +3585,7 @@ void InsetTabular::drawCellLines(Painter & pain, int x, int y,
        drawline = tabular.rightLine(cell)
                   || (col + 1 < tabular.ncols()
                       && tabular.leftLine(tabular.cellIndex(row, col + 1)));
-       pain.line(x + w, y, x + w, y + h,
+       pi.pain.line(x + w, y, x + w, y + h,
                drawline ? linecolor : gridcolor,
                drawline ? Painter::line_solid : Painter::line_onoffdash);
 }
@@ -3747,7 +3737,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                        // only update if selection changes
                        if (bvcur.idx() == cur.idx() &&
                                !(bvcur.realAnchor().idx() == cur.idx() && bvcur.pos() != cur.pos()))
-                               cur.noUpdate();
+                               cur.noScreenUpdate();
                        setCursorFromCoordinates(cur, cmd.x(), cmd.y());
                        bvcur.setCursor(cur);
                        bvcur.setSelection(true);
@@ -3782,7 +3772,15 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_CHAR_RIGHT_SELECT:
        case LFUN_CHAR_RIGHT:
        case LFUN_CHAR_LEFT_SELECT:
-       case LFUN_CHAR_LEFT: {
+       case LFUN_CHAR_LEFT: 
+       case LFUN_WORD_FORWARD:
+       case LFUN_WORD_FORWARD_SELECT:
+       case LFUN_WORD_BACKWARD:
+       case LFUN_WORD_BACKWARD_SELECT:
+       case LFUN_WORD_RIGHT:
+       case LFUN_WORD_RIGHT_SELECT:
+       case LFUN_WORD_LEFT:
+       case LFUN_WORD_LEFT_SELECT: {
                // determine whether we move to next or previous cell, where to enter 
                // the new cell from, and which command to "finish" (i.e., exit the
                // inset) with:
@@ -3791,12 +3789,16 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                FuncCode finish_lfun;
 
                if (act == LFUN_CHAR_FORWARD 
-                               || act == LFUN_CHAR_FORWARD_SELECT) {
+                               || act == LFUN_CHAR_FORWARD_SELECT
+                               || act == LFUN_WORD_FORWARD
+                               || act == LFUN_WORD_FORWARD_SELECT) {
                        next_cell = true;
                        finish_lfun = LFUN_FINISHED_FORWARD;
                }
                else if (act == LFUN_CHAR_BACKWARD
-                               || act == LFUN_CHAR_BACKWARD_SELECT) {
+                               || act == LFUN_CHAR_BACKWARD_SELECT
+                               || act == LFUN_WORD_BACKWARD
+                               || act == LFUN_WORD_BACKWARD_SELECT) {
                        next_cell = false;
                        finish_lfun = LFUN_FINISHED_BACKWARD;
                }
@@ -3804,7 +3806,9 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                // table's direction.
                else {
                        bool const right = act == LFUN_CHAR_RIGHT
-                               || act == LFUN_CHAR_RIGHT_SELECT;
+                               || act == LFUN_CHAR_RIGHT_SELECT
+                               || act == LFUN_WORD_RIGHT
+                               || act == LFUN_WORD_RIGHT_SELECT;
                        next_cell = isRightToLeft(cur) != right;
                        
                        if (lyxrc.visual_cursor)
@@ -3813,10 +3817,14 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                        finish_lfun = right ? LFUN_FINISHED_RIGHT : LFUN_FINISHED_LEFT;
                }
 
-               bool const select = act == LFUN_CHAR_FORWARD_SELECT ||
-                   act == LFUN_CHAR_BACKWARD_SELECT ||
-                   act == LFUN_CHAR_RIGHT_SELECT ||
-                   act == LFUN_CHAR_LEFT_SELECT;
+               bool const select =     act == LFUN_CHAR_FORWARD_SELECT 
+                   || act == LFUN_CHAR_BACKWARD_SELECT
+                   || act == LFUN_CHAR_RIGHT_SELECT
+                   || act == LFUN_CHAR_LEFT_SELECT
+                       || act == LFUN_WORD_FORWARD_SELECT
+                       || act == LFUN_WORD_RIGHT_SELECT
+                       || act == LFUN_WORD_BACKWARD_SELECT
+                       || act == LFUN_WORD_LEFT_SELECT;
 
                // If we have a multicell selection or we're 
                // not doing some LFUN_*_SELECT thing anyway...
@@ -3941,7 +3949,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
 //             col_type const col = tabular.cellColumn(cur.idx());
 //             int const t =   cur.bv().top_y() + cur.bv().height();
 //             if (t < yo() + tabular.getHeightOfTabular()) {
-//                     cur.bv().scrollDocView(t);
+//                     cur.bv().scrollDocView(t, true);
 //                     cur.idx() = tabular.cellBelow(first_visible_cell) + col;
 //             } else {
 //                     cur.idx() = tabular.getFirstCellInRow(tabular.rows() - 1) + col;
@@ -3957,7 +3965,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
 //             col_type const col = tabular.cellColumn(cur.idx());
 //             int const t =   cur.bv().top_y() + cur.bv().height();
 //             if (yo() < 0) {
-//                     cur.bv().scrollDocView(t);
+//                     cur.bv().scrollDocView(t, true);
 //                     if (yo() > 0)
 //                             cur.idx() = col;
 //                     else
@@ -4305,6 +4313,10 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
                        break;
 
                case Tabular::SET_LONGTABULAR:
+                       // setting as longtable is not allowed when table is inside a float
+                       if (cur.innerInsetOfType(FLOAT_CODE) != 0
+                               || cur.innerInsetOfType(WRAP_CODE) != 0)
+                               status.setEnabled(false);
                        status.setOnOff(tabular.is_long_tabular);
                        break;
 
@@ -4646,7 +4658,7 @@ int InsetTabular::dist(BufferView & bv, idx_type const cell, int x, int y) const
        Inset const & inset = *tabular.cellInset(cell);
        Point o = bv.coordCache().getInsets().xy(&inset);
        int const xbeg = o.x_ - tabular.textHOffset(cell);
-       int const xend = xbeg + tabular.columnWidth(cell);
+       int const xend = xbeg + tabular.cellWidth(cell);
        row_type const row = tabular.cellRow(cell);
        int const ybeg = o.y_ - tabular.rowAscent(row)
                - tabular.interRowSpace(row);
@@ -4710,7 +4722,7 @@ int InsetTabular::cellXPos(idx_type const cell) const
        col_type col = tabular.cellColumn(cell);
        int lx = 0;
        for (col_type c = 0; c < col; ++c)
-               lx += tabular.columnWidth(c);
+               lx += tabular.column_info[c].width;
 
        return lx;
 }
@@ -4730,7 +4742,7 @@ void InsetTabular::resetPos(Cursor & cur) const
                int const X2 = maxwidth;
                int const offset = ADD_TO_TABULAR_WIDTH + 2;
                int const x1 = xo(cur.bv()) + cellXPos(cur[i].idx()) + offset;
-               int const x2 = x1 + tabular.columnWidth(cur[i].idx());
+               int const x2 = x1 + tabular.cellWidth(cur[i].idx());
 
                if (x1 < X1)
                        scx_ = X1 + 20 - x1;
@@ -4742,7 +4754,7 @@ void InsetTabular::resetPos(Cursor & cur) const
 
        // only update if offset changed
        if (scx_ != scx_old)
-               cur.updateFlags(Update::Force | Update::FitCursor);
+               cur.screenUpdateFlags(Update::Force | Update::FitCursor);
 }