Attached is what I currently have to support multirows.
There is currently one issue I cannot solve: The metrics and drawing of the cells that are part of a multirow is broken. The drawing of the first multirow cell is however correct. I failed to figure out this problem and therefore ask for help.
Besides this, the copy/paste mechanism is not yet ready for multirows. The same applies for the plain text output but I have not yet had a look at this.The UI is also not yet feature-complete. I plan to further add support to set the multirow width and the horzontal alignment.
thanks in advance and regards Uwe
<<attachment: tabular-feature_multirow.png>>
Index: development/scons/scons_manifest.py =================================================================== --- development/scons/scons_manifest.py (revision 33077) +++ development/scons/scons_manifest.py (working copy) @@ -1515,6 +1515,7 @@ tabular-feature_delete-column.png tabular-feature_delete-row.png tabular-feature_multicolumn.png + tabular-feature_multirow.png tabular-feature_set-all-lines.png tabular-feature_set-border-lines.png tabular-feature_set-longtabular.png Index: lib/images/tabular-feature_multirow.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: lib\images\tabular-feature_multirow.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Index: lib/Makefile.am =================================================================== --- lib/Makefile.am (revision 33077) +++ lib/Makefile.am (working copy) @@ -415,6 +415,7 @@ images/tabular-feature_delete-column.png \ images/tabular-feature_delete-row.png \ images/tabular-feature_multicolumn.png \ + images/tabular-feature_multirow.png \ images/tabular-feature_set-all-lines.png \ images/tabular-feature_set-longtabular.png \ images/tabular-feature_set-rotate-cell.png \ Index: lib/ui/stdtoolbars.inc =================================================================== --- lib/ui/stdtoolbars.inc (revision 33077) +++ lib/ui/stdtoolbars.inc (working copy) @@ -151,6 +151,7 @@ Item "Rotate cell" "tabular-feature toggle-rotate-cell" Item "Rotate table" "tabular-feature toggle-rotate-tabular" Item "Set multi-column" "tabular-feature multicolumn" + Item "Set multi-row" "tabular-feature multirow" End Toolbar "math" "Math" Index: src/frontends/qt4/GuiTabular.cpp =================================================================== --- src/frontends/qt4/GuiTabular.cpp (revision 33077) +++ src/frontends/qt4/GuiTabular.cpp (working copy) @@ -96,6 +96,8 @@ this, SLOT(vAlign_changed(int))); connect(multicolumnCB, SIGNAL(clicked()), this, SLOT(multicolumn_clicked())); + connect(multirowCB, SIGNAL(clicked()), + this, SLOT(multirow_clicked())); connect(newpageCB, SIGNAL(clicked()), this, SLOT(ltNewpage_clicked())); connect(headerStatusCB, SIGNAL(clicked()), @@ -172,6 +174,7 @@ bc().addReadOnly(booktabsRB); bc().addReadOnly(multicolumnCB); + bc().addReadOnly(multirowCB); bc().addReadOnly(rotateCellCB); bc().addReadOnly(rotateTabularCB); bc().addReadOnly(specialAlignmentED); @@ -396,7 +399,13 @@ changed(); } +void GuiTabular::multirow_clicked() +{ + toggleMultiRow(); + changed(); +} + void GuiTabular::rotateTabular() { rotateTabular(rotateTabularCB->isChecked()); @@ -654,7 +663,7 @@ Length getMColumnPWidth(Tabular const & t, size_t cell) { - if (t.isMultiColumn(cell)) + if (t.isMultiColumn(cell) || t.isMultiRow(cell)) return t.cellInfo(cell).p_width; return Length(); } @@ -662,7 +671,8 @@ docstring getAlignSpecial(Tabular const & t, size_t cell, int what) { - if (what == Tabular::SET_SPECIAL_MULTI) + if (what == Tabular::SET_SPECIAL_MULTICOLUMN + || what == Tabular::SET_SPECIAL_MULTIROW) return t.cellInfo(cell).align_special; return t.column_info[t.cellColumn(cell)].align_special; } @@ -670,7 +680,6 @@ } - void GuiTabular::updateContents() { initialiseParams(string()); @@ -684,9 +693,11 @@ tabularColumnED->setText(QString::number(col + 1)); bool const multicol(tabular_.isMultiColumn(cell)); - multicolumnCB->setChecked(multicol); + bool const multirow(tabular_.isMultiRow(cell)); + multirowCB->setChecked(multirow); + rotateCellCB->setChecked(tabular_.getRotateCell(cell)); rotateTabularCB->setChecked(tabular_.rotate); @@ -699,8 +710,12 @@ if (multicol) { special = getAlignSpecial(tabular_, cell, - Tabular::SET_SPECIAL_MULTI); + Tabular::SET_SPECIAL_MULTICOLUMN); pwidth = getMColumnPWidth(tabular_, cell); + } else if (multirow) { + special = getAlignSpecial(tabular_, cell, + Tabular::SET_SPECIAL_MULTIROW); + pwidth = getMColumnPWidth(tabular_, cell); } else { special = getAlignSpecial(tabular_, cell, Tabular::SET_SPECIAL_COLUMN); @@ -832,7 +847,8 @@ vAlignCB->setCurrentIndex(valign); hAlignCB->setEnabled(true); - vAlignCB->setEnabled(!pwidth.zero()); + if (!multirow && !pwidth.zero()) + vAlignCB->setEnabled(true); int tableValign = 1; switch (tabular_.tabular_valignment) { @@ -927,6 +943,7 @@ // When a row is set as longtable caption, it must not be allowed // to unset that this row is a multicolumn. multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN)); + multirowCB->setEnabled(funcEnabled(Tabular::MULTIROW)); Tabular::ltType ltt; bool use_empty; @@ -1021,15 +1038,16 @@ // apply the fixed width values size_t const cell = getActiveCell(); bool const multicol = tabular_.isMultiColumn(cell); + bool const multirow = tabular_.isMultiRow(cell); string width = widgetsToLength(widthED, widthUnitCB); string width2; Length llen = getColumnPWidth(tabular_, cell); Length llenMulti = getMColumnPWidth(tabular_, cell); - if (multicol && !llenMulti.zero()) + if (multicol && multirow && !llenMulti.zero()) width2 = llenMulti.asString(); - else if (!multicol && !llen.zero()) + else if (!multicol && !multirow && !llen.zero()) width2 = llen.asString(); // apply the special alignment @@ -1038,14 +1056,19 @@ if (multicol) sa2 = getAlignSpecial(tabular_, cell, - Tabular::SET_SPECIAL_MULTI); + Tabular::SET_SPECIAL_MULTICOLUMN); + else if (multirow) + sa2 = getAlignSpecial(tabular_, cell, + Tabular::SET_SPECIAL_MULTIROW); else sa2 = getAlignSpecial(tabular_, cell, Tabular::SET_SPECIAL_COLUMN); if (sa1 != sa2) { if (multicol) - set(Tabular::SET_SPECIAL_MULTI, to_utf8(sa1)); + set(Tabular::SET_SPECIAL_MULTICOLUMN, to_utf8(sa1)); + if (multirow) + set(Tabular::SET_SPECIAL_MULTIROW, to_utf8(sa1)); else set(Tabular::SET_SPECIAL_COLUMN, to_utf8(sa1)); } @@ -1162,7 +1185,9 @@ void GuiTabular::setSpecial(string const & special) { if (tabular_.isMultiColumn(getActiveCell())) - set(Tabular::SET_SPECIAL_MULTI, special); + set(Tabular::SET_SPECIAL_MULTICOLUMN, special); + else if (tabular_.isMultiRow(getActiveCell())) + set(Tabular::SET_SPECIAL_MULTIROW, special); else set(Tabular::SET_SPECIAL_COLUMN, special); } @@ -1186,6 +1211,13 @@ } +void GuiTabular::toggleMultiRow() +{ + set(Tabular::MULTIROW); + updateView(); +} + + void GuiTabular::rotateTabular(bool yes) { if (yes) @@ -1255,7 +1287,8 @@ break; } - if (tabular_.isMultiColumn(getActiveCell())) + if (tabular_.isMultiColumn(getActiveCell()) + || tabular_.isMultiRow(getActiveCell())) set(multi_num); else set(num); Index: src/frontends/qt4/GuiTabular.h =================================================================== --- src/frontends/qt4/GuiTabular.h (revision 33077) +++ src/frontends/qt4/GuiTabular.h (working copy) @@ -45,6 +45,7 @@ void topBorder_changed(); void bottomBorder_changed(); void multicolumn_clicked(); + void multirow_clicked(); void rotateTabular(); void rotateCell(); void hAlign_changed(int align); @@ -101,6 +102,7 @@ void setWidth(std::string const & width); void toggleMultiColumn(); + void toggleMultiRow(); void rotateTabular(bool yes); void rotateCell(bool yes); Index: src/frontends/qt4/ui/TabularUi.ui =================================================================== --- src/frontends/qt4/ui/TabularUi.ui (revision 33077) +++ src/frontends/qt4/ui/TabularUi.ui (working copy) @@ -130,8 +130,8 @@ <attribute name="title"> <string>&Table Settings</string> </attribute> - <layout class="QGridLayout" name="gridLayout_6"> - <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0" colspan="2"> <widget class="QGroupBox" name="GroupBox12"> <property name="title"> <string>Column settings</string> @@ -283,7 +283,7 @@ <item row="3" column="0"> <widget class="QCheckBox" name="multicolumnCB"> <property name="toolTip"> - <string>Merge cells</string> + <string>Merge cells of different columns</string> </property> <property name="text"> <string>&Multicolumn</string> @@ -296,10 +296,29 @@ <item row="1" column="0"> <widget class="QGroupBox" name="groupBox"> <property name="title"> - <string>Cell setting</string> + <string>Row setting</string> </property> <layout class="QGridLayout" name="gridLayout_3"> <item row="0" column="0"> + <widget class="QCheckBox" name="multirowCB"> + <property name="toolTip"> + <string>Merge cells of different rows</string> + </property> + <property name="text"> + <string>M&ultirow</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="1" column="1"> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Cell setting</string> + </property> + <layout class="QGridLayout" name="gridLayout_6"> + <item row="0" column="0"> <widget class="QCheckBox" name="rotateCellCB"> <property name="toolTip"> <string>Rotate this cell by 90 degrees</string> @@ -312,7 +331,7 @@ </layout> </widget> </item> - <item row="2" column="0"> + <item row="2" column="0" colspan="2"> <widget class="QGroupBox" name="tabAlignmentGB"> <property name="enabled"> <bool>true</bool> @@ -388,7 +407,7 @@ </layout> </widget> </item> - <item row="3" column="0"> + <item row="3" column="0" colspan="2"> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <widget class="QLabel" name="specialAlignmentLA"> @@ -409,15 +428,15 @@ </item> </layout> </item> - <item row="4" column="0"> + <item row="4" column="1"> <spacer name="verticalSpacer_2"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> - <width>20</width> - <height>68</height> + <width>17</width> + <height>0</height> </size> </property> </spacer> @@ -1497,6 +1516,7 @@ <tabstop>vAlignCB</tabstop> <tabstop>multicolumnCB</tabstop> <tabstop>rotateTabularCB</tabstop> + <tabstop>multirowCB</tabstop> <tabstop>rotateCellCB</tabstop> <tabstop>specialAlignmentED</tabstop> <tabstop>closePB</tabstop> Index: src/insets/InsetTabular.cpp =================================================================== --- src/insets/InsetTabular.cpp (revision 33077) +++ src/insets/InsetTabular.cpp (working copy) @@ -130,6 +130,7 @@ { Tabular::M_VALIGN_BOTTOM, "m-valign-bottom" }, { Tabular::M_VALIGN_MIDDLE, "m-valign-middle" }, { Tabular::MULTICOLUMN, "multicolumn" }, + { Tabular::MULTIROW, "multirow" }, { Tabular::SET_ALL_LINES, "set-all-lines" }, { Tabular::UNSET_ALL_LINES, "unset-all-lines" }, { Tabular::SET_LONGTABULAR, "set-longtabular" }, @@ -154,7 +155,8 @@ { Tabular::SET_LTNEWPAGE, "set-ltnewpage" }, { Tabular::TOGGLE_LTCAPTION, "toggle-ltcaption" }, { Tabular::SET_SPECIAL_COLUMN, "set-special-column" }, - { Tabular::SET_SPECIAL_MULTI, "set-special-multi" }, + { Tabular::SET_SPECIAL_MULTICOLUMN, "set-special-multicolumn" }, + { Tabular::SET_SPECIAL_MULTIROW, "set-special-multirow" }, { Tabular::SET_BOOKTABS, "set-booktabs" }, { Tabular::UNSET_BOOKTABS, "unset-booktabs" }, { Tabular::SET_TOP_SPACE, "set-top-space" }, @@ -519,6 +521,7 @@ : cellno(0), width(0), multicolumn(Tabular::CELL_NORMAL), + multirow(Tabular::CELL_NORMAL), alignment(LYX_ALIGN_CENTER), valignment(LYX_VALIGN_TOP), top_line(false), @@ -537,6 +540,7 @@ : cellno(cs.cellno), width(cs.width), multicolumn(cs.multicolumn), + multirow(cs.multirow), alignment(cs.alignment), valignment(cs.valignment), top_line(cs.top_line), @@ -562,6 +566,7 @@ std::swap(cellno, rhs.cellno); std::swap(width, rhs.width); std::swap(multicolumn, rhs.multicolumn); + std::swap(multirow, rhs.multirow); std::swap(alignment, rhs.alignment); std::swap(valignment, rhs.valignment); std::swap(top_line, rhs.top_line); @@ -704,6 +709,15 @@ if (row_info.size() == 1) return; + size_t const column_count = column_info.size(); + for (col_type i = 0; i < column_count; ++i) { + // Care about multirow cells + if (row + 1 < row_info.size() && + cell_info[row][i].multirow == CELL_BEGIN_OF_MULTIROW && + cell_info[row][i + 1].multirow == CELL_PART_OF_MULTIROW) { + cell_info[row][i + 1].multirow = CELL_BEGIN_OF_MULTIROW; + } + } row_info.erase(row_info.begin() + row); cell_info.erase(cell_info.begin() + row); updateIndexes(); @@ -809,7 +823,8 @@ numberofcells = 0; for (row_type row = 0; row < nrows; ++row) for (col_type column = 0; column < ncols; ++column) { - if (!isPartOfMultiColumn(row, column)) + if (!isPartOfMultiColumn(row, column) + && !isPartOfMultiRow(row, column)) ++numberofcells; cell_info[row][column].cellno = numberofcells - 1; } @@ -819,7 +834,8 @@ idx_type i = 0; for (row_type row = 0; row < nrows; ++row) for (col_type column = 0; column < ncols; ++column) { - if (isPartOfMultiColumn(row, column)) + if (isPartOfMultiColumn(row, column) + || isPartOfMultiRow(row, column)) continue; rowofcell[i] = row; columnofcell[i] = column; @@ -1098,7 +1114,7 @@ void Tabular::setAlignSpecial(idx_type cell, docstring const & special, Tabular::Feature what) { - if (what == SET_SPECIAL_MULTI) + if (what == SET_SPECIAL_MULTICOLUMN) cellInfo(cell).align_special = special; else column_info[cellColumn(cell)].align_special = special; @@ -1379,6 +1395,7 @@ for (col_type j = 0; j < column_info.size(); ++j) { os << "<cell" << write_attribute("multicolumn", cell_info[i][j].multicolumn) + << write_attribute("multirow", cell_info[i][j].multirow) << write_attribute("alignment", cell_info[i][j].alignment) << write_attribute("valignment", cell_info[i][j].valignment) << write_attribute("topline", cell_info[i][j].top_line) @@ -1486,6 +1503,7 @@ return; } getTokenValue(line, "multicolumn", cell_info[i][j].multicolumn); + getTokenValue(line, "multirow", cell_info[i][j].multirow); 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); @@ -1525,14 +1543,19 @@ bool Tabular::isMultiColumn(idx_type cell) const { - return cellInfo(cell).multicolumn != CELL_NORMAL; + if (cellInfo(cell).multicolumn == CELL_BEGIN_OF_MULTICOLUMN + || cellInfo(cell).multicolumn == CELL_PART_OF_MULTICOLUMN) + return true; + else + return false; } bool Tabular::isMultiColumnReal(idx_type cell) const { return cellColumn(cell) != cellRightColumn(cell) && - cellInfo(cell).multicolumn != CELL_NORMAL; + (cellInfo(cell).multicolumn == CELL_BEGIN_OF_MULTICOLUMN + || cellInfo(cell).multicolumn == CELL_PART_OF_MULTICOLUMN); } @@ -1558,6 +1581,39 @@ } +bool Tabular::isMultiRow(idx_type cell) const +{ + if (cellInfo(cell).multirow == CELL_BEGIN_OF_MULTIROW + || cellInfo(cell).multirow == CELL_PART_OF_MULTIROW) + return true; + else + return false; +} + + +void Tabular::setMultiRow(idx_type cell, idx_type number) +{ + idx_type const column = cellColumn(cell); + idx_type row = cellRow(cell); + idx_type const ncolumns = column_info.size(); + CellData & cs = cellInfo(cell); + cs.multirow = CELL_BEGIN_OF_MULTIROW; + // FIXME: the horizontal alignment can only be changed for + // the whole table, support for this needs to be implemented + // assigning this to uwestoehr + cs.valignment = LYX_VALIGN_MIDDLE; + // set the bottom row of the last selected cell + setBottomLine(cell, bottomLine(cell + (number - 1)*ncolumns)); + for (idx_type i = 1; i < number; ++i) { + CellData & cs1 = cell_info[row+i][column]; + cs1.multirow = CELL_PART_OF_MULTIROW; + cs.inset->appendParagraphs(cs1.inset->paragraphs()); + cs1.inset->clear(); + } + updateIndexes(); +} + + Tabular::idx_type Tabular::columnSpan(idx_type cell) const { row_type const row = cellRow(cell); @@ -1572,6 +1628,20 @@ } +Tabular::idx_type Tabular::rowSpan(idx_type cell) const +{ + row_type const nrows = row_info.size(); + col_type const column = cellColumn(cell); + idx_type result = 1; + col_type row = cellRow(cell) + 1; + while (row < nrows && isPartOfMultiRow(row, column)) { + ++result; + ++row; + } + return result; +} + + Tabular::idx_type Tabular::unsetMultiColumn(idx_type cell) { row_type const row = cellRow(cell); @@ -1595,6 +1665,29 @@ } +Tabular::idx_type Tabular::unsetMultiRow(idx_type cell) +{ + row_type row = cellRow(cell); + col_type const column = cellColumn(cell); + + idx_type result = 0; + + if (cell_info[row][column].multirow == CELL_BEGIN_OF_MULTIROW) { + cell_info[row][column].multirow = CELL_NORMAL; + ++row; + while (row < row_info.size() && + cell_info[row][column].multirow == CELL_PART_OF_MULTIROW) + { + cell_info[row][column].multirow = CELL_NORMAL; + ++row; + ++result; + } + } + updateIndexes(); + return result; +} + + void Tabular::setRotateCell(idx_type cell, bool flag) { cellInfo(cell).rotate = flag; @@ -1873,6 +1966,14 @@ } +bool Tabular::isPartOfMultiRow(row_type row, col_type column) const +{ + LASSERT(row < row_info.size(), /**/); + LASSERT(column < column_info.size(), /**/); + return cell_info[row][column].multirow == CELL_PART_OF_MULTIROW; +} + + int Tabular::TeXTopHLine(odocstream & os, row_type row, string const lang) const { // we only output complete row lines and the 1st row here, the rest @@ -1979,7 +2080,8 @@ } -int Tabular::TeXCellPreamble(odocstream & os, idx_type cell, bool & ismulticol) const +int Tabular::TeXCellPreamble(odocstream & os, idx_type cell, + bool & ismulticol, bool & ismultirow) const { int ret = 0; row_type const r = cellRow(cell); @@ -1999,7 +2101,8 @@ && leftLine(cellIndex(r, nextcol)); bool coldouble = colright && nextcolleft; bool celldouble = rightLine(cell) && nextcellleft; - ismulticol = isMultiColumn(cell) + + ismulticol = isMultiColumn(cell) || (c == 0 && colleft != leftLine(cell)) || ((colright || nextcolleft) && !rightLine(cell) && !nextcellleft) || (!colright && !nextcolleft && (rightLine(cell) || nextcellleft)) @@ -2059,7 +2162,23 @@ // add extra vertical line if we want a double one os << '|'; os << "}{"; - } + } // end if ismulticol + + // we only need code for the first multirow cell + ismultirow = false; + if (cellInfo(cell).multirow == CELL_BEGIN_OF_MULTIROW) + ismultirow = true; + if (ismultirow) { + os << "\\multirow{" << rowSpan(cell) << "}{"; + if (!getPWidth(cell).zero()) + os << from_ascii(getPWidth(cell).asLatexString()); + else + // we need to set a default value + // needs to be discussed + os << "2.0cm"; + os << "}{"; + } // end if ismultirow + if (getRotateCell(cell)) { os << "\\begin{sideways}\n"; ++ret; @@ -2100,7 +2219,8 @@ } -int Tabular::TeXCellPostamble(odocstream & os, idx_type cell, bool ismulticol) const +int Tabular::TeXCellPostamble(odocstream & os, idx_type cell, + bool ismulticol, bool ismultirow) const { int ret = 0; row_type const r = cellRow(cell); @@ -2118,7 +2238,7 @@ os << "%\n\\end{sideways}"; ++ret; } - if (ismulticol) { + if (ismulticol || ismultirow) { os << '}'; } return ret; @@ -2267,10 +2387,11 @@ ++ret; } bool ismulticol = false; + bool ismultirow = false; for (col_type j = 0; j < column_info.size(); ++j) { - if (isPartOfMultiColumn(i, j)) + if (isPartOfMultiColumn(i, j) || isPartOfMultiRow(i, j)) continue; - ret += TeXCellPreamble(os, cell, ismulticol); + ret += TeXCellPreamble(os, cell, ismulticol, ismultirow); shared_ptr<InsetTableCell> inset = cellInset(cell); Paragraph const & par = inset->paragraphs().front(); @@ -2302,7 +2423,7 @@ if (rtl) os << '}'; - ret += TeXCellPostamble(os, cell, ismulticol); + ret += TeXCellPostamble(os, cell, ismulticol, ismultirow); if (!isLastCellInRow(cell)) { // not last cell in row os << " & "; } @@ -3152,8 +3273,9 @@ int maxAsc = 0; int maxDesc = 0; for (col_type j = 0; j < tabular.column_info.size(); ++j) { - if (tabular.isPartOfMultiColumn(i, j)) - // Multicolumn cell, but not first one + if (tabular.isPartOfMultiColumn(i, j) + || tabular.isPartOfMultiRow(i, j)) + // multicolumn or multirow cell, but not first one continue; Dimension dim; MetricsInfo m = mi; @@ -3250,6 +3372,7 @@ int const cx = nx + tabular.getBeginningOfTextInCell(idx); // Cache the Inset position. bv->coordCache().insets().add(cell(idx).get(), cx, y); + // FIXME: missing comment what this loop does if (nx + tabular.columnWidth(idx) < 0 || nx > bv->workWidth() || y + d < 0 @@ -3259,8 +3382,14 @@ drawCellLines(pi.pain, nx, y, i, idx, pi.change_); pi.pain.setDrawingEnabled(original_drawing_state); } else { - cell(idx)->draw(pi, cx, y); - drawCellLines(pi.pain, nx, y, i, idx, pi.change_); + // don't draw multirow cells (only their width is + // taken into account) + if (!tabular.isPartOfMultiRow(i, j)) { + cell(idx)->draw(pi, cx, y); + drawCellLines(pi.pain, nx, y, i, idx, pi.change_); + } + // FIXME: the ehight of the forst multiro cell needs to be + // calculated correctly } nx += tabular.columnWidth(idx); ++idx; @@ -3934,7 +4063,8 @@ case Tabular::SET_PWIDTH: case Tabular::SET_MPWIDTH: case Tabular::SET_SPECIAL_COLUMN: - case Tabular::SET_SPECIAL_MULTI: + case Tabular::SET_SPECIAL_MULTICOLUMN: + case Tabular::SET_SPECIAL_MULTIROW: case Tabular::APPEND_ROW: case Tabular::APPEND_COLUMN: case Tabular::DELETE_ROW: @@ -3955,6 +4085,14 @@ status.setOnOff(tabular.isMultiColumn(cur.idx())); break; + case Tabular::MULTIROW: + // If a row is set as longtable caption, it must not be allowed + // to unset that this row is a multirow. + status.setEnabled(sel_col_start == sel_col_end + && !tabular.ltCaption(tabular.cellRow(cur.idx()))); + status.setOnOff(tabular.isMultiRow(cur.idx())); + break; + case Tabular::SET_ALL_LINES: case Tabular::UNSET_ALL_LINES: case Tabular::SET_BORDER_LINES: @@ -4343,9 +4481,13 @@ { cell(sl.idx())->cursorPos(bv, sl, boundary, x, y); + int const row = tabular.cellRow(sl.idx()); + int const col = tabular.cellColumn(sl.idx()); + // y offset correction - int const row = tabular.cellRow(sl.idx()); for (int i = 0; i <= row; ++i) { + if (tabular.isPartOfMultiRow(i, col)) + continue; if (i != 0) { y += tabular.rowAscent(i); y += tabular.getAdditionalHeight(i); @@ -4355,7 +4497,6 @@ } // x offset correction - int const col = tabular.cellColumn(sl.idx()); int idx = tabular.cellIndex(row, 0); for (int j = 0; j < col; ++j) { if (tabular.isPartOfMultiColumn(row, j)) @@ -4713,7 +4854,7 @@ break; case Tabular::SET_SPECIAL_COLUMN: - case Tabular::SET_SPECIAL_MULTI: + case Tabular::SET_SPECIAL_MULTICOLUMN: tabular.setAlignSpecial(cur.idx(), from_utf8(value), feature); break; @@ -4837,6 +4978,32 @@ cur.setSelection(false); break; } + + case Tabular::MULTIROW: { + if (!cur.selection()) { + // just multirow for one single cell + // check whether we are completely in a multirow + if (tabular.isMultiRow(cur.idx())) + tabular.unsetMultiRow(cur.idx()); + else + tabular.setMultiRow(cur.idx(), 1); + break; + } + // we have a selection so this means we just add all this + // cells to form a multirow cell + idx_type const s_start = cur.selBegin().idx(); + idx_type const s_end = cur.selEnd().idx(); + // the cell index is counted from left to right, we therefore + // need to know the number of columns of the table to calculate + // the number of selected rows + idx_type const ncolumns = tabular.column_info.size(); + tabular.setMultiRow(s_start, (s_end - s_start)/ncolumns + 1); + cur.idx() = s_start; + cur.pit() = 0; + cur.pos() = 0; + cur.setSelection(false); + break; + } case Tabular::SET_ALL_LINES: setLines = true; Index: src/insets/InsetTabular.h =================================================================== --- src/insets/InsetTabular.h (revision 33077) +++ src/insets/InsetTabular.h (working copy) @@ -12,7 +12,6 @@ * Full author contact details are available in file CREDITS. */ - // This is Juergen's rewrite of the tabular (table) support. // Things to think of when designing the new tabular support: @@ -24,14 +23,6 @@ // - multirow // - column styles -// This is what I have written about tabular support in the LyX3-Tasks file: -// -// o rewrite of table code. Should probably be written as some -// kind of an inset. [Done] -// o enhance longtable support - -// Lgb - #ifndef INSET_TABULAR_H #define INSET_TABULAR_H @@ -120,6 +111,8 @@ /// MULTICOLUMN, /// + MULTIROW, + /// SET_ALL_LINES, /// UNSET_ALL_LINES, @@ -164,8 +157,10 @@ /// SET_SPECIAL_COLUMN, /// - SET_SPECIAL_MULTI, + SET_SPECIAL_MULTICOLUMN, /// + SET_SPECIAL_MULTIROW, + /// SET_BOOKTABS, /// UNSET_BOOKTABS, @@ -199,7 +194,11 @@ /// CELL_BEGIN_OF_MULTICOLUMN, /// - CELL_PART_OF_MULTICOLUMN + CELL_PART_OF_MULTICOLUMN, + /// + CELL_BEGIN_OF_MULTIROW, + /// + CELL_PART_OF_MULTIROW }; /// @@ -388,6 +387,14 @@ /// bool isPartOfMultiColumn(row_type row, col_type column) const; /// + bool isPartOfMultiRow(row_type row, col_type column) const; + /// + bool isMultiRow(idx_type cell) const; + /// + void setMultiRow(idx_type cell, idx_type number); + /// + idx_type unsetMultiRow(idx_type cell); // returns number of new cells + /// row_type cellRow(idx_type cell) const; /// col_type cellColumn(idx_type cell) const; @@ -482,6 +489,8 @@ /// int multicolumn; /// + int multirow; + /// LyXAlignment alignment; /// VAlignment valignment; @@ -614,6 +623,8 @@ /// idx_type columnSpan(idx_type cell) const; /// + idx_type rowSpan(idx_type cell) const; + /// BoxType useParbox(idx_type cell) const; /// // helper function for Latex returns number of newlines @@ -622,9 +633,9 @@ /// int TeXBottomHLine(odocstream &, row_type row, std::string const lang) const; /// - int TeXCellPreamble(odocstream &, idx_type cell, bool & ismulticol) const; + int TeXCellPreamble(odocstream &, idx_type cell, bool & ismulticol, bool & ismultirow) const; /// - int TeXCellPostamble(odocstream &, idx_type cell, bool ismulticol) const; + int TeXCellPostamble(odocstream &, idx_type cell, bool ismulticol, bool ismultirow) const; /// int TeXLongtableHeaderFooter(odocstream &, OutputParams const &) const; /// Index: src/LyXAction.cpp =================================================================== --- src/LyXAction.cpp (revision 33077) +++ src/LyXAction.cpp (working copy) @@ -2047,9 +2047,10 @@ set-rotate-cell|unset-rotate-cell|toggle-rotate-cell|set-usebox|set-lthead| unset-lthead|set-ltfirsthead|unset-ltfirsthead|set-ltfoot|unset-ltfoot| set-ltlastfoot|unset-ltlastfoot|set-ltnewpage|toggle-ltcaption| - set-special-column|set-special-multi|set-booktabs|unset-booktabs| - set-top-space|set-bottom-space|set-interline-space|set-border-lines| - tabular-valign-top|tabular-valign-middle|tabular-valign-bottom \n + set-special-column|set-special-multicolumn|set-special-multirow| + set-booktabs|unset-booktabs|set-top-space|set-bottom-space| + set-interline-space|set-border-lines|tabular-valign-top| + tabular-valign-middle|tabular-valign-bottom \n <ARG>: additional argument for some commands, use debug mode to explore its values. * \li Origin: Jug, 28 Jul 2000 * \endvar