X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetTabular.cpp;h=f9503c7124d8e23bff0629da8dbffb019d3d02ee;hb=6e4e0869006aa4c225162164aaa14a70d041facf;hp=e83c895b546b2d1855a71976acd3183a426a70df;hpb=e2fa3cb6ef0e65704402570d56086deca7643828;p=lyx.git diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index e83c895b54..f9503c7124 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -33,6 +33,7 @@ #include "DispatchResult.h" #include "FuncRequest.h" #include "FuncStatus.h" +#include "InsetIterator.h" #include "InsetList.h" #include "Language.h" #include "LaTeXFeatures.h" @@ -66,6 +67,7 @@ #include "support/unique_ptr.h" #include +#include #include #include #include @@ -543,7 +545,7 @@ InsetTableCell splitCell(InsetTableCell & head, docstring const & align_d, bool { InsetTableCell tail = InsetTableCell(head); DocIterator const dit = separatorPos(&head, align_d); - hassep = dit; + hassep = (bool)dit; if (hassep) { pit_type const psize = head.paragraphs().front().size(); head.paragraphs().front().eraseChars(dit.pos(), psize, false); @@ -877,8 +879,8 @@ void Tabular::insertColumn(col_type const col, bool copy) setBottomLine(i, bottomLine(j)); setTopLine(i, topLine(j)); setLeftLine(i, leftLine(j)); + setRightLine(i, rightLine(j)); if (rightLine(i) && rightLine(j)) { - setRightLine(i, true); setRightLine(j, false); } if (buffer().params().track_changes) @@ -1033,7 +1035,7 @@ bool Tabular::updateColumnWidths() idx_type const i = cellIndex(r, c); if (columnSpan(i) == 1) { if (getAlignment(i) == LYX_ALIGN_DECIMAL - && cell_info[r][c].decimal_width!=0) + && cell_info[r][c].decimal_width != 0) new_width = max(new_width, cellInfo(i).width + max_dwidth[c] - cellInfo(i).decimal_width); else @@ -1145,7 +1147,7 @@ void toggleFixedWidth(Cursor & cur, InsetTableCell * inset, bool fixedWidth) cur.pop(); } -} +} // namespace void Tabular::setColumnPWidth(Cursor & cur, idx_type cell, @@ -1859,7 +1861,7 @@ int Tabular::getRotateCell(idx_type cell) const bool Tabular::needRotating() const { - if (rotate) + if (rotate && !is_long_tabular) return true; for (row_type r = 0; r < nrows(); ++r) for (col_type c = 0; c < ncols(); ++c) @@ -2651,6 +2653,17 @@ void Tabular::TeXRow(otexstream & os, row_type row, tail.setMacrocontextPositionRecursive(dit); tail.latex(os, newrp); } + } else if (ltCaption(row)) { + // Inside longtable caption rows, we must only output the caption inset + // with its content and omit anything outside of that (see #10791) + InsetIterator it = inset_iterator_begin(*const_cast(inset)); + InsetIterator i_end = inset_iterator_end(*const_cast(inset)); + for (; it != i_end; ++it) { + if (it->lyxCode() != CAPTION_CODE) + continue; + it->latex(os, runparams); + break; + } } else if (!isPartOfMultiRow(row, c)) { if (!runparams.nice) os.texrow().start(par.id(), 0); @@ -2708,7 +2721,7 @@ void Tabular::TeXRow(otexstream & os, row_type row, void Tabular::latex(otexstream & os, OutputParams const & runparams) const { bool const is_tabular_star = !tabular_width.zero(); - RowEntry pos = TexRow::textEntry(runparams.lastid, runparams.lastpos); + TexRow::RowEntry pos = TexRow::textEntry(runparams.lastid, runparams.lastpos); //+--------------------------------------------------------------------- //+ first the opening preamble + @@ -2718,7 +2731,7 @@ void Tabular::latex(otexstream & os, OutputParams const & runparams) const if (!TexRow::isNone(pos)) os.texrow().start(pos); - if (rotate != 0) + if (rotate != 0 && !is_long_tabular) os << "\\begin{turn}{" << convert(rotate) << "}\n"; if (is_long_tabular) { @@ -2762,6 +2775,7 @@ void Tabular::latex(otexstream & os, OutputParams const & runparams) const os << column_info[c].align_special; } else { if (!column_info[c].p_width.zero()) { + bool decimal = false; switch (column_info[c].alignment) { case LYX_ALIGN_LEFT: os << ">{\\raggedright}"; @@ -2776,24 +2790,49 @@ void Tabular::latex(otexstream & os, OutputParams const & runparams) const case LYX_ALIGN_BLOCK: case LYX_ALIGN_LAYOUT: case LYX_ALIGN_SPECIAL: + break; case LYX_ALIGN_DECIMAL: + os << ">{\\raggedleft}"; + decimal = true; break; } + char valign = 'p'; switch (column_info[c].valignment) { case LYX_VALIGN_TOP: - os << 'p'; + // this is the default break; case LYX_VALIGN_MIDDLE: - os << 'm'; + valign = 'm'; break; case LYX_VALIGN_BOTTOM: - os << 'b'; + valign = 'b'; break; - } - os << '{' - << from_ascii(column_info[c].p_width.asLatexString()) - << '}'; + } + os << valign; + + // Fixed-width cells with alignment at decimal separator + // are output as two cells of half the width with the decimal + // separator as column sep. This effectively puts the content + // centered, which differs from the normal decimal sep alignment + // and is not ideal, but we cannot do better ATM (see #9568). + // FIXME: Implement proper decimal sep alignment, e.g. via siunitx. + if (decimal) { + docstring const halffixedwith = + from_ascii(Length(column_info[c].p_width.value() / 2, + column_info[c].p_width.unit()).asLatexString()); + os << '{' + << halffixedwith + << '}' + << "@{\\extracolsep{0pt}" << column_info[c].decimal_point << "}" + << valign + << '{' + << halffixedwith + << '}'; + } else + os << '{' + << from_ascii(column_info[c].p_width.asLatexString()) + << '}'; } else { switch (column_info[c].alignment) { case LYX_ALIGN_LEFT: @@ -2843,7 +2882,7 @@ void Tabular::latex(otexstream & os, OutputParams const & runparams) const os << "\\end{tabular}"; } - if (rotate != 0) + if (rotate != 0 && !is_long_tabular) os << breakln << "\\end{turn}"; if (!TexRow::isNone(pos)) @@ -3015,13 +3054,13 @@ docstring Tabular::xhtmlRow(XHTMLStream & xs, row_type row, continue; stringstream attr; - + Length const cwidth = column_info[c].p_width; if (!cwidth.zero()) { string const hwidth = cwidth.asHTMLString(); attr << "style =\"width: " << hwidth << ";\" "; } - + attr << "align='"; switch (getAlignment(cell)) { case LYX_ALIGN_LEFT: @@ -3397,7 +3436,16 @@ void Tabular::validate(LaTeXFeatures & features) const if (getVAlignment(cell) != LYX_VALIGN_TOP || !getPWidth(cell).zero()) features.require("array"); + // Tell footnote that we need a savenote + // environment in non-long tables or + // longtable headers/footers + else if (!is_long_tabular && !features.inFloat()) + features.saveNoteEnv("tabular"); + else if (!isValidRow(cellRow(cell))) + features.saveNoteEnv("longtable"); + cellInset(cell)->validate(features); + features.saveNoteEnv(string()); } } @@ -3484,9 +3532,9 @@ docstring InsetTableCell::asString(bool intoInsets) void InsetTableCell::addToToc(DocIterator const & di, bool output_active, - UpdateType utype) const + UpdateType utype, TocBackend & backend) const { - InsetText::iterateForToc(di, output_active, utype); + InsetText::iterateForToc(di, output_active, utype, backend); } @@ -3642,7 +3690,7 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const MetricsInfo m = mi; Length const p_width = tabular.getPWidth(cell); if (!p_width.zero()) - m.base.textwidth = p_width.inPixels(mi.base); + m.base.textwidth = mi.base.inPixels(p_width); tabular.cellInset(cell)->metrics(m, dim); if (!p_width.zero()) dim.wid = m.base.textwidth; @@ -3702,12 +3750,12 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const maxdes = max(maxdes, dim.des + offset); } int const top_space = tabular.row_info[r].top_space_default ? - default_line_space : - tabular.row_info[r].top_space.inPixels(mi.base); + default_line_space : + mi.base.inPixels(tabular.row_info[r].top_space); tabular.setRowAscent(r, maxasc + ADD_TO_HEIGHT + top_space); int const bottom_space = tabular.row_info[r].bottom_space_default ? - default_line_space : - tabular.row_info[r].bottom_space.inPixels(mi.base); + default_line_space : + mi.base.inPixels(tabular.row_info[r].bottom_space); tabular.setRowDescent(r, maxdes + ADD_TO_HEIGHT + bottom_space); } @@ -3955,13 +4003,13 @@ void InsetTabular::updateBuffer(ParIterator const & it, UpdateType utype) void InsetTabular::addToToc(DocIterator const & cpit, bool output_active, - UpdateType utype) const + UpdateType utype, TocBackend & backend) const { DocIterator dit = cpit; dit.forwardPos(); size_t const end = dit.nargs(); for ( ; dit.idx() < end; dit.top().forwardIdx()) - cell(dit.idx())->addToToc(dit, output_active, utype); + cell(dit.idx())->addToToc(dit, output_active, utype, backend); } @@ -4432,6 +4480,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) case LFUN_FONT_SIZE: case LFUN_FONT_UNDERLINE: case LFUN_FONT_STRIKEOUT: + case LFUN_FONT_CROSSOUT: case LFUN_FONT_UNDERUNDERLINE: case LFUN_FONT_UNDERWAVE: case LFUN_LANGUAGE: @@ -4648,12 +4697,14 @@ bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s, // therefore allow always left but right and center only if there is no width case Tabular::M_ALIGN_LEFT: flag = false; + // fall through case Tabular::ALIGN_LEFT: status.setOnOff(tabular.getAlignment(cur.idx(), flag) == LYX_ALIGN_LEFT); break; case Tabular::M_ALIGN_RIGHT: flag = false; + // fall through case Tabular::ALIGN_RIGHT: status.setEnabled(!(tabular.isMultiRow(cur.idx()) && !tabular.getPWidth(cur.idx()).zero())); @@ -4662,6 +4713,7 @@ bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s, case Tabular::M_ALIGN_CENTER: flag = false; + // fall through case Tabular::ALIGN_CENTER: status.setEnabled(!(tabular.isMultiRow(cur.idx()) && !tabular.getPWidth(cur.idx()).zero())); @@ -4682,6 +4734,7 @@ bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s, case Tabular::M_VALIGN_TOP: flag = false; + // fall through case Tabular::VALIGN_TOP: status.setEnabled(!tabular.getPWidth(cur.idx()).zero() && !tabular.isMultiRow(cur.idx())); @@ -4691,6 +4744,7 @@ bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s, case Tabular::M_VALIGN_BOTTOM: flag = false; + // fall through case Tabular::VALIGN_BOTTOM: status.setEnabled(!tabular.getPWidth(cur.idx()).zero() && !tabular.isMultiRow(cur.idx())); @@ -4700,6 +4754,7 @@ bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s, case Tabular::M_VALIGN_MIDDLE: flag = false; + // fall through case Tabular::VALIGN_MIDDLE: status.setEnabled(!tabular.getPWidth(cur.idx()).zero() && !tabular.isMultiRow(cur.idx())); @@ -4903,7 +4958,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, if (&cur.inset() != this) break; string action = cmd.getArg(0); - string arg = cmd.getLongArg(1); + string arg = cmd.getLongArg(1); return getFeatureStatus(cur, action, arg, status); } @@ -4978,7 +5033,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, status.setEnabled(false); return true; } - // Fall back + // fall through case LFUN_NEWLINE_INSERT: { if (tabular.getPWidth(cur.idx()).zero()) { status.setEnabled(false); @@ -5159,7 +5214,6 @@ int InsetTabular::dist(BufferView & bv, idx_type const cell, int x, int y) const Inset * InsetTabular::editXY(Cursor & cur, int x, int y) { //lyxerr << "InsetTabular::editXY: " << this << endl; - cur.selection(false); cur.push(*this); cur.idx() = getNearestCell(cur.bv(), x, y); return cur.bv().textMetrics(&cell(cur.idx())->text()).editXY(cur, x, y); @@ -5331,6 +5385,8 @@ void InsetTabular::tabularFeatures(Cursor & cur, string const & argument) cur.recordUndoInset(this); istringstream is(argument); + // limit the size of strings we read to avoid memory problems + is >> setw(65636); string s; // Safe guard. size_t safe_guard = 0; @@ -5631,6 +5687,7 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::M_VALIGN_BOTTOM: case Tabular::M_VALIGN_MIDDLE: flag = false; + // fall through case Tabular::VALIGN_TOP: case Tabular::VALIGN_BOTTOM: case Tabular::VALIGN_MIDDLE: @@ -5753,6 +5810,7 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::SET_ALL_LINES: setLines = true; + // fall through case Tabular::UNSET_ALL_LINES: for (row_type r = sel_row_start; r <= sel_row_end; ++r) for (col_type c = sel_col_start; c <= sel_col_end; ++c) { @@ -5877,6 +5935,7 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::UNSET_LTFIRSTHEAD: flag = false; + // fall through case Tabular::SET_LTFIRSTHEAD: tabular.getRowOfLTFirstHead(row, ltt); checkLongtableSpecial(ltt, value, flag); @@ -5885,6 +5944,7 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::UNSET_LTHEAD: flag = false; + // fall through case Tabular::SET_LTHEAD: tabular.getRowOfLTHead(row, ltt); checkLongtableSpecial(ltt, value, flag); @@ -5893,6 +5953,7 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::UNSET_LTFOOT: flag = false; + // fall through case Tabular::SET_LTFOOT: tabular.getRowOfLTFoot(row, ltt); checkLongtableSpecial(ltt, value, flag); @@ -5901,6 +5962,7 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::UNSET_LTLASTFOOT: flag = false; + // fall through case Tabular::SET_LTLASTFOOT: tabular.getRowOfLTLastFoot(row, ltt); checkLongtableSpecial(ltt, value, flag); @@ -5909,6 +5971,7 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::UNSET_LTNEWPAGE: flag = false; + // fall through case Tabular::SET_LTNEWPAGE: tabular.setLTNewPage(row, flag); break; @@ -6111,6 +6174,7 @@ bool InsetTabular::pasteClipboard(Cursor & cur) inset->setChange(Change(buffer().params().track_changes ? Change::INSERTED : Change::UNCHANGED)); cur.pos() = 0; + cur.pit() = 0; } } return true;