]> git.lyx.org Git - features.git/blobdiff - src/insets/InsetTabular.cpp
Use new display() values to remove some inset hardcoding.
[features.git] / src / insets / InsetTabular.cpp
index 7cb486f606e6128004f102a931a934388f2fa33a..0680d93be8a7e60702400c2ee8030d602b82a926 100644 (file)
@@ -1036,7 +1036,7 @@ bool Tabular::updateColumnWidths(MetricsInfo & mi)
        map<col_type, int> max_pwidth;
        // collect max. variable width of column
        map<col_type, int> max_width;
-       
+
        for(col_type c = 0; c < ncols(); ++c)
                for(row_type r = 0; r < nrows(); ++r) {
                        idx_type const i = cellIndex(r, c);
@@ -1044,14 +1044,20 @@ bool Tabular::updateColumnWidths(MetricsInfo & mi)
                                max_dwidth[c] = max(max_dwidth[c], cell_info[r][c].decimal_width);
                        if (!getPWidth(i).zero())
                                max_pwidth[c] = max(max_pwidth[c], cell_info[r][c].width);
-                       else
+                       else if (!column_info[c].varwidth)
                                max_width[c] = max(max_width[c], cell_info[r][c].width);
                }
 
        // If we have a fixed tabular width, we take this into account
+       Length tab_width = tabular_width;
+       bool const tabularx = hasVarwidthColumn();
+       if (tabularx && tab_width.zero())
+               // If no tabular width is specified with X columns,
+               // we use 100% colwidth
+               tab_width = Length(100, Length::PCW);
        int restwidth = -1;
-       if (!tabular_width.zero()) {
-               restwidth = mi.base.inPixels(tabular_width);
+       if (!tab_width.zero()) {
+               restwidth = mi.base.inPixels(tab_width);
                // Substract the fixed widths from the table width
                for (auto const w : max_pwidth)
                        restwidth -= w.second;
@@ -1068,7 +1074,7 @@ bool Tabular::updateColumnWidths(MetricsInfo & mi)
        if (vcolwidth > 0) {
                bool changed = false;
                for (auto const w : max_width) {
-                       if (w.second > vcolwidth) {
+                       if (tabularx || w.second > vcolwidth) {
                                --restcols;
                                restwidth -= w.second;
                                changed = true;
@@ -1089,16 +1095,23 @@ bool Tabular::updateColumnWidths(MetricsInfo & mi)
                                        && cell_info[r][c].decimal_width != 0)
                                        new_width = max(new_width, cellInfo(i).width
                                                + max_dwidth[c] - cellInfo(i).decimal_width);
-                               else if (getPWidth(i).zero() && vcolwidth > 0)
-                                       new_width = max(vcolwidth, max(new_width, cellInfo(i).width));
-                               else
+                               else if (getPWidth(i).zero() && vcolwidth > 0) {
+                                       if (tabularx && !column_info[c].varwidth)
+                                               new_width = max(new_width, cellInfo(i).width);
+                                       else if (tabularx)
+                                               new_width = vcolwidth;
+                                       else
+                                               new_width = max(vcolwidth, max(new_width, cellInfo(i).width));
+                               } else
                                        new_width = max(new_width, cellInfo(i).width);
                        }
                }
 
                if (column_info[c].width != new_width) {
                        column_info[c].width = new_width;
-                       update = true;
+                       // Do not trigger update when no space is left for variable
+                       // columns, as this will loop
+                       update = tab_width.zero() || restwidth > 0;
                }
        }
        // update col widths to fit merged cells
@@ -1115,7 +1128,9 @@ bool Tabular::updateColumnWidths(MetricsInfo & mi)
 
                        if (cellInfo(i).width > old_width) {
                                column_info[c + span - 1].width += cellInfo(i).width - old_width;
-                               update = true;
+                               // Do not trigger update when no space is left for variable
+                               // columns, as this will loop
+                               update = tab_width.zero() || restwidth > 0;
                        }
                }
 
@@ -3822,7 +3837,6 @@ void InsetTableCell::metrics(MetricsInfo & mi, Dimension & dim) const
 
        // We tell metrics here not to expand on multiple pars
        // This is the difference to InsetText::Metrics
-       // FIXME: pars with newlines are still too wide!
        if (hasFixedWidth())
                tm.metrics(mi, dim, mi.base.textwidth, false);
        else
@@ -3979,8 +3993,10 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
                        Length const p_width = tabular.getPWidth(cell);
                        if (!p_width.zero())
                                m.base.textwidth = mi.base.inPixels(p_width);
+                       else if (tabular.column_info[c].varwidth)
+                               m.base.textwidth = tabular.column_info[c].width;
                        tabular.cellInset(cell)->metrics(m, dim0);
-                       if (!p_width.zero())
+                       if (!p_width.zero() || tabular.column_info[c].varwidth)
                                dim0.wid = m.base.textwidth;
                        tabular.cellInfo(cell).width = dim0.wid + 2 * WIDTH_OF_LINE
                                + tabular.interColumnSpace(cell);
@@ -4047,7 +4063,10 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
                tabular.setRowDescent(r, maxdes + ADD_TO_HEIGHT + bottom_space);
        }
 
-       tabular.updateColumnWidths(mi);
+       // We need to recalculate the metrics after column width calculation
+       // with xtabular (possibly multiple times, so the call is recursive).
+       if (tabular.updateColumnWidths(mi) && tabular.hasVarwidthColumn())
+               metrics(mi, dim);
        dim.asc = tabular.rowAscent(0) - tabular.offsetVAlignment();
        dim.des = tabular.height() - dim.asc;
        dim.wid = tabular.width() + 2 * ADD_TO_TABULAR_WIDTH;
@@ -4192,35 +4211,44 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
 }
 
 
+namespace {
+
+void tabline(PainterInfo const & pi, int x1, int y1, int x2, int y2,
+             bool drawline, bool heavy = false)
+{
+       ColorCode const col = drawline ? Color_tabularline : Color_tabularonoffline;
+       pi.pain.line(x1, y1, x2, y2, pi.textColor(col),
+                                drawline ? Painter::line_solid : Painter::line_onoffdash,
+                                (heavy ? 2 : 1) * Painter::thin_line);
+}
+
+}
+
+
 void InsetTabular::drawCellLines(PainterInfo & pi, int x, int y,
                                 row_type row, idx_type cell) const
 {
        y -= tabular.rowAscent(row);
        int const w = tabular.cellWidth(cell);
        int const h = tabular.cellHeight(cell);
-       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)));
-       pi.pain.line(x, y, x + w, y,
-               drawline ? linecolor : gridcolor,
-               drawline ? Painter::line_solid : Painter::line_onoffdash);
+       bool heavy = tabular.use_booktabs && row == 0 && tabular.rowTopLine(row);
+       tabline(pi, x, y, x + w, y, drawline, heavy);
 
        // Bottom
        drawline = tabular.bottomLine(cell);
-       pi.pain.line(x, y + h, x + w, y + h,
-               drawline ? linecolor : gridcolor,
-               drawline ? Painter::line_solid : Painter::line_onoffdash);
+       heavy = tabular.use_booktabs && row == tabular.nrows() - 1
+               && tabular.rowBottomLine(row);
+       tabline(pi, x, y + h, x + w, y + h, drawline, heavy);
 
        // Left
        col_type const col = tabular.cellColumn(cell);
        drawline = tabular.leftLine(cell)
                || (col > 0 && tabular.rightLine(tabular.cellIndex(row, col - 1)));
-       pi.pain.line(x, y, x, y + h,
-               drawline ? linecolor : gridcolor,
-               drawline ? Painter::line_solid : Painter::line_onoffdash);
+       tabline(pi, x, y, x, y + h, drawline);
 
        // Right
        x -= tabular.interColumnSpace(cell);
@@ -4231,9 +4259,7 @@ void InsetTabular::drawCellLines(PainterInfo & pi, int x, int y,
        drawline = tabular.rightLine(cell)
                   || (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);
+       tabline(pi, x + w, y, x + w, y + h, drawline);
 }
 
 
@@ -5370,13 +5396,13 @@ Inset::DisplayType InsetTabular::display() const
                if (tabular.is_long_tabular) {
                        switch (tabular.longtabular_alignment) {
                        case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
-                               return AlignLeft;
+                               return Display | AlignLeft;
                        case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
-                               return AlignCenter;
+                               return Display;
                        case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
-                               return AlignRight;
+                               return Display | AlignRight;
                        default:
-                               return AlignCenter;
+                               return Display;
                        }
                } else
                        return Inline;
@@ -5814,10 +5840,12 @@ void InsetTabular::tabularFeatures(Cursor & cur,
 
        case Tabular::SET_PWIDTH: {
                Length const len(value);
-               tabular.setColumnPWidth(cur, cur.idx(), len);
-               if (len.zero()
-                   && tabular.getAlignment(cur.idx(), true) == LYX_ALIGN_BLOCK)
-                       tabularFeatures(cur, Tabular::ALIGN_CENTER, string());
+               for (col_type c = sel_col_start; c <= sel_col_end; ++c) {
+                       tabular.setColumnPWidth(cur, tabular.cellIndex(row, c), len);
+                       if (len.zero()
+                           && tabular.getAlignment(tabular.cellIndex(row, c), true) == LYX_ALIGN_BLOCK)
+                               tabularFeatures(cur, Tabular::ALIGN_CENTER, string());
+               }
                break;
        }
 
@@ -5827,7 +5855,8 @@ void InsetTabular::tabularFeatures(Cursor & cur,
 
        case Tabular::TOGGLE_VARWIDTH_COLUMN: {
                bool const varwidth = value == "on";
-               tabular.toggleVarwidth(cur.idx(), varwidth);
+               for (col_type c = sel_col_start; c <= sel_col_end; ++c)
+                       tabular.toggleVarwidth(tabular.cellIndex(row, c), varwidth);
                break;
        }
 
@@ -6187,8 +6216,6 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                tabular.longtabular_alignment = Tabular::LYX_LONGTABULAR_ALIGN_RIGHT;
                break;
 
-
-
        case Tabular::SET_ROTATE_CELL:
                for (row_type r = sel_row_start; r <= sel_row_end; ++r)
                        for (col_type c = sel_col_start; c <= sel_col_end; ++c)
@@ -6545,12 +6572,12 @@ void InsetTabular::getSelection(Cursor & cur,
        cs = tabular.cellColumn(beg.idx());
        ce = tabular.cellColumn(end.idx());
        if (cs > ce)
-               swap(cs, ce);
+               std::swap(cs, ce);
 
        rs = tabular.cellRow(beg.idx());
        re = tabular.cellRow(end.idx());
        if (rs > re)
-               swap(rs, re);
+               std::swap(rs, re);
 }