X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ftabular.C;h=239c1ff65be9281f7f77139172c3f948b78007ca;hb=3ef684e752bb5afdbfdea51d4c3df4afe1461916;hp=10e8d938fc374924dfa8a4875a2fde4d344d5b23;hpb=94a6cafe4a78d69b5a52df27535dc43e150f452d;p=lyx.git diff --git a/src/tabular.C b/src/tabular.C index 10e8d938fc..239c1ff65b 100644 --- a/src/tabular.C +++ b/src/tabular.C @@ -37,10 +37,13 @@ #include -using lyx::support::ltrim; -using lyx::support::prefixIs; -using lyx::support::rtrim; -using lyx::support::suffixIs; + +namespace lyx { + +using support::prefixIs; +using support::ltrim; +using support::rtrim; +using support::suffixIs; using boost::shared_ptr; using boost::dynamic_pointer_cast; @@ -64,6 +67,8 @@ using std::strlen; namespace { int const WIDTH_OF_LINE = 5; +int const default_line_space = 10; + template string const write_attribute(string const & name, T const & t) @@ -299,6 +304,21 @@ bool getTokenValue(string const & str, char const * token, LyXLength & len) } +bool getTokenValue(string const & str, char const * token, LyXLength & len, bool & flag) +{ + len = LyXLength(); + flag = false; + string tmp; + if (!getTokenValue(str, token, tmp)) + return false; + if (tmp == "default") { + flag = true; + return true; + } + return isValidLength(tmp, &len); +} + + void l_getline(istream & is, string & str) { str.erase(); @@ -380,6 +400,9 @@ LyXTabular::rowstruct::rowstruct() descent_of_row(0), top_line(true), bottom_line(false), + top_space_default(false), + bottom_space_default(false), + interline_space_default(false), endhead(false), endfirsthead(false), endfoot(false), @@ -406,7 +429,7 @@ LyXTabular::ltType::ltType() LyXTabular::LyXTabular(BufferParams const & bp, row_type rows_arg, - col_type columns_arg) + col_type columns_arg) { init(bp, rows_arg, columns_arg); } @@ -414,7 +437,7 @@ LyXTabular::LyXTabular(BufferParams const & bp, row_type rows_arg, // activates all lines and sets all widths to 0 void LyXTabular::init(BufferParams const & bp, row_type rows_arg, - col_type columns_arg) + col_type columns_arg) { rows_ = rows_arg; columns_ = columns_arg; @@ -432,6 +455,7 @@ void LyXTabular::init(BufferParams const & bp, row_type rows_arg, column_info.back().right_line = true; is_long_tabular = false; rotate = false; + use_booktabs = false; } @@ -474,9 +498,9 @@ void LyXTabular::appendRow(BufferParams const & bp, idx_type const cell) for (row_type i = row + 2; i < rows_; ++i) swap(cell_info[i], old[i - 1]); - if (bp.tracking_changes) + if (bp.trackChanges) for (col_type j = 0; j < columns_; ++j) - cell_info[row + 1][j].inset->markNew(true); + cell_info[row + 1][j].inset->setChange(Change(Change::INSERTED)); set_row_column_number_info(); } @@ -495,6 +519,21 @@ void LyXTabular::deleteRow(row_type const row) } +void LyXTabular::copyRow(BufferParams const & bp, row_type const row) +{ + ++rows_; + + row_info.insert(row_info.begin() + row, row_info[row]); + cell_info.insert(cell_info.begin() + row, cell_info[row]); + + if (bp.trackChanges) + for (col_type j = 0; j < columns_; ++j) + cell_info[row + 1][j].inset->setChange(Change(Change::INSERTED)); + + set_row_column_number_info(); +} + + void LyXTabular::appendColumn(BufferParams const & bp, idx_type const cell) { ++columns_; @@ -519,8 +558,8 @@ void LyXTabular::appendColumn(BufferParams const & bp, idx_type const cell) //++column; for (row_type i = 0; i < rows_; ++i) { cell_info[i][column + 1].inset->clear(); - if (bp.tracking_changes) - cell_info[i][column + 1].inset->markNew(true); + if (bp.trackChanges) + cell_info[i][column + 1].inset->setChange(Change(Change::INSERTED)); } fixCellNums(); } @@ -540,6 +579,22 @@ void LyXTabular::deleteColumn(col_type const column) } +void LyXTabular::copyColumn(BufferParams const & bp, col_type const column) +{ + ++columns_; + + column_info.insert(column_info.begin() + column, column_info[column]); + + for (row_type i = 0; i < rows_; ++i) + cell_info[i].insert(cell_info[i].begin() + column, cell_info[i][column]); + + if (bp.trackChanges) + for (row_type i = 0; i < rows_; ++i) + cell_info[i][column + 1].inset->setChange(Change(Change::INSERTED)); + fixCellNums(); +} + + void LyXTabular::set_row_column_number_info() { numberofcells = 0; @@ -607,10 +662,10 @@ LyXTabular::idx_type LyXTabular::numberOfCellsInRow(idx_type const cell) const } -// returns 1 if there is a topline, returns 0 if not bool LyXTabular::topLine(idx_type const cell, bool const onlycolumn) const { - if (!onlycolumn && isMultiColumn(cell)) + if (!onlycolumn && isMultiColumn(cell) && + !(use_booktabs && row_of_cell(cell) == 0)) return cellinfo_of_cell(cell).top_line; return row_info[row_of_cell(cell)].top_line; } @@ -618,7 +673,8 @@ bool LyXTabular::topLine(idx_type const cell, bool const onlycolumn) const bool LyXTabular::bottomLine(idx_type const cell, bool onlycolumn) const { - if (!onlycolumn && isMultiColumn(cell)) + if (!onlycolumn && isMultiColumn(cell) && + !(use_booktabs && isLastRow(cell))) return cellinfo_of_cell(cell).bottom_line; return row_info[row_of_cell(cell)].bottom_line; } @@ -626,6 +682,8 @@ bool LyXTabular::bottomLine(idx_type const cell, bool onlycolumn) const bool LyXTabular::leftLine(idx_type cell, bool onlycolumn) const { + if (use_booktabs) + return false; if (!onlycolumn && isMultiColumn(cell) && (isFirstCellInRow(cell) || isMultiColumn(cell-1))) { @@ -641,6 +699,8 @@ bool LyXTabular::leftLine(idx_type cell, bool onlycolumn) const bool LyXTabular::rightLine(idx_type cell, bool onlycolumn) const { + if (use_booktabs) + return false; if (!onlycolumn && isMultiColumn(cell) && (isLastCellInRow(cell) || isMultiColumn(cell + 1))) { @@ -721,9 +781,12 @@ int LyXTabular::getAdditionalHeight(row_type row) const top = row_info[row].top_line; } } + int const interline_space = row_info[row - 1].interline_space_default ? + default_line_space : + row_info[row - 1].interline_space.inPixels(width_of_tabular); if (top && bottom) - return WIDTH_OF_LINE; - return 0; + return interline_space + WIDTH_OF_LINE; + return interline_space; } @@ -856,7 +919,7 @@ void LyXTabular::setWidthOfCell(idx_type cell, int new_width) void LyXTabular::setAlignment(idx_type cell, LyXAlignment align, - bool onlycolumn) + bool onlycolumn) { if (!isMultiColumn(cell) || onlycolumn) column_info[column_of_cell(cell)].alignment = align; @@ -866,7 +929,7 @@ void LyXTabular::setAlignment(idx_type cell, LyXAlignment align, void LyXTabular::setVAlignment(idx_type cell, VAlignment align, - bool onlycolumn) + bool onlycolumn) { if (!isMultiColumn(cell) || onlycolumn) column_info[column_of_cell(cell)].valignment = align; @@ -889,15 +952,14 @@ void toggleFixedWidth(LCursor & cur, InsetText * inset, bool fixedWidth) return; // merge all paragraphs to one - BufferParams const & bp = - inset->getText(0)->bv_owner->buffer()->params(); + BufferParams const & bp = cur.bv().buffer()->params(); while (inset->paragraphs().size() > 1) mergeParagraph(bp, inset->paragraphs(), 0); // reset layout cur.push(*inset); // undo information has already been recorded - inset->getText(0)->setLayout(0, cur.lastpit() + 1, + inset->getText(0)->setLayout(*cur.bv().buffer(), 0, cur.lastpit() + 1, bp.getLyXTextClass().defaultLayoutName()); cur.pop(); } @@ -915,7 +977,7 @@ void LyXTabular::setColumnPWidth(LCursor & cur, idx_type cell, idx_type const cell = getCellNumber(i, j); // because of multicolumns toggleFixedWidth(cur, getCellInset(cell).get(), - !getPWidth(cell).zero()); + !getPWidth(cell).zero()); } // cur paragraph can become invalid after paragraphs were merged if (cur.pit() > cur.lastpit()) @@ -1193,6 +1255,7 @@ void LyXTabular::write(Buffer const & buf, ostream & os) const // global longtable options os << "= rows_) @@ -1777,12 +1874,14 @@ int LyXTabular::TeXBottomHLine(ostream & os, row_type row) const if (bottomLine(i)) ++tmp; } - if (tmp == n - fcell) { - os << "\\hline"; + if (use_booktabs && row == rows_ - 1) { + os << "\\bottomrule"; + } else if (tmp == n - fcell) { + os << (use_booktabs ? "\\midrule" : "\\hline"); } else if (tmp) { for (idx_type i = fcell; i < n; ++i) { if (bottomLine(i)) { - os << "\\cline{" + os << (use_booktabs ? "\\cmidrule{" : "\\cline{") << column_of_cell(i) + 1 << '-' << right_column_of_cell(i) + 1 @@ -1797,7 +1896,7 @@ int LyXTabular::TeXBottomHLine(ostream & os, row_type row) const } -int LyXTabular::TeXCellPreamble(ostream & os, idx_type cell) const +int LyXTabular::TeXCellPreamble(odocstream & os, idx_type cell) const { int ret = 0; @@ -1808,7 +1907,8 @@ int LyXTabular::TeXCellPreamble(ostream & os, idx_type cell) const if (isMultiColumn(cell)) { os << "\\multicolumn{" << cells_in_multicolumn(cell) << "}{"; if (!cellinfo_of_cell(cell).align_special.empty()) { - os << cellinfo_of_cell(cell).align_special << "}{"; + os << from_ascii(cellinfo_of_cell(cell).align_special) + << "}{"; } else { if (leftLine(cell) && (isFirstCellInRow(cell) || @@ -1830,7 +1930,7 @@ int LyXTabular::TeXCellPreamble(ostream & os, idx_type cell) const break; } os << '{' - << getPWidth(cell).asLatexString() + << from_ascii(getPWidth(cell).asLatexString()) << '}'; } else { switch (getAlignment(cell)) { @@ -1866,7 +1966,8 @@ int LyXTabular::TeXCellPreamble(ostream & os, idx_type cell) const os << 'b'; break; } - os << "]{" << getPWidth(cell).asLatexString() << "}{"; + os << "]{" << from_ascii(getPWidth(cell).asLatexString()) + << "}{"; } else if (getUsebox(cell) == BOX_MINIPAGE) { os << "\\begin{minipage}["; switch (getVAlignment(cell)) { @@ -1880,14 +1981,15 @@ int LyXTabular::TeXCellPreamble(ostream & os, idx_type cell) const os << 'b'; break; } - os << "]{" << getPWidth(cell).asLatexString() << "}\n"; + os << "]{" << from_ascii(getPWidth(cell).asLatexString()) + << "}\n"; ++ret; } return ret; } -int LyXTabular::TeXCellPostamble(ostream & os, idx_type cell) const +int LyXTabular::TeXCellPostamble(odocstream & os, idx_type cell) const { int ret = 0; @@ -1909,7 +2011,7 @@ int LyXTabular::TeXCellPostamble(ostream & os, idx_type cell) const } -int LyXTabular::TeXLongtableHeaderFooter(ostream & os, Buffer const & buf, +int LyXTabular::TeXLongtableHeaderFooter(odocstream & os, Buffer const & buf, OutputParams const & runparams) const { if (!is_long_tabular) @@ -2009,12 +2111,29 @@ bool LyXTabular::isValidRow(row_type row) const } -int LyXTabular::TeXRow(ostream & os, row_type i, Buffer const & buf, +int LyXTabular::TeXRow(odocstream & os, row_type i, Buffer const & buf, OutputParams const & runparams) const { idx_type cell = getCellNumber(i, 0); - int ret = TeXTopHLine(os, i); + if (row_info[i].top_space_default) { + if (use_booktabs) + os << "\\addlinespace\n"; + else + os << "\\noalign{\\vskip\\doublerulesep}\n"; + } else if(!row_info[i].top_space.zero()) { + if (use_booktabs) + os << "\\addlinespace[" + << from_ascii(row_info[i].top_space.asLatexString()) + << "]\n"; + else { + os << "\\noalign{\\vskip" + << from_ascii(row_info[i].top_space.asLatexString()) + << "}\n"; + } + ++ret; + } + for (col_type j = 0; j < columns_; ++j) { if (isPartOfMultiColumn(i, j)) continue; @@ -2034,19 +2153,47 @@ int LyXTabular::TeXRow(ostream & os, row_type i, Buffer const & buf, ret += TeXCellPostamble(os, cell); if (!isLastCellInRow(cell)) { // not last cell in row - os << "&\n"; - ++ret; + os << " & "; } ++cell; } - os << "\\tabularnewline\n"; + os << "\\tabularnewline"; + if (row_info[i].bottom_space_default) { + if (use_booktabs) + os << "\\addlinespace"; + else + os << "[\\doublerulesep]"; + } else if (!row_info[i].bottom_space.zero()) { + if (use_booktabs) + os << "\\addlinespace"; + os << '[' + << from_ascii(row_info[i].bottom_space.asLatexString()) + << ']'; + } + os << '\n'; ++ret; ret += TeXBottomHLine(os, i); + if (row_info[i].interline_space_default) { + if (use_booktabs) + os << "\\addlinespace\n"; + else + os << "\\noalign{\\vskip\\doublerulesep}\n"; + } else if (!row_info[i].interline_space.zero()) { + if (use_booktabs) + os << "\\addlinespace[" + << from_ascii(row_info[i].interline_space.asLatexString()) + << "]\n"; + else + os << "\\noalign{\\vskip" + << from_ascii(row_info[i].interline_space.asLatexString()) + << "}\n"; + ++ret; + } return ret; } -int LyXTabular::latex(Buffer const & buf, ostream & os, +int LyXTabular::latex(Buffer const & buf, odocstream & os, OutputParams const & runparams) const { int ret = 0; @@ -2065,9 +2212,9 @@ int LyXTabular::latex(Buffer const & buf, ostream & os, os << "\\begin{tabular}{"; for (col_type i = 0; i < columns_; ++i) { if (!column_info[i].align_special.empty()) { - os << column_info[i].align_special; + os << from_ascii(column_info[i].align_special); } else { - if (column_info[i].left_line) + if (!use_booktabs && column_info[i].left_line) os << '|'; if (!column_info[i].p_width.zero()) { switch (column_info[i].alignment) { @@ -2099,7 +2246,7 @@ int LyXTabular::latex(Buffer const & buf, ostream & os, break; } os << '{' - << column_info[i].p_width.asLatexString() + << from_ascii(column_info[i].p_width.asLatexString()) << '}'; } else { switch (column_info[i].alignment) { @@ -2114,7 +2261,7 @@ int LyXTabular::latex(Buffer const & buf, ostream & os, break; } } - if (column_info[i].right_line) + if (!use_booktabs && column_info[i].right_line) os << '|'; } } @@ -2154,49 +2301,7 @@ int LyXTabular::latex(Buffer const & buf, ostream & os, } -int LyXTabular::linuxdoc(Buffer const & buf, ostream & os, - const OutputParams & runparams) const -{ - os << "\n"; - idx_type cell = 0; - int ret = 0; - for (row_type i = 0; i < rows_; ++i) { - for (col_type j = 0; j < columns_; ++j) { - if (isPartOfMultiColumn(i, j)) - continue; - shared_ptr inset = getCellInset(cell); - - ret += inset->linuxdoc(buf, os, runparams); - - if (isLastCellInRow(cell)) { - os << "@\n"; - ++ret; - } else { - os << "|"; - } - ++cell; - } - } - os << "\n"; - return ret; -} - - -int LyXTabular::docbookRow(Buffer const & buf, ostream & os, row_type row, +int LyXTabular::docbookRow(Buffer const & buf, odocstream & os, row_type row, OutputParams const & runparams) const { int ret = 0; @@ -2248,7 +2353,7 @@ int LyXTabular::docbookRow(Buffer const & buf, ostream & os, row_type row, } -int LyXTabular::docbook(Buffer const & buf, ostream & os, +int LyXTabular::docbook(Buffer const & buf, odocstream & os, OutputParams const & runparams) const { int ret = 0; @@ -2333,7 +2438,7 @@ int LyXTabular::docbook(Buffer const & buf, ostream & os, } -int LyXTabular::asciiTopHLine(ostream & os, row_type row, +int LyXTabular::asciiTopHLine(odocstream & os, row_type row, vector const & clen) const { idx_type const fcell = getFirstCellInRow(row); @@ -2349,7 +2454,7 @@ int LyXTabular::asciiTopHLine(ostream & os, row_type row, if (!tmp) return 0; - unsigned char ch; + char_type ch; for (idx_type i = fcell; i < n; ++i) { if (topLine(i)) { if (leftLine(i)) @@ -2366,7 +2471,7 @@ int LyXTabular::asciiTopHLine(ostream & os, row_type row, while (column < columns_ - 1 && isPartOfMultiColumn(row, ++column)) len += clen[column] + 4; - os << string(len, ch); + os << docstring(len, ch); if (topLine(i)) { if (rightLine(i)) os << "-+"; @@ -2381,7 +2486,7 @@ int LyXTabular::asciiTopHLine(ostream & os, row_type row, } -int LyXTabular::asciiBottomHLine(ostream & os, row_type row, +int LyXTabular::asciiBottomHLine(odocstream & os, row_type row, vector const & clen) const { idx_type const fcell = getFirstCellInRow(row); @@ -2397,7 +2502,7 @@ int LyXTabular::asciiBottomHLine(ostream & os, row_type row, if (!tmp) return 0; - unsigned char ch; + char_type ch; for (idx_type i = fcell; i < n; ++i) { if (bottomLine(i)) { if (leftLine(i)) @@ -2414,7 +2519,7 @@ int LyXTabular::asciiBottomHLine(ostream & os, row_type row, while (column < columns_ -1 && isPartOfMultiColumn(row, ++column)) len += clen[column] + 4; - os << string(len, ch); + os << docstring(len, ch); if (bottomLine(i)) { if (rightLine(i)) os << "-+"; @@ -2429,13 +2534,13 @@ int LyXTabular::asciiBottomHLine(ostream & os, row_type row, } -int LyXTabular::asciiPrintCell(Buffer const & buf, ostream & os, +int LyXTabular::asciiPrintCell(Buffer const & buf, odocstream & os, OutputParams const & runparams, idx_type cell, row_type row, col_type column, vector const & clen, bool onlydata) const { - ostringstream sstr; + odocstringstream sstr; int const ret = getCellInset(cell)->plaintext(buf, sstr, runparams); if (onlydata) { @@ -2470,7 +2575,8 @@ int LyXTabular::asciiPrintCell(Buffer const & buf, ostream & os, break; } - os << string(len1, ' ') << sstr.str() << string(len2, ' '); + os << docstring(len1, ' ') << sstr.str() + << docstring(len2, ' '); if (rightLine(cell)) os << " |"; @@ -2481,7 +2587,7 @@ int LyXTabular::asciiPrintCell(Buffer const & buf, ostream & os, } -int LyXTabular::plaintext(Buffer const & buf, ostream & os, +int LyXTabular::plaintext(Buffer const & buf, odocstream & os, OutputParams const & runparams, int const depth, bool onlydata, unsigned char delim) const @@ -2499,7 +2605,7 @@ int LyXTabular::plaintext(Buffer const & buf, ostream & os, idx_type cell = getCellNumber(i, j); if (isMultiColumnReal(cell)) continue; - ostringstream sstr; + odocstringstream sstr; getCellInset(cell)->plaintext(buf, sstr, runparams); if (clen[j] < sstr.str().length()) clen[j] = sstr.str().length(); @@ -2511,7 +2617,7 @@ int LyXTabular::plaintext(Buffer const & buf, ostream & os, idx_type cell = getCellNumber(i, j); if (!isMultiColumnReal(cell) || isPartOfMultiColumn(i, j)) continue; - ostringstream sstr; + odocstringstream sstr; getCellInset(cell)->plaintext(buf, sstr, runparams); int len = int(sstr.str().length()); idx_type const n = cells_in_multicolumn(cell); @@ -2525,7 +2631,7 @@ int LyXTabular::plaintext(Buffer const & buf, ostream & os, idx_type cell = 0; for (row_type i = 0; i < rows_; ++i) { if (!onlydata && asciiTopHLine(os, i, clen)) - os << string(depth * 2, ' '); + os << docstring(depth * 2, ' '); for (col_type j = 0; j < columns_; ++j) { if (isPartOfMultiColumn(i, j)) continue; @@ -2537,9 +2643,9 @@ int LyXTabular::plaintext(Buffer const & buf, ostream & os, } os << endl; if (!onlydata) { - os << string(depth * 2, ' '); + os << docstring(depth * 2, ' '); if (asciiBottomHLine(os, i, clen)) - os << string(depth * 2, ' '); + os << docstring(depth * 2, ' '); } } return ret; @@ -2553,7 +2659,7 @@ shared_ptr LyXTabular::getCellInset(idx_type cell) const shared_ptr LyXTabular::getCellInset(row_type row, - col_type column) const + col_type column) const { return cell_info[row][column].inset; } @@ -2594,6 +2700,8 @@ LyXTabular::getCellFromInset(InsetBase const * inset) const void LyXTabular::validate(LaTeXFeatures & features) const { features.require("NeedTabularnewline"); + if (useBookTabs()) + features.require("booktabs"); if (isLongTabular()) features.require("longtable"); if (needRotating()) @@ -2607,15 +2715,6 @@ void LyXTabular::validate(LaTeXFeatures & features) const } -void LyXTabular::getLabelList(Buffer const & buffer, - std::vector & list) const -{ - for (row_type i = 0; i < rows_; ++i) - for (col_type j = 0; j < columns_; ++j) - getCellInset(i, j)->getLabelList(buffer, list); -} - - LyXTabular::BoxType LyXTabular::useParbox(idx_type cell) const { ParagraphList const & parlist = getCellInset(cell)->paragraphs(); @@ -2629,3 +2728,6 @@ LyXTabular::BoxType LyXTabular::useParbox(idx_type cell) const return BOX_NONE; } + + +} // namespace lyx