From 0ebe0ff37ef48aba4dae19b6d39c9c891a183de6 Mon Sep 17 00:00:00 2001 From: Edwin Leuven Date: Sat, 5 Jun 2010 07:44:44 +0000 Subject: [PATCH] add support for decimal alignment in tables git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@34598 a592a061-630c-0410-9148-cb99ea01b6c8 --- lib/images/tabular-feature_align-decimal.png | Bin 0 -> 1255 bytes lib/lyx2lyx/lyx_2_0.py | 23 +- lib/ui/stdtoolbars.inc | 1 + src/Buffer.cpp | 2 +- src/LayoutEnums.h | 4 +- src/LyXRC.cpp | 13 + src/LyXRC.h | 3 + src/frontends/qt4/GuiPrefs.cpp | 4 + src/frontends/qt4/GuiTabular.cpp | 113 ++++---- src/frontends/qt4/ui/PrefLanguageUi.ui | 57 +++- src/frontends/qt4/ui/TabularUi.ui | 135 ++++++--- src/insets/InsetTabular.cpp | 289 +++++++++++++++---- src/insets/InsetTabular.h | 15 +- 13 files changed, 488 insertions(+), 171 deletions(-) create mode 100644 lib/images/tabular-feature_align-decimal.png diff --git a/lib/images/tabular-feature_align-decimal.png b/lib/images/tabular-feature_align-decimal.png new file mode 100644 index 0000000000000000000000000000000000000000..f627fdbea7859a2c06f4257b5b755208f6672bce GIT binary patch literal 1255 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQaEa{HEjtmSN`?>!lvNA9*GX(gA zxB|uh|NjppN5NRR|O^k_7YEDSN5B%g1qL& z|JHNu0SZZ$xJHx&=ckpFCl;kL1SDqWmFW4ohA5O7>zV4AdUpMJ0954X>Ealo5j=MS zBNu}L2lMs+^0|5jzPw7z3yYshEYXZn2 DepClean; typedef map > RefCache; diff --git a/src/LayoutEnums.h b/src/LayoutEnums.h index d24302c494..5c02d8ed0a 100644 --- a/src/LayoutEnums.h +++ b/src/LayoutEnums.h @@ -59,7 +59,9 @@ enum LyXAlignment { /// LYX_ALIGN_LAYOUT = 16, /// - LYX_ALIGN_SPECIAL = 32 + LYX_ALIGN_SPECIAL = 32, + /// + LYX_ALIGN_DECIMAL = 64 }; /// diff --git a/src/LyXRC.cpp b/src/LyXRC.cpp index a717a6b84e..67ba6780d4 100644 --- a/src/LyXRC.cpp +++ b/src/LyXRC.cpp @@ -84,6 +84,7 @@ LexerKeyword lyxrcTags[] = { { "\\cursor_follows_scrollbar", LyXRC::RC_CURSOR_FOLLOWS_SCROLLBAR }, { "\\date_insert_format", LyXRC::RC_DATE_INSERT_FORMAT }, { "\\def_file", LyXRC::RC_DEFFILE }, + { "\\default_decimal_point", LyXRC::RC_DEFAULT_DECIMAL_POINT }, { "\\default_language", LyXRC::RC_DEFAULT_LANGUAGE }, { "\\default_papersize", LyXRC::RC_DEFAULT_PAPERSIZE }, { "\\default_view_format", LyXRC::RC_DEFAULT_VIEW_FORMAT }, @@ -352,6 +353,7 @@ void LyXRC::setDefaults() completion_inline_text = false; completion_inline_dots = -1; completion_inline_delay = 0.2; + default_decimal_point = "."; } @@ -939,6 +941,9 @@ int LyXRC::read(Lexer & lexrc) backupdir_path = expandPath(backupdir_path); } break; + case RC_DEFAULT_DECIMAL_POINT: + lexrc >> default_decimal_point; + break; case RC_DATE_INSERT_FORMAT: lexrc >> date_insert_format; break; @@ -2380,6 +2385,14 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c if (tag != RC_LAST) break; + case RC_DEFAULT_DECIMAL_POINT: + if (ignore_system_lyxrc || + default_decimal_point != system_lyxrc.default_decimal_point) { + os << "\\default_decimal_point " << default_decimal_point << '\n'; + } + if (tag != RC_LAST) + break; + case RC_SPELLCHECKER: if (ignore_system_lyxrc || spellchecker != system_lyxrc.spellchecker) { diff --git a/src/LyXRC.h b/src/LyXRC.h index 4ec4d2aeef..823dc15f74 100644 --- a/src/LyXRC.h +++ b/src/LyXRC.h @@ -66,6 +66,7 @@ public: RC_COPIER, RC_CURSOR_FOLLOWS_SCROLLBAR, RC_DATE_INSERT_FORMAT, + RC_DEFAULT_DECIMAL_POINT, RC_DEFAULT_LANGUAGE, RC_DEFAULT_VIEW_FORMAT, RC_DEFAULT_PAPERSIZE, @@ -499,6 +500,8 @@ public: std::string forward_search_pdf; /// int export_overwrite; + /// Default decimal point when aligning table columns on decimal + std::string default_decimal_point; }; diff --git a/src/frontends/qt4/GuiPrefs.cpp b/src/frontends/qt4/GuiPrefs.cpp index 1831d8a8cc..d8f1504b4f 100644 --- a/src/frontends/qt4/GuiPrefs.cpp +++ b/src/frontends/qt4/GuiPrefs.cpp @@ -2070,6 +2070,8 @@ PrefLanguage::PrefLanguage(GuiPreferences * form) this, SIGNAL(changed())); connect(uiLanguageCO, SIGNAL(activated(int)), this, SIGNAL(changed())); + connect(defaultDecimalPointLE, SIGNAL(textChanged(QString)), + this, SIGNAL(changed())); uiLanguageCO->clear(); @@ -2113,6 +2115,7 @@ void PrefLanguage::apply(LyXRC & rc) const rc.language_command_end = fromqstr(endCommandED->text()); rc.gui_language = fromqstr( uiLanguageCO->itemData(uiLanguageCO->currentIndex()).toString()); + rc.default_decimal_point = fromqstr(defaultDecimalPointLE->text()); } @@ -2132,6 +2135,7 @@ void PrefLanguage::update(LyXRC const & rc) languagePackageED->setText(toqstr(rc.language_package)); startCommandED->setText(toqstr(rc.language_command_begin)); endCommandED->setText(toqstr(rc.language_command_end)); + defaultDecimalPointLE->setText(toqstr(rc.default_decimal_point)); int pos = uiLanguageCO->findData(toqstr(rc.gui_language)); uiLanguageCO->blockSignals(true); diff --git a/src/frontends/qt4/GuiTabular.cpp b/src/frontends/qt4/GuiTabular.cpp index 77ec768a57..2c7051441d 100644 --- a/src/frontends/qt4/GuiTabular.cpp +++ b/src/frontends/qt4/GuiTabular.cpp @@ -27,6 +27,7 @@ #include "FuncRequest.h" #include "FuncStatus.h" #include "LyX.h" +#include "LyXRC.h" #include "insets/InsetTabular.h" @@ -159,6 +160,10 @@ GuiTabular::GuiTabular(QWidget * parent) void GuiTabular::checkEnabled() { hAlignCB->setEnabled(true); + bool dalign = hAlignCB->currentText() == QString("Decimal"); + decimalPointLE->setEnabled(dalign); + decimalL->setEnabled(dalign); + vAlignCB->setEnabled(!multirowCB->isChecked() && !widgetsToLength(widthED, widthUnitCB).empty()); @@ -271,38 +276,24 @@ static void setParam(string & param_str, Tabular::Feature f, string const & arg void GuiTabular::setHAlign(string & param_str) const { - int const align = hAlignCB->currentIndex(); - - enum HALIGN { LEFT, RIGHT, CENTER, BLOCK }; - HALIGN h = LEFT; - - switch (align) { - case 0: h = LEFT; break; - case 1: h = CENTER; break; - case 2: h = RIGHT; break; - case 3: h = BLOCK; break; - } - Tabular::Feature num = Tabular::ALIGN_LEFT; Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT; - - switch (h) { - case LEFT: - num = Tabular::ALIGN_LEFT; - multi_num = Tabular::M_ALIGN_LEFT; - break; - case CENTER: - num = Tabular::ALIGN_CENTER; - multi_num = Tabular::M_ALIGN_CENTER; - break; - case RIGHT: - num = Tabular::ALIGN_RIGHT; - multi_num = Tabular::M_ALIGN_RIGHT; - break; - case BLOCK: - num = Tabular::ALIGN_BLOCK; - //multi_num: no equivalent - break; + QString const align = hAlignCB->currentText(); + if (align == qt_("Left")) { + num = Tabular::ALIGN_LEFT; + multi_num = Tabular::M_ALIGN_LEFT; + } else if (align == qt_("Center")) { + num = Tabular::ALIGN_CENTER; + multi_num = Tabular::M_ALIGN_CENTER; + } else if (align == qt_("Right")) { + num = Tabular::ALIGN_RIGHT; + multi_num = Tabular::M_ALIGN_RIGHT; + } else if (align == qt_("Justified")) { + num = Tabular::ALIGN_BLOCK; + //multi_num: no equivalent + } else if (align == qt_("Decimal")) { + num = Tabular::ALIGN_DECIMAL; + //multi_num: no equivalent } if (multicolumnCB->isChecked()) @@ -367,6 +358,13 @@ docstring GuiTabular::dialogToParams() const // FIXME: We should use Tabular directly. string param_str = "tabular"; setHAlign(param_str); + + // SET_DECIMAL_POINT must come after setHAlign() (ALIGN_DECIMAL) + string decimal_point = fromqstr(decimalPointLE->text()); + if (decimal_point.empty()) + decimal_point = lyxrc.default_decimal_point; + setParam(param_str, Tabular::SET_DECIMAL_POINT, decimal_point); + setVAlign(param_str); setTableAlignment(param_str); // @@ -693,29 +691,43 @@ void GuiTabular::paramsToDialog(Inset const * inset) hAlignCB->addItem(qt_("Right")); if (!multicol && !pwidth.zero()) hAlignCB->addItem(qt_("Justified")); + if (!multicol) + hAlignCB->addItem(qt_("Decimal")); - int align = 0; + QString align; switch (tabular.getAlignment(cell)) { - case LYX_ALIGN_LEFT: - align = 0; - break; - case LYX_ALIGN_CENTER: - align = 1; - break; - case LYX_ALIGN_RIGHT: - align = 2; - break; - case LYX_ALIGN_BLOCK: - { - if (!multicol && !pwidth.zero()) - align = 3; - break; - } - default: - align = 0; - break; + case LYX_ALIGN_LEFT: + align = qt_("Left"); + break; + case LYX_ALIGN_CENTER: + align = qt_("Center"); + break; + case LYX_ALIGN_RIGHT: + align = qt_("Right"); + break; + case LYX_ALIGN_BLOCK: + { + if (!multicol && !pwidth.zero()) + align = qt_("Justified"); + break; + } + case LYX_ALIGN_DECIMAL: + { + if (!multicol) + align = qt_("Decimal"); + break; + } + default: + // we should never end up here + break; } - hAlignCB->setCurrentIndex(align); + hAlignCB->setCurrentIndex(hAlignCB->findText(align)); + + // + QString decimal_point = toqstr(tabular.column_info[col].decimal_point); + if (decimal_point.isEmpty()) + decimal_point = toqstr(from_utf8(lyxrc.default_decimal_point)); + decimalPointLE->setText(decimal_point); int valign = 0; switch (tabular.getVAlignment(cell)) { @@ -772,6 +784,7 @@ void GuiTabular::paramsToDialog(Inset const * inset) captionStatusCB->blockSignals(true); captionStatusCB->setChecked(false); captionStatusCB->blockSignals(false); + checkEnabled(); return; } else { // longtables cannot have a vertical alignment diff --git a/src/frontends/qt4/ui/PrefLanguageUi.ui b/src/frontends/qt4/ui/PrefLanguageUi.ui index 2305eb0996..a7e9a66004 100644 --- a/src/frontends/qt4/ui/PrefLanguageUi.ui +++ b/src/frontends/qt4/ui/PrefLanguageUi.ui @@ -43,14 +43,31 @@ - + Enter the command to load the language package (default: babel) - + + + + Command s&tart: + + + startCommandED + + + + + + + The LaTeX command that starts a switch to a foreign language + + + + Qt::Horizontal @@ -64,36 +81,45 @@ - + - Command s&tart: + Command e&nd: - startCommandED + endCommandED - + - The LaTeX command that starts a switch to a foreign language + The LaTeX command that ends a switch to a foreign language - + - Command e&nd: + Default Decimal &Point: - endCommandED + defaultDecimalPointLE - - - The LaTeX command that ends a switch to a foreign language + + + + 20 + 16777215 + + + + X; + + + Qt::AlignCenter @@ -244,14 +270,19 @@ + uiLanguageCO languagePackageED startCommandED endCommandED + defaultDecimalPointLE useBabelCB globalCB autoBeginCB autoEndCB markForeignCB + rtlGB + logicalCursorRB + visualCursorRB qt_i18n.h diff --git a/src/frontends/qt4/ui/TabularUi.ui b/src/frontends/qt4/ui/TabularUi.ui index 4b2516caa0..d9b55b2f3b 100644 --- a/src/frontends/qt4/ui/TabularUi.ui +++ b/src/frontends/qt4/ui/TabularUi.ui @@ -5,17 +5,20 @@ 0 0 - 374 - 389 + 358 + 376 - true + false - + + + 0 + @@ -73,23 +76,76 @@ Right + + + Decimal + + - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + false + + + Decimal point: + + + decimalPointLE + + + + + + + false + + + + 0 + 0 + + + + + 20 + 16777215 + + + + X; + + + + + + 1 + + + Qt::AlignCenter + + + + @@ -149,7 +205,7 @@ - + Qt::Horizontal @@ -309,19 +365,6 @@ - - - - Qt::Vertical - - - - 20 - 4 - - - - @@ -1420,43 +1463,49 @@ TabWidget hAlignCB + decimalPointLE widthED widthUnitCB vAlignCB multicolumnCB - rotateTabularCB multirowCB rotateCellCB + TableAlignCB + rotateTabularCB specialAlignmentED - borderSetPB - borderUnsetPB borderDefaultRB booktabsRB topspaceCO - bottomspaceCO - interlinespaceCO + bottomspaceUnit topspaceED + topspaceUnit + bottomspaceCO bottomspaceED interlinespaceED - topspaceUnit - bottomspaceUnit - interlinespaceUnit + interlinespaceCO longTabularCB + interlinespaceUnit headerStatusCB + firstheaderNoContentsCB headerBorderAboveCB headerBorderBelowCB firstheaderStatusCB firstheaderBorderAboveCB firstheaderBorderBelowCB - firstheaderNoContentsCB - footerStatusCB footerBorderAboveCB + footerStatusCB + newpageCB footerBorderBelowCB lastfooterStatusCB lastfooterBorderAboveCB lastfooterBorderBelowCB lastfooterNoContentsCB - newpageCB + captionStatusCB + leftRB + borderSetPB + centerRB + rightRB + borderUnsetPB qt_i18n.h diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index 77c1fa6365..0ae20f1246 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -125,6 +125,7 @@ TabularFeature tabularFeature[] = { Tabular::ALIGN_RIGHT, "align-right", false }, { Tabular::ALIGN_CENTER, "align-center", false }, { Tabular::ALIGN_BLOCK, "align-block", false }, + { Tabular::ALIGN_DECIMAL, "align-decimal", false }, { Tabular::VALIGN_TOP, "valign-top", false }, { Tabular::VALIGN_BOTTOM, "valign-bottom", false }, { Tabular::VALIGN_MIDDLE, "valign-middle", false }, @@ -174,6 +175,7 @@ TabularFeature tabularFeature[] = { Tabular::LONGTABULAR_ALIGN_LEFT, "longtabular-align-left", false }, { Tabular::LONGTABULAR_ALIGN_CENTER, "longtabular-align-center", false }, { Tabular::LONGTABULAR_ALIGN_RIGHT, "longtabular-align-right", false }, + { Tabular::SET_DECIMAL_POINT, "set-decimal-point", true }, { Tabular::LAST_ACTION, "", false } }; @@ -251,6 +253,8 @@ string const tostr(LyXAlignment const & num) return "layout"; case LYX_ALIGN_SPECIAL: return "special"; + case LYX_ALIGN_DECIMAL: + return "decimal"; } return string(); } @@ -311,6 +315,8 @@ bool string2type(string const str, LyXAlignment & num) num = LYX_ALIGN_CENTER; else if (str == "right") num = LYX_ALIGN_RIGHT; + else if (str == "decimal") + num = LYX_ALIGN_DECIMAL; else return false; return true; @@ -502,6 +508,30 @@ string const featureAsString(Tabular::Feature action) } +InsetTableCell splitCell(InsetTableCell & head, docstring const align_d, bool & hassep) +{ + InsetTableCell tail = InsetTableCell(head); + tail.getText(0)->setMacrocontextPosition( + head.getText(0)->macrocontextPosition()); + tail.setBuffer(head.buffer()); + + DocIterator dit = doc_iterator_begin(&head.buffer(), &head); + for (; dit; dit.forwardChar()) + if (dit.inTexted() && dit.depth()==1 + && dit.paragraph().find(align_d, false, false, dit.pos())) + break; + + pit_type const psize = head.paragraphs().front().size(); + hassep = dit; + if (hassep) + head.paragraphs().front().eraseChars(dit.pos(), psize, false); + + tail.paragraphs().front().eraseChars(0, + dit.pos() < psize ? dit.pos() + 1 : psize, false); + + return tail; +} + ///////////////////////////////////////////////////////////////////// // @@ -517,6 +547,8 @@ Tabular::CellData::CellData(Buffer * buf) multirow(Tabular::CELL_NORMAL), alignment(LYX_ALIGN_CENTER), valignment(LYX_VALIGN_TOP), + decimal_hoffset(0), + decimal_width(0), voffset(0), top_line(false), bottom_line(false), @@ -537,6 +569,8 @@ Tabular::CellData::CellData(CellData const & cs) multirow(cs.multirow), alignment(cs.alignment), valignment(cs.valignment), + decimal_hoffset(cs.decimal_hoffset), + decimal_width(cs.decimal_width), voffset(cs.voffset), top_line(cs.top_line), bottom_line(cs.bottom_line), @@ -564,6 +598,8 @@ void Tabular::CellData::swap(CellData & rhs) std::swap(multirow, rhs.multirow); std::swap(alignment, rhs.alignment); std::swap(valignment, rhs.valignment); + std::swap(decimal_hoffset, rhs.decimal_hoffset); + std::swap(decimal_width, rhs.decimal_width); std::swap(voffset, rhs.voffset); std::swap(top_line, rhs.top_line); std::swap(bottom_line, rhs.bottom_line); @@ -814,7 +850,8 @@ void Tabular::updateIndexes() rowofcell[i] = row; columnofcell[i] = column; setFixedWidth(row, column); - updateContentAlignment(row, column); + cell_info[row][column].inset->setContentAlignment( + getAlignment(cellIndex(row, column))); ++i; } } @@ -910,6 +947,14 @@ int Tabular::cellHeight(idx_type cell) const bool Tabular::updateColumnWidths() { + vector max_dwidth(ncols(), 0); + for(col_type c = 0; c < ncols(); ++c) + for(row_type r = 0; r < nrows(); ++r) { + idx_type const i = cellIndex(r, c); + if (getAlignment(i) == LYX_ALIGN_DECIMAL) + max_dwidth[c] = max(max_dwidth[c], cell_info[r][c].decimal_width); + } + bool update = false; // for each col get max of single col cells for(col_type c = 0; c < ncols(); ++c) { @@ -917,7 +962,11 @@ bool Tabular::updateColumnWidths() for(row_type r = 0; r < nrows(); ++r) { idx_type const i = cellIndex(r, c); if (columnSpan(i) == 1) - new_width = max(new_width, cellInfo(i).width); + if (getAlignment(i) == LYX_ALIGN_DECIMAL) + new_width = max(new_width, cellInfo(i).width + + max_dwidth[c] - cellInfo(i).decimal_width); + else + new_width = max(new_width, cellInfo(i).width); } if (column_info[c].width != new_width) { @@ -966,11 +1015,16 @@ void Tabular::setCellWidth(idx_type cell, int new_width) void Tabular::setAlignment(idx_type cell, LyXAlignment align, bool onlycolumn) { - if (!isMultiColumn(cell) || onlycolumn) - column_info[cellColumn(cell)].alignment = align; - if (!onlycolumn) + col_type const col = cellColumn(cell); + if (onlycolumn || !isMultiColumn(cell)) { + column_info[col].alignment = align; + docstring & dpoint = column_info[col].decimal_point; + if (align == LYX_ALIGN_DECIMAL && dpoint.empty()) + dpoint = from_utf8(lyxrc.default_decimal_point); + } else { cellInfo(cell).alignment = align; - cellInset(cell).get()->setContentAlignment(align); + cellInset(cell).get()->setContentAlignment(align); + } } @@ -1050,13 +1104,6 @@ bool Tabular::setFixedWidth(row_type r, col_type c) } -void Tabular::updateContentAlignment(row_type r, col_type c) -{ - cell_info[r][c].inset->setContentAlignment( - getAlignment(cellIndex(r, c))); -} - - bool Tabular::setMColumnPWidth(Cursor & cur, idx_type cell, Length const & width) { @@ -1170,8 +1217,9 @@ bool Tabular::columnRightLine(col_type c) const LyXAlignment Tabular::getAlignment(idx_type cell, bool onlycolumn) const { - if (!onlycolumn && isMultiColumn(cell)) + if (!onlycolumn && (isMultiColumn(cell) || isMultiRow(cell))) return cellInfo(cell).alignment; + return column_info[cellColumn(cell)].alignment; } @@ -1212,6 +1260,21 @@ int Tabular::textHOffset(idx_type cell) const x += columnWidth(cell) - cellWidth(cell); // + interColumnSpace(cell); break; + case LYX_ALIGN_DECIMAL: { + // we center when no decimal point + if (cellInfo(cell).decimal_width == 0) { + x += (columnWidth(cell) - cellWidth(cell)) / 2; + break; + } + col_type const c = cellColumn(cell); + int max_dhoffset = 0; + for(row_type r = 0; r < row_info.size() ; ++r) { + idx_type const i = cellIndex(r, c); + if (getAlignment(i) == LYX_ALIGN_DECIMAL) + max_dhoffset = max(max_dhoffset, cellInfo(i).decimal_hoffset); + } + x += max_dhoffset - cellInfo(cell).decimal_hoffset; + } default: // LYX_ALIGN_LEFT: nothing :-) break; @@ -1303,8 +1366,10 @@ void Tabular::write(ostream & os) const os << ">\n"; for (col_type c = 0; c < ncols(); ++c) { os << "\n"; @@ -1410,6 +1475,7 @@ void Tabular::read(Lexer & lex) return; } getTokenValue(line, "alignment", column_info[c].alignment); + getTokenValue(line, "decimal_point", column_info[c].decimal_point); getTokenValue(line, "valignment", column_info[c].valignment); getTokenValue(line, "width", column_info[c].p_width); getTokenValue(line, "special", column_info[c].align_special); @@ -1504,7 +1570,8 @@ Tabular::idx_type Tabular::setMultiColumn(idx_type cell, idx_type number) cell = cellIndex(row, col); CellData & cs = cellInfo(cell); cs.multicolumn = CELL_BEGIN_OF_MULTICOLUMN; - cs.alignment = column_info[col].alignment; + if (column_info[col].alignment != LYX_ALIGN_DECIMAL) + cs.alignment = column_info[col].alignment; if (col > 0) setRightLine(cell, rightLine(cellIndex(row, col - 1))); @@ -1544,7 +1611,7 @@ Tabular::idx_type Tabular::setMultiRow(idx_type cell, idx_type number) // change (assigning this to uwestoehr) // until LyX supports this, use the deault alignment of multirow // cells: left - cs.alignment = LYX_ALIGN_LEFT; + cs.alignment = LYX_ALIGN_CENTER; // set the bottom row of the last selected cell setBottomLine(cell, bottomLine(cell + (number - 1)*ncols())); @@ -1563,11 +1630,12 @@ Tabular::idx_type Tabular::setMultiRow(idx_type cell, idx_type number) Tabular::idx_type Tabular::columnSpan(idx_type cell) const { row_type const row = cellRow(cell); - col_type column = cellColumn(cell) + 1; - while (column < ncols() && isPartOfMultiColumn(row, column)) - ++column; + col_type const col = cellColumn(cell); + int span = 1; + while (col + span < ncols() && isPartOfMultiColumn(row, col + span)) + ++span; - return column - cellColumn(cell); + return span; } @@ -1936,20 +2004,29 @@ int Tabular::TeXTopHLine(odocstream & os, row_type row, string const lang) const } } else if (row == 0) { for (col_type c = 0; c < ncols(); ++c) { - if (topline[c]) { - //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 << (use_booktabs ? "\\expandafter\\cmidrule\\expandafter{\\expandafter" : - "\\expandafter\\cline\\expandafter{\\expandafter") - << c + 1 << "\\string-"; - else - os << (use_booktabs ? "\\cmidrule{" : "\\cline{") << c + 1 << '-'; - // get to last column of line span - while (c < ncols() && topline[c]) - ++c; - os << c << "} "; - } + for ( ; c < ncols() && !topline[c]; ++c) {} + + 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 << '-'; + + col_type cstart = c; + for ( ; c < ncols() && topline[c]; ++c) {} + + for (col_type j = cstart ; j < c ; ++j) + if (column_info[j].alignment == LYX_ALIGN_DECIMAL) + ++offset; + + os << c + offset << "} "; } } os << "\n"; @@ -2000,20 +2077,29 @@ int Tabular::TeXBottomHLine(odocstream & os, row_type row, string const lang) co os << "\\hline "; } else { for (col_type c = 0; c < ncols(); ++c) { - if (bottomline[c]) { - //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 << (use_booktabs ? "\\expandafter\\cmidrule\\expandafter{\\expandafter" : - "\\expandafter\\cline\\expandafter{\\expandafter") - << c + 1 << "\\string-"; - else - os << (use_booktabs ? "\\cmidrule{" : "\\cline{") << c + 1 << '-'; - // get to last column of line span - while (c < ncols() && bottomline[c]) - ++c; - os << c << "} "; - } + for ( ; c < ncols() && !bottomline[c]; ++c) {} + + 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 << '-'; + + col_type cstart = c; + for ( ; c < ncols() && bottomline[c]; ++c) {} + + for (col_type j = cstart ; j < c ; ++j) + if (column_info[j].alignment == LYX_ALIGN_DECIMAL) + ++offset; + + os << c + offset << "} "; } } os << "\n"; @@ -2048,8 +2134,19 @@ int Tabular::TeXCellPreamble(odocstream & os, idx_type cell, || ((colright || nextcolleft) && !rightLine(cell) && !nextcellleft) || (!colright && !nextcolleft && (rightLine(cell) || nextcellleft)) || (coldouble != celldouble); + + // we center in multicol when no decimal point + ismulticol |= ((column_info[c].alignment == LYX_ALIGN_DECIMAL) + && (cellInfo(cell).decimal_width == 0) || isMultiRow(cell)); + + // up counter by 1 for each decimally aligned col since they use 2 latex cols + int latexcolspan = columnSpan(cell); + for(col_type col = c; col < c + columnSpan(cell); ++col) + if (column_info[col].alignment == LYX_ALIGN_DECIMAL) + ++latexcolspan; + if (ismulticol) { - os << "\\multicolumn{" << columnSpan(cell) << "}{"; + os << "\\multicolumn{" << latexcolspan << "}{"; if (c ==0 && leftLine(cell)) os << '|'; if (!cellInfo(cell).align_special.empty()) { @@ -2103,7 +2200,7 @@ int Tabular::TeXCellPreamble(odocstream & os, idx_type cell, // add extra vertical line if we want a double one os << '|'; os << "}{"; - } // end if ismulticol + } // end if ismulticol // we only need code for the first multirow cell ismultirow = isMultiRow(cell); @@ -2116,7 +2213,7 @@ int Tabular::TeXCellPreamble(odocstream & os, idx_type cell, // needs to be discussed os << "*"; os << "}{"; - } // end if ismultirow + } // end if ismultirow if (getRotateCell(cell)) { os << "\\begin{sideways}\n"; @@ -2177,9 +2274,11 @@ int Tabular::TeXCellPostamble(odocstream & os, idx_type cell, os << "%\n\\end{sideways}"; ++ret; } - if (ismulticol || ismultirow) { + if (ismultirow) os << '}'; - } + if (ismulticol) + os << '}'; + return ret; } @@ -2328,10 +2427,15 @@ int Tabular::TeXRow(odocstream & os, row_type row, bool ismulticol = false; bool ismultirow = false; for (col_type c = 0; c < ncols(); ++c) { - if (isPartOfMultiRow(row, c)) - os << " & "; // we need to add a further column - if (isPartOfMultiColumn(row, c) || isPartOfMultiRow(row, c)) + if (isPartOfMultiColumn(row, c)) + continue; + + if (isPartOfMultiRow(row, c) && + column_info[c].alignment != LYX_ALIGN_DECIMAL) { + os << " & "; continue; + } + cell = cellIndex(row, c); ret += TeXCellPreamble(os, cell, ismulticol, ismultirow); shared_ptr inset = cellInset(cell); @@ -2360,7 +2464,22 @@ int Tabular::TeXRow(odocstream & os, row_type row, newrp.inTableCell = (getAlignment(cell) == LYX_ALIGN_BLOCK) ? OutputParams::PLAIN : OutputParams::ALIGNED; - ret += inset->latex(os, newrp); + + if (getAlignment(cell) == LYX_ALIGN_DECIMAL + && cellInfo(cell).decimal_width != 0 && !isMultiRow(cell)) { + // copy cell and split in 2 + InsetTableCell head = InsetTableCell(*cellInset(cell).get()); + head.getText(0)->setMacrocontextPosition( + cellInset(cell)->getText(0)->macrocontextPosition()); + head.setBuffer(buffer()); + bool hassep = false; + InsetTableCell tail = splitCell(head, column_info[c].decimal_point, hassep); + head.latex(os, newrp); + os << '&'; + ret += tail.latex(os, newrp); + } else if (!isPartOfMultiRow(row, c)) + ret += inset->latex(os, newrp); + runparams.encoding = newrp.encoding; if (rtl) os << '}'; @@ -2477,6 +2596,7 @@ int Tabular::latex(odocstream & os, OutputParams const & runparams) const case LYX_ALIGN_BLOCK: case LYX_ALIGN_LAYOUT: case LYX_ALIGN_SPECIAL: + case LYX_ALIGN_DECIMAL: break; } @@ -2502,6 +2622,9 @@ int Tabular::latex(odocstream & os, OutputParams const & runparams) const case LYX_ALIGN_RIGHT: os << 'r'; break; + case LYX_ALIGN_DECIMAL: + os << "r@{\\extracolsep{0pt}" << column_info[c].decimal_point << "}l"; + break; default: os << 'c'; break; @@ -3235,6 +3358,33 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const // FIXME(?): do we need a second metrics call? TextMetrics const & tm = mi.base.bv->textMetrics(tabular.cellInset(cell)->getText(0)); + + // determine horiz offset because of decimal align (if necessary) + int decimal_hoffset = 0; + int decimal_width = 0; + if ((tabular.column_info[c].alignment == LYX_ALIGN_DECIMAL) + && !tabular.isMultiColumn(cell) + && !tabular.isMultiRow(cell)) { + // make a copy which we will split in 2 + InsetTableCell head = InsetTableCell(*tabular.cellInset(cell).get()); + head.getText(0)->setMacrocontextPosition( + tabular.cellInset(cell)->getText(0)->macrocontextPosition()); + head.setBuffer(tabular.buffer()); + // split in 2 and calculate width of each part + bool hassep = false; + InsetTableCell tail = + splitCell(head, tabular.column_info[c].decimal_point, hassep); + Dimension dim1; + head.metrics(m, dim1); + decimal_hoffset = dim1.width(); + if (hassep) { + tail.metrics(m, dim1); + decimal_width = dim1.width(); + } + } + tabular.cell_info[r][c].decimal_hoffset = decimal_hoffset; + tabular.cell_info[r][c].decimal_width = decimal_width; + // with LYX_VALIGN_BOTTOM the descent is relative to the last par // = descent of text in last par + TEXT_TO_INSET_OFFSET: int const lastpardes = tm.last().second->descent() @@ -4040,6 +4190,11 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, status.clear(); return true; + case Tabular::SET_DECIMAL_POINT: + status.setEnabled( + tabular.getAlignment(cur.idx()) == LYX_ALIGN_DECIMAL); + break; + case Tabular::MULTICOLUMN: // If a row is set as longtable caption, it must not be allowed // to unset that this row is a multicolumn. @@ -4116,6 +4271,12 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, status.setOnOff(tabular.getAlignment(cur.idx(), flag) == LYX_ALIGN_BLOCK); break; + case Tabular::ALIGN_DECIMAL: + status.setEnabled(!tabular.isMultiRow(cur.idx()) + && !tabular.isMultiColumn(cur.idx())); + status.setOnOff(tabular.getAlignment(cur.idx(), true) == LYX_ALIGN_DECIMAL); + break; + case Tabular::M_VALIGN_TOP: flag = false; case Tabular::VALIGN_TOP: @@ -4810,6 +4971,10 @@ void InsetTabular::tabularFeatures(Cursor & cur, setAlign = LYX_ALIGN_BLOCK; break; + case Tabular::ALIGN_DECIMAL: + setAlign = LYX_ALIGN_DECIMAL; + break; + case Tabular::M_VALIGN_TOP: case Tabular::VALIGN_TOP: setVAlign = Tabular::LYX_VALIGN_TOP; @@ -4954,6 +5119,7 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::ALIGN_RIGHT: case Tabular::ALIGN_CENTER: case Tabular::ALIGN_BLOCK: + case Tabular::ALIGN_DECIMAL: 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.setAlignment(tabular.cellIndex(r, c), setAlign, flag); @@ -5245,6 +5411,11 @@ void InsetTabular::tabularFeatures(Cursor & cur, break; } + case Tabular::SET_DECIMAL_POINT: + for (col_type c = sel_col_start; c <= sel_col_end; ++c) + tabular.column_info[c].decimal_point = from_utf8(value); + break; + // dummy stuff just to avoid warnings case Tabular::LAST_ACTION: break; diff --git a/src/insets/InsetTabular.h b/src/insets/InsetTabular.h index e0c4326c4e..d529793016 100644 --- a/src/insets/InsetTabular.h +++ b/src/insets/InsetTabular.h @@ -96,6 +96,8 @@ public: /// ALIGN_BLOCK, /// + ALIGN_DECIMAL, + /// VALIGN_TOP, /// VALIGN_BOTTOM, @@ -190,6 +192,8 @@ public: /// LONGTABULAR_ALIGN_RIGHT, /// + SET_DECIMAL_POINT, + /// LAST_ACTION }; /// @@ -490,6 +494,10 @@ public: LyXAlignment alignment; /// VAlignment valignment; + /// width of the part before the decimal + int decimal_hoffset; + /// width of the decimal part + int decimal_width; /// int voffset; /// @@ -570,6 +578,8 @@ public: Length p_width; /// docstring align_special; + /// + docstring decimal_point; }; /// typedef std::vector column_vector; @@ -614,8 +624,6 @@ public: void updateIndexes(); /// bool setFixedWidth(row_type r, col_type c); - /// - void updateContentAlignment(row_type r, col_type c); /// return true of update is needed bool updateColumnWidths(); /// @@ -944,6 +952,9 @@ private: std::string const featureAsString(Tabular::Feature feature); +/// Split cell on decimal symbol +InsetTableCell splitCell(InsetTableCell & head, docstring const decimal_sym, bool & hassep); + } // namespace lyx #endif // INSET_TABULAR_H -- 2.39.2