X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetTabular.cpp;h=b12474344606c04db87920a5ca81e3f92c5408a4;hb=4824f7c9db8301550c1bc53c340fbeae916a46f3;hp=79aaf4b7245cdb177c7d7d152117e3d4a3d94bce;hpb=9236a93894f6a182eb17a219b216eff747e50a27;p=lyx.git diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index 79aaf4b724..b124743446 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -13,6 +13,7 @@ * \author Jürgen Vigna * \author Uwe Stöhr * \author Edwin Leuven + * \author Scott Kostyshak * * Full author contact details are available in file CREDITS. */ @@ -32,6 +33,7 @@ #include "DispatchResult.h" #include "FuncRequest.h" #include "FuncStatus.h" +#include "InsetList.h" #include "Language.h" #include "LaTeXFeatures.h" #include "Lexer.h" @@ -62,10 +64,10 @@ #include -#include +#include #include #include -#include +#include using namespace std; using namespace lyx::support; @@ -114,6 +116,10 @@ TabularFeature tabularFeature[] = { Tabular::DELETE_COLUMN, "delete-column", false }, { Tabular::COPY_ROW, "copy-row", false }, { Tabular::COPY_COLUMN, "copy-column", false }, + { Tabular::MOVE_COLUMN_RIGHT, "move-column-right", false }, + { Tabular::MOVE_COLUMN_LEFT, "move-column-left", false }, + { Tabular::MOVE_ROW_DOWN, "move-row-down", false }, + { 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_LINE_LEFT, "set-line-left", true }, @@ -149,9 +155,9 @@ TabularFeature tabularFeature[] = { Tabular::UNSET_LONGTABULAR, "unset-longtabular", false }, { Tabular::SET_PWIDTH, "set-pwidth", true }, { Tabular::SET_MPWIDTH, "set-mpwidth", true }, - { Tabular::SET_ROTATE_TABULAR, "set-rotate-tabular", false }, - { Tabular::UNSET_ROTATE_TABULAR, "unset-rotate-tabular", false }, - { Tabular::TOGGLE_ROTATE_TABULAR, "toggle-rotate-tabular", false }, + { Tabular::SET_ROTATE_TABULAR, "set-rotate-tabular", true }, + { Tabular::UNSET_ROTATE_TABULAR, "unset-rotate-tabular", true }, + { Tabular::TOGGLE_ROTATE_TABULAR, "toggle-rotate-tabular", true }, { Tabular::SET_ROTATE_CELL, "set-rotate-cell", true }, { Tabular::UNSET_ROTATE_CELL, "unset-rotate-cell", true }, { Tabular::TOGGLE_ROTATE_CELL, "toggle-rotate-cell", true }, @@ -165,6 +171,7 @@ TabularFeature tabularFeature[] = { Tabular::SET_LTLASTFOOT, "set-ltlastfoot", true }, { Tabular::UNSET_LTLASTFOOT, "unset-ltlastfoot", true }, { Tabular::SET_LTNEWPAGE, "set-ltnewpage", false }, + { Tabular::UNSET_LTNEWPAGE, "unset-ltnewpage", false }, { Tabular::TOGGLE_LTCAPTION, "toggle-ltcaption", false }, { Tabular::SET_LTCAPTION, "set-ltcaption", false }, { Tabular::UNSET_LTCAPTION, "unset-ltcaption", false }, @@ -686,7 +693,7 @@ void Tabular::init(Buffer * buf, row_type rows_arg, tabular_valignment = LYX_VALIGN_MIDDLE; tabular_width = Length(); longtabular_alignment = LYX_LONGTABULAR_ALIGN_CENTER; - rotate = false; + rotate = 0; use_booktabs = false; // set silly default lines for (row_type r = 0; r < nrows(); ++r) @@ -768,6 +775,54 @@ void Tabular::insertRow(row_type const row, bool copy) } +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); + std::swap(cell_info[r][col].right_line, cell_info[r][col + 1].right_line); + + // FIXME track changes is broken for tabular features (#8469) + idx_type const i = cellIndex(r, col); + idx_type const j = cellIndex(r, col + 1); + if (buffer().params().trackChanges) { + cellInfo(i).inset->setChange(Change(Change::INSERTED)); + cellInfo(j).inset->setChange(Change(Change::INSERTED)); + } + } + updateIndexes(); +} + + +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); + std::swap(cell_info[row][c].bottom_line, cell_info[row + 1][c].bottom_line); + + // FIXME track changes is broken for tabular features (#8469) + idx_type const i = cellIndex(row, c); + idx_type const j = cellIndex(row + 1, c); + if (buffer().params().trackChanges) { + cellInfo(i).inset->setChange(Change(Change::INSERTED)); + cellInfo(j).inset->setChange(Change(Change::INSERTED)); + } + } + updateIndexes(); +} + + void Tabular::deleteColumn(col_type const col) { // Not allowed to delete last column @@ -1388,7 +1443,7 @@ void Tabular::write(ostream & os) const << ">\n"; // global longtable options os << "(rotate)) << write_attribute("booktabs", use_booktabs) << write_attribute("islongtable", is_long_tabular) << write_attribute("firstHeadTopDL", endfirsthead.topDL) @@ -1476,14 +1531,13 @@ void Tabular::read(Lexer & lex) l_getline(is, line); if (!prefixIs(line, "= 2, /**/); + LATTEST(version >= 2); int rows_arg; if (!getTokenValue(line, "rows", rows_arg)) @@ -1602,6 +1656,16 @@ bool Tabular::isMultiColumn(idx_type cell) const } +bool Tabular::hasMultiColumn(col_type c) const +{ + for (row_type r = 0; r < nrows(); ++r) { + if (isMultiColumn(cellIndex(r, c))) + return true; + } + return false; +} + + Tabular::CellData & Tabular::cellInfo(idx_type cell) const { return cell_info[cellRow(cell)][cellColumn(cell)]; @@ -1622,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); @@ -1642,6 +1705,14 @@ bool Tabular::isMultiRow(idx_type cell) const || cellInfo(cell).multirow == CELL_PART_OF_MULTIROW); } +bool Tabular::hasMultiRow(row_type r) const +{ + for (col_type c = 0; c < ncols(); ++c) { + if (isMultiRow(cellIndex(r, c))) + return true; + } + return false; +} Tabular::idx_type Tabular::setMultiRow(idx_type cell, idx_type number, bool const bottom_border) @@ -1798,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; } @@ -2030,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; } @@ -2054,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; } @@ -2379,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) @@ -2492,7 +2573,8 @@ void Tabular::TeXRow(otexstream & os, row_type row, Paragraph const & par = inset->paragraphs().front(); bool rtl = par.isRTL(buffer().params()) && !par.empty() - && getPWidth(cell).zero(); + && getPWidth(cell).zero() + && !runparams.use_polyglossia; if (rtl) { string const lang = @@ -2599,8 +2681,8 @@ void Tabular::latex(otexstream & os, OutputParams const & runparams) const if (runparams.lastid != -1) os.texrow().start(runparams.lastid, runparams.lastpos); - if (rotate) - os << "\\begin{sideways}\n"; + if (rotate != 0) + os << "\\begin{turn}{" << convert(rotate) << "}\n"; if (is_long_tabular) { os << "\\begin{longtable}"; @@ -2724,8 +2806,8 @@ void Tabular::latex(otexstream & os, OutputParams const & runparams) const os << "\\end{tabular}"; } - if (rotate) - os << breakln << "\\end{sideways}"; + if (rotate != 0) + os << breakln << "\\end{turn}"; } @@ -3016,7 +3098,7 @@ docstring Tabular::xhtml(XHTMLStream & xs, OutputParams const & runparams) const } -bool Tabular::plaintextTopHLine(odocstream & os, row_type row, +bool Tabular::plaintextTopHLine(odocstringstream & os, row_type row, vector const & clen) const { idx_type const fcell = getFirstCellInRow(row); @@ -3064,7 +3146,7 @@ bool Tabular::plaintextTopHLine(odocstream & os, row_type row, } -bool Tabular::plaintextBottomHLine(odocstream & os, row_type row, +bool Tabular::plaintextBottomHLine(odocstringstream & os, row_type row, vector const & clen) const { idx_type const fcell = getFirstCellInRow(row); @@ -3111,14 +3193,14 @@ bool Tabular::plaintextBottomHLine(odocstream & os, row_type row, } -void Tabular::plaintextPrintCell(odocstream & os, +void Tabular::plaintextPrintCell(odocstringstream & os, OutputParams const & runparams, idx_type cell, row_type row, col_type column, vector const & clen, - bool onlydata) const + bool onlydata, size_t max_length) const { odocstringstream sstr; - cellInset(cell)->plaintext(sstr, runparams); + cellInset(cell)->plaintext(sstr, runparams, max_length); if (onlydata) { os << sstr.str(); @@ -3161,9 +3243,9 @@ void Tabular::plaintextPrintCell(odocstream & os, } -void Tabular::plaintext(odocstream & os, +void Tabular::plaintext(odocstringstream & os, OutputParams const & runparams, int const depth, - bool onlydata, char_type delim) const + bool onlydata, char_type delim, size_t max_length) const { // first calculate the width of the single columns vector clen(ncols()); @@ -3177,7 +3259,7 @@ void Tabular::plaintext(odocstream & os, if (isMultiColumn(cell)) continue; odocstringstream sstr; - cellInset(cell)->plaintext(sstr, runparams); + cellInset(cell)->plaintext(sstr, runparams, max_length); if (clen[c] < sstr.str().length()) clen[c] = sstr.str().length(); } @@ -3189,7 +3271,7 @@ void Tabular::plaintext(odocstream & os, if (cell_info[r][c].multicolumn != CELL_BEGIN_OF_MULTICOLUMN) continue; odocstringstream sstr; - cellInset(cell)->plaintext(sstr, runparams); + cellInset(cell)->plaintext(sstr, runparams, max_length); int len = int(sstr.str().length()); idx_type const n = columnSpan(cell); for (col_type k = c; len > 0 && k < c + n - 1; ++k) @@ -3210,8 +3292,10 @@ void Tabular::plaintext(odocstream & os, // we don't use operator<< for single UCS4 character. // see explanation in docstream.h os.put(delim); - plaintextPrintCell(os, runparams, cell, r, c, clen, onlydata); + plaintextPrintCell(os, runparams, cell, r, c, clen, onlydata, max_length); ++cell; + if (os.str().size() > max_length) + break; } os << endl; if (!onlydata) { @@ -3219,6 +3303,8 @@ void Tabular::plaintext(odocstream & os, if (plaintextBottomHLine(os, r, clen)) os << docstring(depth * 2, ' '); } + if (os.str().size() > max_length) + break; } } @@ -3346,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) @@ -3406,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; @@ -3475,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; @@ -3761,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); @@ -3803,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(); @@ -3813,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); } @@ -4027,6 +4133,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) if (select_whole && !empty_cell){ getText(cur.idx())->selectAll(cur); cur.dispatched(); + cur.screenUpdateFlags(Update::Force | Update::FitCursor); break; } @@ -4091,9 +4198,10 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) cur.pit() = cur.lastpit(); cur.pos() = cur.lastpos(); cur.setCurrentFont(); + cur.screenUpdateFlags(Update::Force | Update::FitCursor); return; } - cur.screenUpdateFlags(Update::FitCursor); + cur.screenUpdateFlags(Update::Force | Update::FitCursor); break; case LFUN_UP_SELECT: @@ -4129,9 +4237,10 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) cur.pit() = 0; cur.pos() = cur.lastpos(); cur.setCurrentFont(); + cur.screenUpdateFlags(Update::Force | Update::FitCursor); return; } - cur.screenUpdateFlags(Update::FitCursor); + cur.screenUpdateFlags(Update::Force | Update::FitCursor); break; // case LFUN_SCREEN_DOWN: { @@ -4219,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: @@ -4245,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; @@ -4293,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: @@ -4406,6 +4525,56 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, && tabular.tabular_valignment == Tabular::LYX_VALIGN_MIDDLE); break; + case Tabular::MOVE_COLUMN_RIGHT: + case Tabular::MOVE_COLUMN_LEFT: + case Tabular::MOVE_ROW_DOWN: + case Tabular::MOVE_ROW_UP: { + if (cur.selection()) { + status.message(_("Selections not supported.")); + status.setEnabled(false); + break; + } + + if ((action == Tabular::MOVE_COLUMN_RIGHT && + tabular.ncols() == tabular.cellColumn(cur.idx()) + 1) || + (action == Tabular::MOVE_COLUMN_LEFT && + tabular.cellColumn(cur.idx()) == 0) || + (action == Tabular::MOVE_ROW_DOWN && + tabular.nrows() == tabular.cellRow(cur.idx()) + 1) || + (action == Tabular::MOVE_ROW_UP && + tabular.cellRow(cur.idx()) == 0)) { + status.setEnabled(false); + break; + } + + if (action == Tabular::MOVE_COLUMN_RIGHT || + action == Tabular::MOVE_COLUMN_LEFT) { + if (tabular.hasMultiColumn(tabular.cellColumn(cur.idx())) || + tabular.hasMultiColumn(tabular.cellColumn(cur.idx()) + + (action == Tabular::MOVE_COLUMN_RIGHT ? 1 : -1))) { + status.message(_("Multi-column in current or" + " destination column.")); + status.setEnabled(false); + break; + } + } + + if (action == Tabular::MOVE_ROW_DOWN || + action == Tabular::MOVE_ROW_UP) { + if (tabular.hasMultiRow(tabular.cellRow(cur.idx())) || + tabular.hasMultiRow(tabular.cellRow(cur.idx()) + + (action == Tabular::MOVE_ROW_DOWN ? 1 : -1))) { + status.message(_("Multi-row in current or" + " destination row.")); + status.setEnabled(false); + break; + } + } + + status.setEnabled(true); + break; + } + case Tabular::SET_DECIMAL_POINT: status.setEnabled( tabular.getAlignment(cur.idx()) == LYX_ALIGN_DECIMAL); @@ -4544,8 +4713,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, case Tabular::TOGGLE_ROTATE_TABULAR: case Tabular::SET_ROTATE_TABULAR: - status.setEnabled(tabular.tabular_width.zero()); - status.setOnOff(tabular.rotate); + status.setOnOff(tabular.rotate != 0); break; case Tabular::TABULAR_VALIGN_TOP: @@ -4578,7 +4746,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, break; case Tabular::UNSET_ROTATE_TABULAR: - status.setOnOff(!tabular.rotate); + status.setOnOff(tabular.rotate == 0); break; case Tabular::TOGGLE_ROTATE_CELL: @@ -4604,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; @@ -4614,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; @@ -4624,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; @@ -4634,13 +4802,16 @@ 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; case Tabular::SET_LTNEWPAGE: status.setOnOff(tabular.getLTNewPage(sel_row_start)); break; + case Tabular::UNSET_LTNEWPAGE: + status.setOnOff(!tabular.getLTNewPage(sel_row_start)); + break; // only one row in head/firsthead/foot/lasthead can be the caption // and a multirow cannot be set as caption @@ -4691,6 +4862,37 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, return true; } + case LFUN_CAPTION_INSERT: { + // caption is only allowed in caption cell of longtable + if (!tabular.ltCaption(tabular.cellRow(cur.idx()))) { + status.setEnabled(false); + return true; + } + // only standard caption is allowed + string arg = cmd.getArg(0); + if (!arg.empty() && arg != "Standard") { + status.setEnabled(false); + return true; + } + // check if there is already a caption + bool have_caption = false; + InsetTableCell itc = InsetTableCell(*tabular.cellInset(cur.idx()).get()); + ParagraphList::const_iterator pit = itc.paragraphs().begin(); + ParagraphList::const_iterator pend = itc.paragraphs().end(); + for (; pit != pend; ++pit) { + InsetList::const_iterator it = pit->insetList().begin(); + InsetList::const_iterator end = pit->insetList().end(); + for (; it != end; ++it) { + if (it->inset->lyxCode() == CAPTION_CODE) { + have_caption = true; + break; + } + } + } + status.setEnabled(!have_caption); + return true; + } + // These are only enabled inside tabular case LFUN_CELL_BACKWARD: case LFUN_CELL_FORWARD: @@ -4725,7 +4927,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, } // disable in non-fixed-width cells - case LFUN_BREAK_PARAGRAPH: + case LFUN_PARAGRAPH_BREAK: // multirow does not allow paragraph breaks if (tabular.isMultiRow(cur.idx())) { status.setEnabled(false); @@ -4798,11 +5000,12 @@ void InsetTabular::latex(otexstream & os, OutputParams const & runparams) const } -int InsetTabular::plaintext(odocstream & os, OutputParams const & runparams) const +int InsetTabular::plaintext(odocstringstream & os, + OutputParams const & runparams, size_t max_length) const { os << '\n'; // output table on a new line int const dp = runparams.linelen > 0 ? runparams.depth : 0; - tabular.plaintext(os, runparams, dp, false, 0); + tabular.plaintext(os, runparams, dp, false, 0, max_length); return PLAINTEXT_NEWLINE; } @@ -5196,6 +5399,7 @@ bool InsetTabular::oneCellHasRotationState(bool rotated, return false; } + void InsetTabular::tabularFeatures(Cursor & cur, Tabular::Feature feature, string const & value) { @@ -5229,7 +5433,10 @@ void InsetTabular::tabularFeatures(Cursor & cur, break; case Tabular::ALIGN_DECIMAL: - setAlign = LYX_ALIGN_DECIMAL; + if (tabular.column_info[tabular.cellColumn(cur.idx())].alignment == LYX_ALIGN_DECIMAL) + setAlign = LYX_ALIGN_CENTER; + else + setAlign = LYX_ALIGN_DECIMAL; break; case Tabular::M_VALIGN_TOP: @@ -5302,6 +5509,12 @@ void InsetTabular::tabularFeatures(Cursor & cur, break; case Tabular::DELETE_ROW: + if (sel_row_end == tabular.nrows() - 1 && sel_row_start != 0) { + 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))); + } + for (row_type r = sel_row_start; r <= sel_row_end; ++r) tabular.deleteRow(sel_row_start); if (sel_row_start >= tabular.nrows()) @@ -5313,6 +5526,18 @@ void InsetTabular::tabularFeatures(Cursor & cur, break; case Tabular::DELETE_COLUMN: + if (sel_col_end == tabular.ncols() - 1 && sel_col_start != 0) { + for (row_type r = 0; r < tabular.nrows(); r++) + tabular.setRightLine(tabular.cellIndex(r, sel_col_start - 1), + tabular.rightLine(tabular.cellIndex(r, sel_col_end))); + } + + if (sel_col_start == 0 && sel_col_end != tabular.ncols() - 1) { + for (row_type r = 0; r < tabular.nrows(); r++) + tabular.setLeftLine(tabular.cellIndex(r, sel_col_end + 1), + tabular.leftLine(tabular.cellIndex(r, 0))); + } + for (col_type c = sel_col_start; c <= sel_col_end; ++c) tabular.deleteColumn(sel_col_start); if (sel_col_start >= tabular.ncols()) @@ -5332,6 +5557,26 @@ void InsetTabular::tabularFeatures(Cursor & cur, cur.idx() = tabular.cellIndex(row, column); break; + case Tabular::MOVE_COLUMN_RIGHT: + tabular.moveColumn(column, Tabular::RIGHT); + cur.idx() = tabular.cellIndex(row, column + 1); + break; + + case Tabular::MOVE_COLUMN_LEFT: + tabular.moveColumn(column, Tabular::LEFT); + cur.idx() = tabular.cellIndex(row, column - 1); + break; + + case Tabular::MOVE_ROW_DOWN: + tabular.moveRow(row, Tabular::DOWN); + cur.idx() = tabular.cellIndex(row + 1, column); + break; + + case Tabular::MOVE_ROW_UP: + tabular.moveRow(row, Tabular::UP); + cur.idx() = tabular.cellIndex(row - 1, column); + break; + case Tabular::SET_LINE_TOP: case Tabular::TOGGLE_LINE_TOP: { bool lineSet = (feature == Tabular::SET_LINE_TOP) @@ -5407,7 +5652,7 @@ void InsetTabular::tabularFeatures(Cursor & cur, tabular.rightLine(cur.idx())); break; } - // we have a selection so this means we just add all this + // we have a selection so this means we just add all these // cells to form a multicolumn cell idx_type const s_start = cur.selBegin().idx(); row_type const col_start = tabular.cellColumn(s_start); @@ -5549,15 +5794,16 @@ void InsetTabular::tabularFeatures(Cursor & cur, break; case Tabular::SET_ROTATE_TABULAR: - tabular.rotate = true; + tabular.rotate = convert(value); break; case Tabular::UNSET_ROTATE_TABULAR: - tabular.rotate = false; + tabular.rotate = 0; break; case Tabular::TOGGLE_ROTATE_TABULAR: - tabular.rotate = !tabular.rotate; + // when pressing the rotate button we default to 90° rotation + tabular.rotate != 0 ? tabular.rotate = 0 : tabular.rotate = 90; break; case Tabular::TABULAR_VALIGN_TOP: @@ -5656,8 +5902,10 @@ void InsetTabular::tabularFeatures(Cursor & cur, tabular.setLTFoot(row, flag, ltt, true); break; + case Tabular::UNSET_LTNEWPAGE: + flag = false; case Tabular::SET_LTNEWPAGE: - tabular.setLTNewPage(row, !tabular.getLTNewPage(row)); + tabular.setLTNewPage(row, flag); break; case Tabular::SET_LTCAPTION: { @@ -5798,7 +6046,7 @@ bool InsetTabular::copySelection(Cursor & cur) odocstringstream os; OutputParams const runparams(0); - paste_tabular->plaintext(os, runparams, 0, true, '\t'); + paste_tabular->plaintext(os, runparams, 0, true, '\t', INT_MAX); // Needed for the "Edit->Paste recent" menu and the system clipboard. cap::copySelection(cur, os.str()); @@ -5889,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(),