X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetTabular.cpp;h=9df7d463c3832dde51d9d04e4bd87868c4b9a12a;hb=ebc2b1295a0464dde6c20a09ddc249c463a21c79;hp=cbc2fe85faffa0fc724d2412f0968235af687402;hpb=022228e56f2a58d3a6a79af26e38470ebd74dcaf;p=lyx.git diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index cbc2fe85fa..9df7d463c3 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -127,12 +127,20 @@ TabularFeature tabularFeature[] = { Tabular::MOVE_ROW_UP, "move-row-up", false }, { Tabular::SET_LINE_TOP, "set-line-top", true }, { Tabular::SET_LINE_BOTTOM, "set-line-bottom", true }, + { Tabular::SET_LTRIM_TOP, "set-ltrim-top", true }, + { Tabular::SET_LTRIM_BOTTOM, "set-ltrim-bottom", true }, + { Tabular::SET_RTRIM_TOP, "set-rtrim-top", true }, + { Tabular::SET_RTRIM_BOTTOM, "set-rtrim-bottom", true }, { Tabular::SET_LINE_LEFT, "set-line-left", true }, { Tabular::SET_LINE_RIGHT, "set-line-right", true }, { Tabular::TOGGLE_LINE_TOP, "toggle-line-top", false }, { Tabular::TOGGLE_LINE_BOTTOM, "toggle-line-bottom", false }, { Tabular::TOGGLE_LINE_LEFT, "toggle-line-left", false }, { Tabular::TOGGLE_LINE_RIGHT, "toggle-line-right", false }, + { Tabular::TOGGLE_LTRIM_TOP, "toggle-ltrim-top", false }, + { Tabular::TOGGLE_LTRIM_BOTTOM, "toggle-ltrim-bottom", false }, + { Tabular::TOGGLE_RTRIM_TOP, "toggle-rtrim-top", false }, + { Tabular::TOGGLE_RTRIM_BOTTOM, "toggle-rtrim-bottom", false }, { Tabular::ALIGN_LEFT, "align-left", false }, { Tabular::ALIGN_RIGHT, "align-right", false }, { Tabular::ALIGN_CENTER, "align-center", false }, @@ -155,6 +163,7 @@ TabularFeature tabularFeature[] = { Tabular::UNSET_MULTIROW, "unset-multirow", false }, { Tabular::SET_MROFFSET, "set-mroffset", true }, { Tabular::SET_ALL_LINES, "set-all-lines", false }, + { Tabular::RESET_FORMAL_DEFAULT, "reset-formal-default", false }, { Tabular::UNSET_ALL_LINES, "unset-all-lines", false }, { Tabular::TOGGLE_LONGTABULAR, "toggle-longtabular", false }, { Tabular::SET_LONGTABULAR, "set-longtabular", false }, @@ -199,6 +208,7 @@ TabularFeature tabularFeature[] = { Tabular::LONGTABULAR_ALIGN_RIGHT, "longtabular-align-right", false }, { Tabular::SET_DECIMAL_POINT, "set-decimal-point", true }, { Tabular::SET_TABULAR_WIDTH, "set-tabular-width", true }, + { Tabular::SET_INNER_LINES, "set-inner-lines", false }, { Tabular::LAST_ACTION, "", false } }; @@ -583,6 +593,10 @@ Tabular::CellData::CellData(Buffer * buf) bottom_line(false), left_line(false), right_line(false), + top_line_rtrimmed(false), + top_line_ltrimmed(false), + bottom_line_rtrimmed(false), + bottom_line_ltrimmed(false), usebox(BOX_NONE), rotate(0), inset(new InsetTableCell(buf)) @@ -606,6 +620,10 @@ Tabular::CellData::CellData(CellData const & cs) bottom_line(cs.bottom_line), left_line(cs.left_line), right_line(cs.right_line), + top_line_rtrimmed(cs.top_line_rtrimmed), + top_line_ltrimmed(cs.top_line_ltrimmed), + bottom_line_rtrimmed(cs.bottom_line_rtrimmed), + bottom_line_ltrimmed(cs.bottom_line_ltrimmed), usebox(cs.usebox), rotate(cs.rotate), align_special(cs.align_special), @@ -632,6 +650,10 @@ Tabular::CellData & Tabular::CellData::operator=(CellData const & cs) bottom_line = cs.bottom_line; left_line = cs.left_line; right_line = cs.right_line; + top_line_rtrimmed = cs.top_line_rtrimmed; + top_line_ltrimmed = cs.top_line_ltrimmed; + bottom_line_rtrimmed = cs.bottom_line_rtrimmed; + bottom_line_rtrimmed = cs.bottom_line_rtrimmed; usebox = cs.usebox; rotate = cs.rotate; align_special = cs.align_special; @@ -963,22 +985,40 @@ bool Tabular::bottomLine(idx_type const cell) const } -bool Tabular::leftLine(idx_type cell) const +bool Tabular::leftLine(idx_type cell, bool const ignore_bt) const { - if (use_booktabs) + if (use_booktabs && !ignore_bt) return false; return cellInfo(cell).left_line; } -bool Tabular::rightLine(idx_type cell) const +bool Tabular::rightLine(idx_type cell, bool const ignore_bt) const { - if (use_booktabs) + if (use_booktabs && !ignore_bt) return false; return cellInfo(cell).right_line; } +pair Tabular::topLineTrim(idx_type const cell) const +{ + if (!use_booktabs) + return make_pair(false, false); + return make_pair(cellInfo(cell).top_line_ltrimmed, + cellInfo(cell).top_line_rtrimmed); +} + + +pair Tabular::bottomLineTrim(idx_type const cell) const +{ + if (!use_booktabs) + return make_pair(false, false); + return make_pair(cellInfo(cell).bottom_line_ltrimmed, + cellInfo(cell).bottom_line_rtrimmed); +} + + int Tabular::interRowSpace(row_type row) const { if (!row || row >= nrows()) @@ -1319,6 +1359,42 @@ void Tabular::setBottomLine(idx_type i, bool line) } +void Tabular::setTopLineLTrim(idx_type i, bool val) +{ + cellInfo(i).top_line_ltrimmed = val; +} + + +void Tabular::setTopLineRTrim(idx_type i, bool val) +{ + cellInfo(i).top_line_rtrimmed = val; +} + + +void Tabular::setBottomLineLTrim(idx_type i, bool val) +{ + cellInfo(i).bottom_line_ltrimmed = val; +} + + +void Tabular::setBottomLineRTrim(idx_type i, bool val) +{ + cellInfo(i).bottom_line_rtrimmed = val; +} + + +void Tabular::setTopLineTrim(idx_type i, pair trim) +{ + setTopLineLTrim(i, trim.first); + setTopLineRTrim(i, trim.second); +} + +void Tabular::setBottomLineTrim(idx_type i, pair trim) +{ + setBottomLineLTrim(i, trim.first); + setBottomLineRTrim(i, trim.second); +} + void Tabular::setLeftLine(idx_type cell, bool line) { cellInfo(cell).left_line = line; @@ -1613,7 +1689,11 @@ void Tabular::write(ostream & os) const << write_attribute("alignment", cell_info[r][c].alignment) << write_attribute("valignment", cell_info[r][c].valignment) << write_attribute("topline", cell_info[r][c].top_line) + << write_attribute("toplineltrim", cell_info[r][c].top_line_ltrimmed) + << write_attribute("toplinertrim", cell_info[r][c].top_line_rtrimmed) << write_attribute("bottomline", cell_info[r][c].bottom_line) + << write_attribute("bottomlineltrim", cell_info[r][c].bottom_line_ltrimmed) + << write_attribute("bottomlinertrim", cell_info[r][c].bottom_line_rtrimmed) << write_attribute("leftline", cell_info[r][c].left_line) << write_attribute("rightline", cell_info[r][c].right_line) << write_attribute("rotate", cell_info[r][c].rotate) @@ -1727,7 +1807,11 @@ void Tabular::read(Lexer & lex) getTokenValue(line, "alignment", cell_info[i][j].alignment); getTokenValue(line, "valignment", cell_info[i][j].valignment); getTokenValue(line, "topline", cell_info[i][j].top_line); + getTokenValue(line, "toplineltrim", cell_info[i][j].top_line_ltrimmed); + getTokenValue(line, "toplinertrim", cell_info[i][j].top_line_rtrimmed); getTokenValue(line, "bottomline", cell_info[i][j].bottom_line); + getTokenValue(line, "bottomlineltrim", cell_info[i][j].bottom_line_ltrimmed); + getTokenValue(line, "bottomlinertrim", cell_info[i][j].bottom_line_rtrimmed); getTokenValue(line, "leftline", cell_info[i][j].left_line); getTokenValue(line, "rightline", cell_info[i][j].right_line); getTokenValue(line, "rotate", cell_info[i][j].rotate); @@ -2303,18 +2387,32 @@ void Tabular::TeXTopHLine(otexstream & os, row_type row, string const & lang, // is done in Tabular::TeXBottomHLine(...) // get for each column the topline (if any) - map topline; + map topline, topltrims, toprtrims; col_type nset = 0; + bool have_trims = false; for (auto const & c : columns) { topline[c] = topLine(cellIndex(row, c)); + topltrims[c] = topLineTrim(cellIndex(row, c)).first; + toprtrims[c] = topLineTrim(cellIndex(row, c)).second; // If cell is part of a multirow and not the first cell of the // multirow, no line must be drawn. if (row != 0) if (isMultiRow(cellIndex(row, c)) - && cell_info[row][c].multirow != CELL_BEGIN_OF_MULTIROW) + && cell_info[row][c].multirow != CELL_BEGIN_OF_MULTIROW) { topline[c] = false; + topltrims[c] = false; + toprtrims[c] = false; + } + // copy trimming to multicolumn parts + if (isPartOfMultiColumn(row, c)) { + topltrims[c] = topltrims[c-1]; + toprtrims[c] = toprtrims[c-1]; + } if (topline.find(c) != topline.end() && topline.find(c)->second) ++nset; + if ((topltrims.find(c) != topltrims.end() && topltrims.find(c)->second) + || (toprtrims.find(c) != toprtrims.end() && toprtrims.find(c)->second)) + have_trims = true; } // do nothing if empty first row, or incomplete row line after @@ -2322,36 +2420,66 @@ void Tabular::TeXTopHLine(otexstream & os, row_type row, string const & lang, return; // only output complete row lines and the 1st row's clines - if (nset == ncols()) { + if (nset == ncols() && !have_trims) { if (use_booktabs) { os << (row == 0 ? "\\toprule " : "\\midrule "); } else { os << "\\hline "; } - } else if (row == 0) { + } else if (row == 0 || have_trims) { + string const cline = use_booktabs ? "\\cmidrule" : "\\cline"; for (auto & c : columns) { if (topline.find(c)->second) { 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 << '-'; - + while (isPartOfMultiColumn(row, c)) + ++c; + string trim; + if (topltrims.find(c) != topltrims.end() + && topltrims.find(c)->second) + trim = "l"; + string const firstcol = convert(c + 1 + offset); col_type cstart = c; - for ( ; c < ncols() && topline.find(c)->second; ++c) {} + for ( ; c < ncols() - 1 && topline.find(c)->second ; ++c) { + if (isMultiColumn(cellIndex(row, c)) + && c < ncols() - 1 && isPartOfMultiColumn(row, c + 1)) + continue; + if (c > cstart && topltrims.find(c) != topltrims.end() + && topltrims.find(c)->second) { + if (!isPartOfMultiColumn(row, c)) + --c; + break; + } else if (toprtrims.find(c) != toprtrims.end() + && toprtrims.find(c)->second) + break; + } for (col_type j = cstart ; j < c ; ++j) if (column_info[j].alignment == LYX_ALIGN_DECIMAL) ++offset; + col_type const lastcol = c + 1 + offset; + if (toprtrims.find(c) != toprtrims.end() + && toprtrims.find(c)->second) + trim += "r"; - os << c + 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" << cline; + if (!trim.empty()) + os << "(" << trim << ")"; + os << "\\expandafter{\\expandafter" << firstcol << "\\string-"; + } else { + os << cline; + if (!trim.empty()) + os << "(" << trim << ")"; + os << "{" << firstcol << '-'; + } + os << lastcol << "}"; + if (c == ncols() - 1) + break; } } } @@ -2367,11 +2495,16 @@ void Tabular::TeXBottomHLine(otexstream & os, row_type row, string const & lang, // get the bottomlines of row r, and toplines in next row bool lastrow = row == nrows() - 1; - map bottomline, topline; + map bottomline, topline, topltrims, toprtrims, bottomltrims, bottomrtrims; bool nextrowset = true; for (auto const & c : columns) { + idx_type const idx = cellIndex(row, c); bottomline[c] = bottomLine(cellIndex(row, c)); + bottomltrims[c] = bottomLineTrim(idx).first; + bottomrtrims[c] = bottomLineTrim(idx).second; topline[c] = !lastrow && topLine(cellIndex(row + 1, c)); + topltrims[c] = !lastrow && topLineTrim(cellIndex(row + 1, c)).first; + toprtrims[c] = !lastrow && topLineTrim(cellIndex(row + 1, c)).second; // If cell is part of a multirow and not the last cell of the // multirow, no line must be drawn. if (!lastrow) @@ -2380,52 +2513,103 @@ void Tabular::TeXBottomHLine(otexstream & os, row_type row, string const & lang, && cell_info[row + 1][c].multirow != CELL_BEGIN_OF_MULTIROW) { bottomline[c] = false; topline[c] = false; - } + bottomltrims[c] = false; + bottomrtrims[c] = false; + topltrims[c] = false; + toprtrims[c] = false; + } + // copy trimming in multicolumn parts + if (isPartOfMultiColumn(row, c)) { + topltrims[c] = topltrims[c-1]; + toprtrims[c] = toprtrims[c-1]; + bottomltrims[c] = bottomltrims[c-1]; + bottomrtrims[c] = bottomrtrims[c-1]; + } + nextrowset &= topline.find(c) != topline.end() && topline.find(c)->second; } // combine this row's bottom lines and next row's toplines if necessary col_type nset = 0; + bool have_trims = false; for (auto const & c : columns) { if (!nextrowset) bottomline[c] = bottomline.find(c)->second || topline.find(c)->second; + bottomltrims[c] = (bottomltrims.find(c) != bottomltrims.end() && bottomltrims.find(c)->second) + || (topltrims.find(c) != topltrims.end() && topltrims.find(c)->second); + bottomrtrims[c] =(bottomrtrims.find(c) != bottomrtrims.end() && bottomrtrims.find(c)->second) + || (toprtrims.find(c) != toprtrims.end() && toprtrims.find(c)->second); if (bottomline.find(c)->second) ++nset; + if ((bottomltrims.find(c) != bottomltrims.end() && bottomltrims.find(c)->second) + || (bottomrtrims.find(c) != bottomrtrims.end() && bottomrtrims.find(c)->second)) + have_trims = true; } // do nothing if empty, OR incomplete row line with a topline in next row if (nset == 0 || (nextrowset && nset != ncols())) return; - if (nset == ncols()) { + if (nset == ncols() && !have_trims) { if (use_booktabs) os << (lastrow ? "\\bottomrule" : "\\midrule"); else os << "\\hline "; } else { + string const cline = use_booktabs ? "\\cmidrule" : "\\cline"; for (auto & c : columns) { if (bottomline.find(c)->second) { 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 << '-'; - + while (isPartOfMultiColumn(row, c)) + ++c; + string trim; + if (bottomltrims.find(c) != bottomltrims.end() + && bottomltrims.find(c)->second) + trim = "l"; + string const firstcol = convert(c + 1 + offset); col_type cstart = c; - for ( ; c < ncols() && bottomline.find(c)->second; ++c) {} + for ( ; c < ncols() - 1 && bottomline.find(c)->second ; ++c) { + if (isMultiColumn(cellIndex(row, c)) + && c < ncols() - 1 + && isPartOfMultiColumn(row, c + 1)) + continue; + if (c > cstart && bottomltrims.find(c) != bottomltrims.end() + && bottomltrims.find(c)->second) { + if (!isPartOfMultiColumn(row, c)) + --c; + break; + } else if (bottomrtrims.find(c) != bottomrtrims.end() + && bottomrtrims.find(c)->second) + break; + } for (col_type j = cstart ; j < c ; ++j) if (column_info[j].alignment == LYX_ALIGN_DECIMAL) ++offset; + col_type const lastcol = c + 1 + offset; + if (bottomrtrims.find(c) != bottomrtrims.end() + && bottomrtrims.find(c)->second) + trim += "r"; - os << c + 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" << cline; + if (!trim.empty()) + os << "(" << trim << ")"; + os << "\\expandafter{\\expandafter" << firstcol << "\\string-"; + } else { + os << cline; + if (!trim.empty()) + os << "(" << trim << ")"; + os << "{" << firstcol << '-'; + } + os << lastcol << "}"; + if (c == ncols() - 1) + break; } } } @@ -4213,13 +4397,21 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const namespace { -void tabline(PainterInfo const & pi, int x1, int y1, int x2, int y2, +void tabline(PainterInfo const & pi, int x1, int y1, int x2, int y2, int lt, int rt, bool drawline, bool heavy = false) { ColorCode const col = drawline ? Color_tabularline : Color_tabularonoffline; - pi.pain.line(x1, y1, x2, y2, pi.textColor(col), + if (drawline && lt > 0) + pi.pain.line(x1, y1, x1 + lt, y2, pi.textColor(Color_tabularonoffline), + Painter::line_onoffdash, + Painter::thin_line); + pi.pain.line(x1 + lt, y1, x2 - rt, y2, pi.textColor(col), drawline ? Painter::line_solid : Painter::line_onoffdash, (heavy ? 2 : 1) * Painter::thin_line); + if (drawline && rt > 0) + pi.pain.line(x2 - rt, y1, x2, y2, pi.textColor(Color_tabularonoffline), + Painter::line_onoffdash, + Painter::thin_line); } } @@ -4231,24 +4423,45 @@ void InsetTabular::drawCellLines(PainterInfo & pi, int x, int y, y -= tabular.rowAscent(row); int const w = tabular.cellWidth(cell); int const h = tabular.cellHeight(cell); + int lt = 0; + int rt = 0; + + col_type const col = tabular.cellColumn(cell); // Top bool drawline = tabular.topLine(cell) || (row > 0 && tabular.bottomLine(tabular.cellAbove(cell))); bool heavy = tabular.use_booktabs && row == 0 && tabular.rowTopLine(row); - tabline(pi, x, y, x + w, y, drawline, heavy); + if (tabular.topLineTrim(cell).first + || (row > 0 && tabular.bottomLineTrim(tabular.cellIndex(row - 1, col)).first)) + lt = 10; + if (tabular.topLineTrim(cell).second + || (row > 0 && tabular.bottomLineTrim(tabular.cellIndex(row - 1, col)).second)) + rt = 10; + tabline(pi, x, y, x + w, y, lt, rt, drawline, heavy); // Bottom + lt = rt = 0; drawline = tabular.bottomLine(cell); - heavy = tabular.use_booktabs && row == tabular.nrows() - 1 - && tabular.rowBottomLine(row); - tabline(pi, x, y + h, x + w, y + h, drawline, heavy); + row_type const lastrow = tabular.nrows() - 1; + // Consider multi-rows + row_type r = row; + while (r < lastrow && tabular.isMultiRow(tabular.cellIndex(r, col)) + && tabular.isPartOfMultiRow(r + 1, col)) + r++; + heavy = tabular.use_booktabs + && ((row == lastrow && tabular.rowBottomLine(row)) + || (r == lastrow && tabular.rowBottomLine(r))); + if (tabular.bottomLineTrim(cell).first) + lt = 10; + if (tabular.bottomLineTrim(cell).second) + rt = 10; + tabline(pi, x, y + h, x + w, y + h, lt, rt, drawline, heavy); // Left - col_type const col = tabular.cellColumn(cell); drawline = tabular.leftLine(cell) || (col > 0 && tabular.rightLine(tabular.cellIndex(row, col - 1))); - tabline(pi, x, y, x, y + h, drawline); + tabline(pi, x, y, x, y + h, 0, 0, drawline); // Right x -= tabular.interColumnSpace(cell); @@ -4259,7 +4472,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))); - tabline(pi, x + w, y, x + w, y + h, drawline); + tabline(pi, x + w, y, x + w, y + h, 0, 0, drawline); } @@ -4769,6 +4982,18 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) case LFUN_PASTE: if (!tabularStackDirty()) { + // Check if we have plain text or HTML with rows/columns. + // and if so, pass over to LFUN_CLIPBOARD_PASTE + if (theClipboard().hasTextContents(Clipboard::AnyTextType) + && !theClipboard().hasTextContents(Clipboard::LyXTextType)) { + docstring const clip = + theClipboard().getAsText(Clipboard::AnyTextType); + if (clip.find_first_of(from_ascii("\t\n")) != docstring::npos) { + FuncRequest ncmd = FuncRequest(LFUN_CLIPBOARD_PASTE, cmd.argument()); + doDispatch(cur, ncmd); + break; + } + } if (!cur.selIsMultiCell()) cell(cur.idx())->dispatch(cur, cmd); break; @@ -4969,10 +5194,15 @@ bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s, case Tabular::SET_ALL_LINES: case Tabular::UNSET_ALL_LINES: + case Tabular::SET_INNER_LINES: case Tabular::SET_BORDER_LINES: status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx()))); break; + case Tabular::RESET_FORMAL_DEFAULT: + status.setEnabled(tabular.use_booktabs); + break; + case Tabular::SET_LINE_TOP: case Tabular::SET_LINE_BOTTOM: status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx()))); @@ -4984,6 +5214,20 @@ bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s, && !tabular.ltCaption(tabular.cellRow(cur.idx()))); break; + case Tabular::SET_LTRIM_TOP: + case Tabular::SET_RTRIM_TOP: + status.setEnabled(tabular.use_booktabs + && tabular.cellRow(cur.idx()) != 0 + && !tabular.ltCaption(tabular.cellRow(cur.idx()))); + break; + + case Tabular::SET_LTRIM_BOTTOM: + case Tabular::SET_RTRIM_BOTTOM: + status.setEnabled(tabular.use_booktabs + && tabular.cellRow(cur.idx()) != tabular.nrows() - 1 + && !tabular.ltCaption(tabular.cellRow(cur.idx()))); + break; + case Tabular::TOGGLE_LINE_TOP: status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx()))); status.setOnOff(tabular.topLine(cur.idx())); @@ -5006,6 +5250,30 @@ bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s, status.setOnOff(tabular.rightLine(cur.idx())); break; + case Tabular::TOGGLE_LTRIM_TOP: + status.setEnabled(tabular.use_booktabs + && !tabular.ltCaption(tabular.cellRow(cur.idx()))); + status.setOnOff(tabular.topLineTrim(cur.idx()).first); + break; + + case Tabular::TOGGLE_RTRIM_TOP: + status.setEnabled(tabular.use_booktabs + && !tabular.ltCaption(tabular.cellRow(cur.idx()))); + status.setOnOff(tabular.topLineTrim(cur.idx()).second); + break; + + case Tabular::TOGGLE_LTRIM_BOTTOM: + status.setEnabled(tabular.use_booktabs + && !tabular.ltCaption(tabular.cellRow(cur.idx()))); + status.setOnOff(tabular.bottomLineTrim(cur.idx()).first); + break; + + case Tabular::TOGGLE_RTRIM_BOTTOM: + status.setEnabled(tabular.use_booktabs + && !tabular.ltCaption(tabular.cellRow(cur.idx()))); + status.setOnOff(tabular.bottomLineTrim(cur.idx()).second); + break; + // multirow cells only inherit the alignment of the column if the column has // no width, otherwise they are left-aligned // therefore allow always left but right and center only if there is no width @@ -5316,6 +5584,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, // disable these with multiple cells selected case LFUN_INSET_INSERT: case LFUN_TABULAR_INSERT: + case LFUN_TABULAR_STYLE_INSERT: case LFUN_FLEX_INSERT: case LFUN_FLOAT_INSERT: case LFUN_FLOAT_WIDE_INSERT: @@ -5779,6 +6048,7 @@ void InsetTabular::tabularFeatures(Cursor & cur, row_type sel_row_start; row_type sel_row_end; bool setLines = false; + bool setLinesInnerOnly = false; LyXAlignment setAlign = LYX_ALIGN_LEFT; Tabular::VAlignment setVAlign = Tabular::LYX_VALIGN_TOP; @@ -5885,9 +6155,12 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::DELETE_ROW: if (sel_row_end == tabular.nrows() - 1 && sel_row_start != 0) { - for (col_type c = 0; c < tabular.ncols(); c++) + for (col_type c = 0; c < tabular.ncols(); c++) { tabular.setBottomLine(tabular.cellIndex(sel_row_start - 1, c), tabular.bottomLine(tabular.cellIndex(sel_row_end, c))); + tabular.setBottomLineTrim(tabular.cellIndex(sel_row_start - 1, c), + tabular.bottomLineTrim(tabular.cellIndex(sel_row_end, c))); + } } for (row_type r = sel_row_start; r <= sel_row_end; ++r) @@ -5954,45 +6227,81 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::SET_LINE_TOP: case Tabular::TOGGLE_LINE_TOP: { + bool lineSet = (feature == Tabular::SET_LINE_TOP) + ? (value == "true") : !tabular.topLine(cur.idx()); for (row_type r = sel_row_start; r <= sel_row_end; ++r) - for (col_type c = sel_col_start; c <= sel_col_end; ++c) { - bool const lineSet = (feature == Tabular::SET_LINE_TOP) - ? (value == "true") : !tabular.topLine(tabular.cellIndex(r, c)); + for (col_type c = sel_col_start; c <= sel_col_end; ++c) tabular.setTopLine(tabular.cellIndex(r, c), lineSet); - } break; } case Tabular::SET_LINE_BOTTOM: case Tabular::TOGGLE_LINE_BOTTOM: { + bool lineSet = (feature == Tabular::SET_LINE_BOTTOM) + ? (value == "true") : !tabular.bottomLine(cur.idx()); for (row_type r = sel_row_start; r <= sel_row_end; ++r) - for (col_type c = sel_col_start; c <= sel_col_end; ++c) { - bool const lineSet = (feature == Tabular::SET_LINE_BOTTOM) - ? (value == "true") : !tabular.bottomLine(tabular.cellIndex(r, c)); + for (col_type c = sel_col_start; c <= sel_col_end; ++c) tabular.setBottomLine(tabular.cellIndex(r, c), lineSet); - } + break; + } + + case Tabular::SET_LTRIM_TOP: + case Tabular::TOGGLE_LTRIM_TOP: { + bool l = (feature == Tabular::SET_LTRIM_TOP) + ? (value == "true") : !tabular.topLineTrim(cur.idx()).first; + for (row_type r = sel_row_start; r <= sel_row_end; ++r) + for (col_type c = sel_col_start; c <= sel_col_end; ++c) + tabular.setTopLineLTrim(tabular.cellIndex(r, c), l); + break; + } + + case Tabular::SET_RTRIM_TOP: + case Tabular::TOGGLE_RTRIM_TOP: { + bool l = (feature == Tabular::SET_RTRIM_TOP) + ? (value == "true") : !tabular.topLineTrim(cur.idx()).second; + for (row_type r = sel_row_start; r <= sel_row_end; ++r) + for (col_type c = sel_col_start; c <= sel_col_end; ++c) + tabular.setTopLineRTrim(tabular.cellIndex(r, c), l); + break; + } + + case Tabular::SET_LTRIM_BOTTOM: + case Tabular::TOGGLE_LTRIM_BOTTOM: { + bool l = (feature == Tabular::SET_LTRIM_BOTTOM) + ? (value == "true") : !tabular.bottomLineTrim(cur.idx()).first; + for (row_type r = sel_row_start; r <= sel_row_end; ++r) + for (col_type c = sel_col_start; c <= sel_col_end; ++c) + tabular.setBottomLineLTrim(tabular.cellIndex(r, c), l); + break; + } + + case Tabular::SET_RTRIM_BOTTOM: + case Tabular::TOGGLE_RTRIM_BOTTOM: { + bool l = (feature == Tabular::SET_RTRIM_BOTTOM) + ? (value == "true") : !tabular.bottomLineTrim(cur.idx()).second; + for (row_type r = sel_row_start; r <= sel_row_end; ++r) + for (col_type c = sel_col_start; c <= sel_col_end; ++c) + tabular.setBottomLineRTrim(tabular.cellIndex(r, c), l); break; } case Tabular::SET_LINE_LEFT: case Tabular::TOGGLE_LINE_LEFT: { + bool lineSet = (feature == Tabular::SET_LINE_LEFT) + ? (value == "true") : !tabular.leftLine(cur.idx()); for (row_type r = sel_row_start; r <= sel_row_end; ++r) - for (col_type c = sel_col_start; c <= sel_col_end; ++c) { - bool const lineSet = (feature == Tabular::SET_LINE_LEFT) - ? (value == "true") : !tabular.leftLine(tabular.cellIndex(r, c)); + for (col_type c = sel_col_start; c <= sel_col_end; ++c) tabular.setLeftLine(tabular.cellIndex(r, c), lineSet); - } break; } case Tabular::SET_LINE_RIGHT: case Tabular::TOGGLE_LINE_RIGHT: { + bool lineSet = (feature == Tabular::SET_LINE_RIGHT) + ? (value == "true") : !tabular.rightLine(cur.idx()); for (row_type r = sel_row_start; r <= sel_row_end; ++r) - for (col_type c = sel_col_start; c <= sel_col_end; ++c) { - bool const lineSet = (feature == Tabular::SET_LINE_RIGHT) - ? (value == "true") : !tabular.rightLine(tabular.cellIndex(r, c)); + for (col_type c = sel_col_start; c <= sel_col_end; ++c) tabular.setRightLine(tabular.cellIndex(r, c), lineSet); - } break; } @@ -6135,6 +6444,9 @@ void InsetTabular::tabularFeatures(Cursor & cur, break; } + case Tabular::SET_INNER_LINES: + setLinesInnerOnly = true; + // fall through case Tabular::SET_ALL_LINES: setLines = true; // fall through @@ -6142,13 +6454,30 @@ void InsetTabular::tabularFeatures(Cursor & cur, for (row_type r = sel_row_start; r <= sel_row_end; ++r) for (col_type c = sel_col_start; c <= sel_col_end; ++c) { idx_type const cell = tabular.cellIndex(r, c); - tabular.setTopLine(cell, setLines); - tabular.setBottomLine(cell, setLines); - tabular.setRightLine(cell, setLines); - tabular.setLeftLine(cell, setLines); + if (!setLinesInnerOnly || r != sel_row_start) + tabular.setTopLine(cell, setLines); + if ((!setLinesInnerOnly || r != sel_row_end) + && (!setLines || r == sel_row_end)) + tabular.setBottomLine(cell, setLines); + if ((!setLinesInnerOnly || c != sel_col_end) + && (!setLines || c == sel_col_end)) + tabular.setRightLine(cell, setLines); + if ((!setLinesInnerOnly || c != sel_col_start)) + tabular.setLeftLine(cell, setLines); } break; + case Tabular::RESET_FORMAL_DEFAULT: + for (row_type r = 0; r < tabular.nrows(); ++r) { + bool const head_or_foot = r == 0 || r == tabular.nrows() - 1; + for (col_type c = 0; c < tabular.ncols(); ++c) { + idx_type const cell = tabular.cellIndex(r, c); + tabular.setTopLine(cell, head_or_foot); + tabular.setBottomLine(cell, head_or_foot); + } + } + break; + case Tabular::SET_BORDER_LINES: for (row_type r = sel_row_start; r <= sel_row_end; ++r) { tabular.setLeftLine(tabular.cellIndex(r, sel_col_start), true); @@ -6668,20 +6997,26 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf, } size_t op = 0; - idx_type const cells = loctab->numberofcells; + idx_type cells = loctab->numberofcells; p = 0; cols = ocol; rows = loctab->nrows(); - col_type const columns = loctab->ncols(); + col_type columns = loctab->ncols(); - while (cell < cells && p < len && row < rows && + while (p < len && (p = buf.find_first_of(from_ascii("\t\n"), p)) != docstring::npos) { if (p >= len) break; switch (buf[p]) { case '\t': - // we can only set this if we are not too far right + // append column if necessary + if (cols == columns) { + loctab->appendColumn(cols - 1); + columns = loctab->ncols(); + cells = loctab->numberofcells; + ++cell; + } if (cols < columns) { shared_ptr inset = loctab->cellInset(cell); Font const font = bv.textMetrics(&inset->text()). @@ -6703,6 +7038,12 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf, } cols = ocol; ++row; + // append row if necessary + if (row == rows && p < len - 1) { + loctab->appendRow(row - 1); + rows = loctab->nrows(); + cells = loctab->numberofcells; + } if (row < rows) cell = loctab->cellIndex(row, cols); break;