X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetTabular.cpp;h=806d8256f29f7c96a2e7d481f9983ce936e1e514;hb=2203d7aa0a8e9d64666498fb26eb17f699c2f52b;hp=b219a9fa78dfb687052c55ad27f46491f97bd70e;hpb=497d6d13f74e3a3513cd5d075832225a93771af2;p=lyx.git diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index b219a9fa78..806d8256f2 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -70,7 +70,6 @@ using namespace std; using namespace lyx::support; -using boost::shared_ptr; namespace lyx { @@ -126,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 }, @@ -175,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 } }; @@ -252,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(); } @@ -312,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; @@ -503,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; +} + ///////////////////////////////////////////////////////////////////// // @@ -518,6 +547,9 @@ 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), left_line(false), @@ -537,6 +569,9 @@ 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), left_line(cs.left_line), @@ -563,6 +598,9 @@ 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); std::swap(left_line, rhs.left_line); @@ -614,10 +652,8 @@ Tabular::Tabular(Buffer * buffer, row_type rows_arg, col_type columns_arg) void Tabular::setBuffer(Buffer & buffer) { buffer_ = &buffer; - row_type const nrows = row_info.size(); - col_type const ncols = column_info.size(); - for (row_type i = 0; i < nrows; ++i) - for (col_type j = 0; j < ncols; ++j) + for (row_type i = 0; i < nrows(); ++i) + for (col_type j = 0; j < ncols(); ++j) cell_info[i][j].inset->setBuffer(*buffer_); } @@ -639,16 +675,14 @@ void Tabular::init(Buffer * buf, row_type rows_arg, longtabular_alignment = LYX_LONGTABULAR_ALIGN_CENTER; rotate = false; use_booktabs = false; - size_t row_count = row_info.size(); - size_t column_count = column_info.size(); // set silly default lines - for (row_type i = 0; i < row_count; ++i) - for (col_type j = 0; j < column_count; ++j) { - cell_info[i][j].inset->setBuffer(*buffer_); - cell_info[i][j].top_line = true; - cell_info[i][j].left_line = true; - cell_info[i][j].bottom_line = i == 0 || i == row_count - 1; - cell_info[i][j].right_line = j == column_count - 1; + for (row_type r = 0; r < nrows(); ++r) + for (col_type c = 0; c < ncols(); ++c) { + cell_info[r][c].inset->setBuffer(*buffer_); + cell_info[r][c].top_line = true; + cell_info[r][c].left_line = true; + cell_info[r][c].bottom_line = r == 0 || r == nrows() - 1; + cell_info[r][c].right_line = c == ncols() - 1; } } @@ -660,10 +694,9 @@ void Tabular::appendRow(idx_type const cell) row_info.insert(row_info.begin() + row + 1, RowData()); row_info[row + 1] = row_info[row]; - col_type const ncols = column_info.size(); cell_info.insert(cell_info.begin() + row + 1, - cell_vector(ncols, CellData(buffer_))); - for (col_type c = 0; c < ncols; ++c) { + cell_vector(ncols(), CellData(buffer_))); + for (col_type c = 0; c < ncols(); ++c) { if (cell_info[row][c].multirow == CELL_BEGIN_OF_MULTIROW) cell_info[row + 1][c].multirow = CELL_PART_OF_MULTIROW; else @@ -671,7 +704,7 @@ void Tabular::appendRow(idx_type const cell) } updateIndexes(); - for (col_type c = 0; c < ncols; ++c) { + for (col_type c = 0; c < ncols(); ++c) { if (isPartOfMultiRow(row, c)) continue; // inherit line settings @@ -694,16 +727,15 @@ void Tabular::appendRow(idx_type const cell) void Tabular::deleteRow(row_type const row) { // Not allowed to delete last row - if (row_info.size() == 1) + if (nrows() == 1) return; - size_t const column_count = column_info.size(); - for (col_type i = 0; i < column_count; ++i) { + for (col_type c = 0; c < ncols(); ++c) { // 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; + if (row + 1 < nrows() && + cell_info[row][c].multirow == CELL_BEGIN_OF_MULTIROW && + cell_info[row + 1][c].multirow == CELL_PART_OF_MULTIROW) { + cell_info[row + 1][c].multirow = CELL_BEGIN_OF_MULTIROW; } } row_info.erase(row_info.begin() + row); @@ -718,8 +750,8 @@ void Tabular::copyRow(row_type const row) cell_info.insert(cell_info.begin() + row, cell_info[row]); if (buffer().params().trackChanges) - for (col_type j = 0; j < column_info.size(); ++j) - cell_info[row + 1][j].inset->setChange(Change(Change::INSERTED)); + for (col_type c = 0; c < ncols(); ++c) + cell_info[row + 1][c].inset->setChange(Change(Change::INSERTED)); updateIndexes(); } @@ -732,8 +764,7 @@ void Tabular::appendColumn(idx_type const cell) column_info.insert(column_info.begin() + c + 1, ColumnData()); column_info[c + 1] = column_info[c]; - row_type const nrows = row_info.size(); - for (row_type r = 0; r < nrows; ++r) { + for (row_type r = 0; r < nrows(); ++r) { cell_info[r].insert(cell_info[r].begin() + c + 1, CellData(buffer_)); if (cell_info[r][c].multicolumn == CELL_BEGIN_OF_MULTICOLUMN) @@ -742,7 +773,7 @@ void Tabular::appendColumn(idx_type const cell) cell_info[r][c + 1].multicolumn = cell_info[r][c].multicolumn; } updateIndexes(); - for (row_type r = 0; r < nrows; ++r) { + for (row_type r = 0; r < nrows(); ++r) { // inherit line settings idx_type const i = cellIndex(r, c + 1); idx_type const j = cellIndex(r, c); @@ -762,13 +793,12 @@ void Tabular::appendColumn(idx_type const cell) void Tabular::deleteColumn(col_type const col) { // Not allowed to delete last column - if (column_info.size() == 1) + if (ncols() == 1) return; - row_type const nrows = row_info.size(); - for (row_type r = 0; r < nrows; ++r) { + for (row_type r = 0; r < nrows(); ++r) { // Care about multicolumn cells - if (col + 1 < column_info.size() && + if (col + 1 < ncols() && cell_info[r][col].multicolumn == CELL_BEGIN_OF_MULTICOLUMN && cell_info[r][col + 1].multicolumn == CELL_PART_OF_MULTICOLUMN) { cell_info[r][col + 1].multicolumn = CELL_BEGIN_OF_MULTICOLUMN; @@ -785,8 +815,7 @@ void Tabular::copyColumn(col_type const col) BufferParams const & bp = buffer().params(); column_info.insert(column_info.begin() + col, column_info[col]); - row_type nrows = row_info.size(); - for (row_type r = 0; r < nrows; ++r) { + for (row_type r = 0; r < nrows(); ++r) { cell_info[r].insert(cell_info[r].begin() + col, cell_info[r][col]); if (bp.trackChanges) cell_info[r][col + 1].inset->setChange(Change(Change::INSERTED)); @@ -798,11 +827,9 @@ void Tabular::copyColumn(col_type const col) void Tabular::updateIndexes() { setBuffer(buffer()); - col_type ncols = column_info.size(); - row_type nrows = row_info.size(); numberofcells = 0; - for (row_type row = 0; row < nrows; ++row) - for (col_type column = 0; column < ncols; ++column) { + for (row_type row = 0; row < nrows(); ++row) + for (col_type column = 0; column < ncols(); ++column) { if (!isPartOfMultiColumn(row, column) && !isPartOfMultiRow(row, column)) ++numberofcells; @@ -815,15 +842,16 @@ void Tabular::updateIndexes() rowofcell.resize(numberofcells); columnofcell.resize(numberofcells); idx_type i = 0; - for (row_type row = 0; row < nrows; ++row) - for (col_type column = 0; column < ncols; ++column) { + for (row_type row = 0; row < nrows(); ++row) + for (col_type column = 0; column < ncols(); ++column) { if (isPartOfMultiColumn(row, column) || isPartOfMultiRow(row, column)) continue; rowofcell[i] = row; columnofcell[i] = column; setFixedWidth(row, column); - updateContentAlignment(row, column); + cell_info[row][column].inset->setContentAlignment( + getAlignment(cellIndex(row, column))); ++i; } } @@ -832,8 +860,8 @@ void Tabular::updateIndexes() Tabular::idx_type Tabular::numberOfCellsInRow(row_type const row) const { idx_type result = 0; - for (col_type i = 0; i < column_info.size(); ++i) - if (cell_info[row][i].multicolumn != Tabular::CELL_PART_OF_MULTICOLUMN) + for (col_type c = 0; c < ncols(); ++c) + if (cell_info[row][c].multicolumn != Tabular::CELL_PART_OF_MULTICOLUMN) ++result; return result; } @@ -869,7 +897,7 @@ bool Tabular::rightLine(idx_type cell) const int Tabular::interRowSpace(row_type row) const { - if (!row || row >= row_info.size()) + if (!row || row >= nrows()) return 0; int const interline_space = row_info[row - 1].interline_space_default ? @@ -884,14 +912,14 @@ int Tabular::interRowSpace(row_type row) const int Tabular::interColumnSpace(idx_type cell) const { col_type const nextcol = cellColumn(cell) + columnSpan(cell); - if (rightLine(cell) && nextcol < column_info.size() + if (rightLine(cell) && nextcol < ncols() && leftLine(cellIndex(cellRow(cell), nextcol))) return WIDTH_OF_LINE; return 0; } -int Tabular::columnWidth(idx_type cell) const +int Tabular::cellWidth(idx_type cell) const { int w = 0; col_type const span = columnSpan(cell); @@ -902,36 +930,45 @@ int Tabular::columnWidth(idx_type cell) const } -int Tabular::rowHeight(idx_type cell) const +int Tabular::cellHeight(idx_type cell) const { - row_type const span = rowSpan(cell); - row_type const row = cellRow(cell); - int h = rowAscent(row) + rowDescent(row); + row_type const span = rowSpan(cell); + row_type const row = cellRow(cell); + int h = 0; + for(row_type r = row; r < row + span ; ++r) { + h += rowAscent(r) + rowDescent(r); + if (r != row + span - 1) + h += interRowSpace(r + 1); + } - for(row_type r = row; r < row + span ; ++r) { - if (r > row) { - h += rowAscent(r); - h += interRowSpace(r); - } - if (r < row + span - 1) - h += rowDescent(r); - } - return h; + return h; } bool Tabular::updateColumnWidths() { - col_type const ncols = column_info.size(); - row_type const nrows = row_info.size(); + 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) { + for(col_type c = 0; c < ncols(); ++c) { int new_width = 0; - for(row_type r = 0; r < nrows; ++r) { + 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 (columnSpan(i) == 1) { + if (getAlignment(i) == LYX_ALIGN_DECIMAL + && cell_info[r][c].decimal_width!=0) + 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) { @@ -940,8 +977,8 @@ bool Tabular::updateColumnWidths() } } // update col widths to fit merged cells - for(col_type c = 0; c < ncols; ++c) - for(row_type r = 0; r < nrows; ++r) { + for(col_type c = 0; c < ncols(); ++c) + for(row_type r = 0; r < nrows(); ++r) { idx_type const i = cellIndex(r, c); int const span = columnSpan(i); if (span == 1 || c > cellColumn(i)) @@ -963,29 +1000,26 @@ bool Tabular::updateColumnWidths() int Tabular::width() const { - col_type const ncols = column_info.size(); int width = 0; - for (col_type i = 0; i < ncols; ++i) - width += column_info[i].width; + for (col_type c = 0; c < ncols(); ++c) + width += column_info[c].width; return width; } -void Tabular::setCellWidth(idx_type cell, int new_width) -{ - cellInfo(cell).width = new_width + 2 * WIDTH_OF_LINE - + interColumnSpace(cell); -} - - 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); + } } @@ -1032,11 +1066,16 @@ void toggleFixedWidth(Cursor & cur, InsetTableCell * inset, bool fixedWidth) void Tabular::setColumnPWidth(Cursor & cur, idx_type cell, Length const & width) { - col_type const j = cellColumn(cell); + col_type const c = cellColumn(cell); - column_info[j].p_width = width; - for (row_type i = 0; i < row_info.size(); ++i) { - idx_type const cell = cellIndex(i, j); + column_info[c].p_width = width; + // reset the vertical alignment to top if the fixed with + // is removed or zero because only fixed width columns can + // have a vertical alignment + if (column_info[c].p_width.zero()) + column_info[c].valignment = LYX_VALIGN_TOP; + for (row_type r = 0; r < nrows(); ++r) { + idx_type const cell = cellIndex(r, c); // because of multicolumns toggleFixedWidth(cur, cellInset(cell).get(), !getPWidth(cell).zero()); @@ -1060,13 +1099,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) { @@ -1095,15 +1127,6 @@ void Tabular::setAlignSpecial(idx_type cell, docstring const & special, } -void Tabular::setAllLines(idx_type cell, bool line) -{ - setTopLine(cell, line); - setBottomLine(cell, line); - setRightLine(cell, line); - setLeftLine(cell, line); -} - - void Tabular::setTopLine(idx_type i, bool line) { cellInfo(i).top_line = line; @@ -1129,24 +1152,18 @@ void Tabular::setRightLine(idx_type cell, bool line) bool Tabular::rowTopLine(row_type r) const { - col_type const ncols = column_info.size(); bool all_rows_set = true; - for (col_type c = 0; all_rows_set && c < ncols; ++c) { - idx_type const i = cellIndex(r, c); - all_rows_set = cellInfo(i).top_line; - } + for (col_type c = 0; all_rows_set && c < ncols(); ++c) + all_rows_set = cellInfo(cellIndex(r, c)).top_line; return all_rows_set; } bool Tabular::rowBottomLine(row_type r) const { - col_type const ncols = column_info.size(); bool all_rows_set = true; - for (col_type c = 0; all_rows_set && c < ncols; ++c) { - idx_type const i = cellIndex(r, c); - all_rows_set = cellInfo(i).bottom_line; - } + for (col_type c = 0; all_rows_set && c < ncols(); ++c) + all_rows_set = cellInfo(cellIndex(r, c)).bottom_line; return all_rows_set; } @@ -1158,9 +1175,8 @@ bool Tabular::columnLeftLine(col_type c) const int nrows_left = 0; int total = 0; - row_type const nrows = row_info.size(); - for (row_type r = 0; r < nrows; ++r) { - idx_type i = cellIndex(r, c); + for (row_type r = 0; r < nrows(); ++r) { + idx_type const i = cellIndex(r, c); if (c == cellColumn(i)) { ++total; bool right = c > 0 && cellInfo(cellIndex(r, c - 1)).right_line; @@ -1179,14 +1195,13 @@ bool Tabular::columnRightLine(col_type c) const int nrows_right = 0; int total = 0; - row_type const nrows = row_info.size(); - for (row_type r = 0; r < nrows; ++r) { + for (row_type r = 0; r < nrows(); ++r) { idx_type i = cellIndex(r, c); if (c == cellColumn(i) + columnSpan(i) - 1) { ++total; - bool left = (c + 1 < column_info.size() + bool left = (c + 1 < ncols() && cellInfo(cellIndex(r, c + 1)).left_line) - || c + 1 == column_info.size(); + || c + 1 == ncols(); if (cellInfo(i).right_line && left) ++nrows_right; } @@ -1197,8 +1212,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; } @@ -1206,7 +1222,7 @@ LyXAlignment Tabular::getAlignment(idx_type cell, bool onlycolumn) const Tabular::VAlignment Tabular::getVAlignment(idx_type cell, bool onlycolumn) const { - if (!onlycolumn && isMultiColumn(cell)) + if (!onlycolumn && (isMultiColumn(cell) || isMultiRow(cell))) return cellInfo(cell).valignment; return column_info[cellColumn(cell)].valignment; } @@ -1220,25 +1236,36 @@ Length const Tabular::getPWidth(idx_type cell) const } -int Tabular::cellWidth(idx_type cell) const -{ - return cellInfo(cell).width; -} - - int Tabular::textHOffset(idx_type cell) const { // the LaTeX Way :-( int x = WIDTH_OF_LINE; + int const w = cellWidth(cell) - cellInfo(cell).width; + switch (getAlignment(cell)) { case LYX_ALIGN_CENTER: - x += (columnWidth(cell) - cellWidth(cell)) / 2; + x += w / 2; break; case LYX_ALIGN_RIGHT: - x += columnWidth(cell) - cellWidth(cell); - // + interColumnSpace(cell); + x += w; break; + case LYX_ALIGN_DECIMAL: { + // we center when no decimal point + if (cellInfo(cell).decimal_width == 0) { + x += w / 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 + && cellInfo(i).decimal_width != 0) + max_dhoffset = max(max_dhoffset, cellInfo(i).decimal_hoffset); + } + x += max_dhoffset - cellInfo(cell).decimal_hoffset; + } default: // LYX_ALIGN_LEFT: nothing :-) break; @@ -1250,21 +1277,12 @@ int Tabular::textHOffset(idx_type cell) const int Tabular::textVOffset(idx_type cell) const { - int h = rowHeight(cell); - - int y = 0; - switch (getVAlignment(cell)) { - case LYX_VALIGN_TOP: - break; - case LYX_VALIGN_MIDDLE: - y += h/2; - break; - case LYX_VALIGN_BOTTOM: - y += h; - break; + int voffset = cellInfo(cell).voffset; + if (isMultiRow(cell)) { + row_type const row = cellRow(cell); + voffset += (cellHeight(cell) - rowAscent(row) - rowDescent(row))/2; } - - return y; + return voffset; } @@ -1279,8 +1297,9 @@ Tabular::idx_type Tabular::getFirstCellInRow(row_type row) const Tabular::idx_type Tabular::getLastCellInRow(row_type row) const { - col_type c = column_info.size() - 1; - while (cell_info[row][c].multirow == CELL_PART_OF_MULTIROW) + col_type c = ncols() - 1; + while (cell_info[row][c].multirow == CELL_PART_OF_MULTIROW + || cell_info[row][c].multicolumn == CELL_PART_OF_MULTICOLUMN) --c; return cell_info[row][c].cellno; } @@ -1289,7 +1308,7 @@ Tabular::idx_type Tabular::getLastCellInRow(row_type row) const Tabular::row_type Tabular::cellRow(idx_type cell) const { if (cell >= numberofcells) - return row_info.size() - 1; + return nrows() - 1; if (cell == npos) return 0; return rowofcell[cell]; @@ -1299,31 +1318,20 @@ Tabular::row_type Tabular::cellRow(idx_type cell) const Tabular::col_type Tabular::cellColumn(idx_type cell) const { if (cell >= numberofcells) - return column_info.size() - 1; + return ncols() - 1; if (cell == npos) return 0; return columnofcell[cell]; } -Tabular::col_type Tabular::cellRightColumn(idx_type cell) const -{ - row_type const row = cellRow(cell); - col_type column = cellColumn(cell); - while (column < column_info.size() - 1 && - cell_info[row][column + 1].multicolumn == CELL_PART_OF_MULTICOLUMN) - ++column; - return column; -} - - void Tabular::write(ostream & os) const { // header line os << "\n"; // global longtable options os << "\n"; - for (col_type j = 0; j < column_info.size(); ++j) { + for (col_type c = 0; c < ncols(); ++c) { os << "\n"; } - for (row_type i = 0; i < row_info.size(); ++i) { + for (row_type r = 0; r < nrows(); ++r) { static const string def("default"); os << "\n"; - for (col_type j = 0; j < column_info.size(); ++j) { + for (col_type c = 0; c < ncols(); ++c) { os << "\n"; os << "\\begin_inset "; - cell_info[i][j].inset->write(os); + cell_info[r][c].inset->write(os); os << "\n\\end_inset\n" << "\n"; } @@ -1448,20 +1458,21 @@ void Tabular::read(Lexer & lex) getTokenValue(line, "lastFootBottomDL", endlastfoot.bottomDL); getTokenValue(line, "lastFootEmpty", endlastfoot.empty); - for (col_type j = 0; j < column_info.size(); ++j) { + for (col_type c = 0; c < ncols(); ++c) { l_getline(is,line); if (!prefixIs(line," got" << line << ')' << endl; return; } - getTokenValue(line, "alignment", column_info[j].alignment); - getTokenValue(line, "valignment", column_info[j].valignment); - getTokenValue(line, "width", column_info[j].p_width); - getTokenValue(line, "special", column_info[j].align_special); + 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); } - for (row_type i = 0; i < row_info.size(); ++i) { + for (row_type i = 0; i < nrows(); ++i) { l_getline(is, line); if (!prefixIs(line, " got" @@ -1480,7 +1491,7 @@ void Tabular::read(Lexer & lex) getTokenValue(line, "endlastfoot", row_info[i].endlastfoot); getTokenValue(line, "newpage", row_info[i].newpage); getTokenValue(line, "caption", row_info[i].caption); - for (col_type j = 0; j < column_info.size(); ++j) { + for (col_type j = 0; j < ncols(); ++j) { l_getline(is, line); if (!prefixIs(line, " got" @@ -1528,19 +1539,8 @@ void Tabular::read(Lexer & lex) bool Tabular::isMultiColumn(idx_type cell) const { - 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_BEGIN_OF_MULTICOLUMN - || cellInfo(cell).multicolumn == CELL_PART_OF_MULTICOLUMN); + return (cellInfo(cell).multicolumn == CELL_BEGIN_OF_MULTICOLUMN + || cellInfo(cell).multicolumn == CELL_PART_OF_MULTICOLUMN); } @@ -1550,12 +1550,22 @@ Tabular::CellData & Tabular::cellInfo(idx_type cell) const } -void Tabular::setMultiColumn(idx_type cell, idx_type number) +Tabular::idx_type Tabular::setMultiColumn(idx_type cell, idx_type number) { + idx_type const col = cellColumn(cell); + idx_type const row = cellRow(cell); + for (idx_type i = 0; i < number; ++i) + unsetMultiRow(cellIndex(row, col + i)); + + // unsetting of multirow may have invalidated cell index + cell = cellIndex(row, col); CellData & cs = cellInfo(cell); cs.multicolumn = CELL_BEGIN_OF_MULTICOLUMN; - cs.alignment = column_info[cellColumn(cell)].alignment; - setRightLine(cell, rightLine(cell + number - 1)); + if (column_info[col].alignment != LYX_ALIGN_DECIMAL) + cs.alignment = column_info[col].alignment; + if (col > 0) + setRightLine(cell, rightLine(cellIndex(row, col - 1))); + for (idx_type i = 1; i < number; ++i) { CellData & cs1 = cellInfo(cell + i); cs1.multicolumn = CELL_PART_OF_MULTICOLUMN; @@ -1563,6 +1573,7 @@ void Tabular::setMultiColumn(idx_type cell, idx_type number) cs1.inset->clear(); } updateIndexes(); + return cell; } @@ -1573,47 +1584,57 @@ bool Tabular::isMultiRow(idx_type cell) const } -void Tabular::setMultiRow(idx_type cell, idx_type number) +Tabular::idx_type 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(); + idx_type const col = cellColumn(cell); + idx_type const row = cellRow(cell); + for (idx_type i = 0; i < number; ++i) + unsetMultiColumn(cellIndex(row + i, col)); + + // unsetting of multicol may have invalidated cell index + cell = cellIndex(row, col); 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; + // FIXME: the horizontal alignment of multirow cells can only + // be changed for the whole table, + // support for this needs to be implemented but us a fileformat + // change (assigning this to uwestoehr) + // until LyX supports this, use the deault alignment of multirow + // cells: left + cs.alignment = LYX_ALIGN_CENTER; + // set the bottom row of the last selected cell - setBottomLine(cell, bottomLine(cell + (number - 1)*ncolumns)); + setBottomLine(cell, bottomLine(cell + (number - 1)*ncols())); + for (idx_type i = 1; i < number; ++i) { - CellData & cs1 = cell_info[row + i][column]; + CellData & cs1 = cell_info[row + i][col]; cs1.multirow = CELL_PART_OF_MULTIROW; cs.inset->appendParagraphs(cs1.inset->paragraphs()); cs1.inset->clear(); } updateIndexes(); + return cell; } Tabular::idx_type Tabular::columnSpan(idx_type cell) const { row_type const row = cellRow(cell); - col_type const ncols = column_info.size(); - 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; } Tabular::idx_type Tabular::rowSpan(idx_type cell) const { - row_type const nrows = row_info.size(); col_type const column = cellColumn(cell); col_type row = cellRow(cell) + 1; - while (row < nrows && isPartOfMultiRow(row, column)) + while (row < nrows() && isPartOfMultiRow(row, column)) ++row; return row - cellRow(cell); @@ -1622,22 +1643,30 @@ Tabular::idx_type Tabular::rowSpan(idx_type cell) const void Tabular::unsetMultiColumn(idx_type cell) { + if (!isMultiColumn(cell)) + return; + row_type const row = cellRow(cell); - col_type const column = cellColumn(cell); + col_type const col = cellColumn(cell); row_type const span = columnSpan(cell); for (col_type c = 0; c < span; ++c) - cell_info[row][column + c].multicolumn = CELL_NORMAL; + cell_info[row][col + c].multicolumn = CELL_NORMAL; updateIndexes(); } void Tabular::unsetMultiRow(idx_type cell) { + if (!isMultiRow(cell)) + return; + + cellInfo(cell).valignment = LYX_VALIGN_TOP; + cellInfo(cell).alignment = LYX_ALIGN_CENTER; row_type const row = cellRow(cell); - col_type const column = cellColumn(cell); + col_type const col = cellColumn(cell); row_type const span = rowSpan(cell); for (row_type r = 0; r < span; ++r) - cell_info[row + r][column].multirow = CELL_NORMAL; + cell_info[row + r][col].multirow = CELL_NORMAL; updateIndexes(); } @@ -1658,9 +1687,9 @@ bool Tabular::needRotating() const { if (rotate) return true; - for (row_type i = 0; i < row_info.size(); ++i) - for (col_type j = 0; j < column_info.size(); ++j) - if (cell_info[i][j].rotate) + for (row_type r = 0; r < nrows(); ++r) + for (col_type c = 0; c < ncols(); ++c) + if (cell_info[r][c].rotate) return true; return false; } @@ -1691,7 +1720,7 @@ Tabular::idx_type Tabular::cellAbove(idx_type cell) const Tabular::idx_type Tabular::cellBelow(idx_type cell) const { row_type const nextrow = cellRow(cell) + rowSpan(cell); - if (nextrow < row_info.size()) + if (nextrow < nrows()) return cell_info[nextrow][cellColumn(cell)].cellno; return cell; } @@ -1699,8 +1728,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 < column_info.size() - && row != npos && row < row_info.size(), /**/); + LASSERT(column != npos && column < ncols() + && row != npos && row < nrows(), /**/); return cell_info[row][column].cellno; } @@ -1803,7 +1832,7 @@ bool Tabular::getLTNewPage(row_type row) const bool Tabular::haveLTHead() const { - for (row_type i = 0; i < row_info.size(); ++i) + for (row_type i = 0; i < nrows(); ++i) if (row_info[i].endhead) return true; return false; @@ -1814,8 +1843,8 @@ bool Tabular::haveLTFirstHead() const { if (endfirsthead.empty) return false; - for (row_type i = 0; i < row_info.size(); ++i) - if (row_info[i].endfirsthead) + for (row_type r = 0; r < nrows(); ++r) + if (row_info[r].endfirsthead) return true; return false; } @@ -1823,8 +1852,8 @@ bool Tabular::haveLTFirstHead() const bool Tabular::haveLTFoot() const { - for (row_type i = 0; i < row_info.size(); ++i) - if (row_info[i].endfoot) + for (row_type r = 0; r < nrows(); ++r) + if (row_info[r].endfoot) return true; return false; } @@ -1834,8 +1863,8 @@ bool Tabular::haveLTLastFoot() const { if (endlastfoot.empty) return false; - for (row_type i = 0; i < row_info.size(); ++i) - if (row_info[i].endlastfoot) + for (row_type r = 0; r < nrows(); ++r) + if (row_info[r].endlastfoot) return true; return false; } @@ -1868,8 +1897,8 @@ bool Tabular::ltCaption(row_type row) const bool Tabular::haveLTCaption() const { - for (row_type i = 0; i < row_info.size(); ++i) - if (row_info[i].caption) + for (row_type r = 0; r < nrows(); ++r) + if (row_info[r].caption) return true; return false; } @@ -1879,7 +1908,7 @@ bool Tabular::haveLTCaption() const void Tabular::setRowAscent(row_type row, int height) { - if (row >= row_info.size() || row_info[row].ascent == height) + if (row >= nrows() || row_info[row].ascent == height) return; row_info[row].ascent = height; } @@ -1887,7 +1916,7 @@ void Tabular::setRowAscent(row_type row, int height) void Tabular::setRowDescent(row_type row, int height) { - if (row >= row_info.size() || row_info[row].descent == height) + if (row >= nrows() || row_info[row].descent == height) return; row_info[row].descent = height; } @@ -1895,14 +1924,14 @@ void Tabular::setRowDescent(row_type row, int height) int Tabular::rowAscent(row_type row) const { - LASSERT(row < row_info.size(), /**/); + LASSERT(row < nrows(), /**/); return row_info[row].ascent; } int Tabular::rowDescent(row_type row) const { - LASSERT(row < row_info.size(), /**/); + LASSERT(row < nrows(), /**/); return row_info[row].descent; } @@ -1910,7 +1939,7 @@ int Tabular::rowDescent(row_type row) const int Tabular::height() const { int height = 0; - for (row_type row = 0; row < row_info.size(); ++row) + for (row_type row = 0; row < nrows(); ++row) height += rowAscent(row) + rowDescent(row) + interRowSpace(row); return height; @@ -1919,16 +1948,16 @@ int Tabular::height() const bool Tabular::isPartOfMultiColumn(row_type row, col_type column) const { - LASSERT(row < row_info.size(), /**/); - LASSERT(column < column_info.size(), /**/); + LASSERT(row < nrows(), /**/); + LASSERT(column < ncols(), /**/); return cell_info[row][column].multicolumn == CELL_PART_OF_MULTICOLUMN; } bool Tabular::isPartOfMultiRow(row_type row, col_type column) const { - LASSERT(row < row_info.size(), /**/); - LASSERT(column < column_info.size(), /**/); + LASSERT(row < nrows(), /**/); + LASSERT(column < ncols(), /**/); return cell_info[row][column].multirow == CELL_PART_OF_MULTIROW; } @@ -1939,10 +1968,9 @@ int Tabular::TeXTopHLine(odocstream & os, row_type row, string const lang) const // is done in Tabular::TeXBottomHLine(...) // get for each column the topline (if any) - col_type const ncols = column_info.size(); vector topline; col_type nset = 0; - for (col_type c = 0; c < ncols; ++c) { + for (col_type c = 0; c < ncols(); ++c) { topline.push_back(topLine(cellIndex(row, c))); // If cell is part of a multirow and not the first cell of the // multirow, no line must be drawn. @@ -1955,32 +1983,41 @@ int Tabular::TeXTopHLine(odocstream & os, row_type row, string const lang) const } // do nothing if empty first row, or incomplete row line after - if ((row == 0 && nset == 0) || (row > 0 && nset != ncols)) + if ((row == 0 && nset == 0) || (row > 0 && nset != ncols())) return 0; // only output complete row lines and the 1st row's clines - if (nset == ncols) { + if (nset == ncols()) { if (use_booktabs) { os << (row == 0 ? "\\toprule " : "\\midrule "); } else { os << "\\hline "; } } 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 (col_type c = 0; c < ncols(); ++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"; @@ -1994,11 +2031,10 @@ int Tabular::TeXBottomHLine(odocstream & os, row_type row, string const lang) co // if the latter do not span the whole tabular // get the bottomlines of row r, and toplines in next row - bool lastrow = row == row_info.size() - 1; - col_type const ncols = column_info.size(); + bool lastrow = row == nrows() - 1; vector bottomline, topline; bool nextrowset = true; - for (col_type c = 0; c < ncols; ++c) { + for (col_type c = 0; c < ncols(); ++c) { bottomline.push_back(bottomLine(cellIndex(row, c))); topline.push_back(!lastrow && topLine(cellIndex(row + 1, c))); // If cell is part of a multirow and not the last or first cell of the @@ -2014,7 +2050,7 @@ int Tabular::TeXBottomHLine(odocstream & os, row_type row, string const lang) co // combine this row's bottom lines and next row's toplines if necessary col_type nset = 0; - for (col_type c = 0; c < ncols; ++c) { + for (col_type c = 0; c < ncols(); ++c) { if (!nextrowset) bottomline[c] = bottomline[c] || topline[c]; if (bottomline[c]) @@ -2022,30 +2058,39 @@ int Tabular::TeXBottomHLine(odocstream & os, row_type row, string const lang) co } // do nothing if empty, OR incomplete row line with a topline in next row - if (nset == 0 || (nextrowset && nset != ncols)) + if (nset == 0 || (nextrowset && nset != ncols())) return 0; - if (nset == ncols) { + if (nset == ncols()) { if (use_booktabs) os << (lastrow ? "\\bottomrule" : "\\midrule"); else 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 (col_type c = 0; c < ncols(); ++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"; @@ -2069,8 +2114,8 @@ int Tabular::TeXCellPreamble(odocstream & os, idx_type cell, col_type const nextcol = c + columnSpan(cell); bool colright = columnRightLine(c); bool colleft = columnLeftLine(c); - bool nextcolleft = nextcol < column_info.size() && columnLeftLine(nextcol); - bool nextcellleft = nextcol < column_info.size() + bool nextcolleft = nextcol < ncols() && columnLeftLine(nextcol); + bool nextcellleft = nextcol < ncols() && leftLine(cellIndex(r, nextcol)); bool coldouble = colright && nextcolleft; bool celldouble = rightLine(cell) && nextcellleft; @@ -2080,8 +2125,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)); + + // 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()) { @@ -2135,7 +2191,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); @@ -2146,9 +2202,9 @@ int Tabular::TeXCellPreamble(odocstream & os, idx_type cell, else // we need to set a default value // needs to be discussed - os << "2.0cm"; + os << "*"; os << "}{"; - } // end if ismultirow + } // end if ismultirow if (getRotateCell(cell)) { os << "\\begin{sideways}\n"; @@ -2209,9 +2265,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; } @@ -2226,9 +2284,9 @@ int Tabular::TeXLongtableHeaderFooter(odocstream & os, // caption handling // the caption must be output before the headers if (haveLTCaption()) { - for (row_type i = 0; i < row_info.size(); ++i) { - if (row_info[i].caption) { - ret += TeXRow(os, i, runparams); + for (row_type r = 0; r < nrows(); ++r) { + if (row_info[r].caption) { + ret += TeXRow(os, r, runparams); } } } @@ -2240,9 +2298,9 @@ int Tabular::TeXLongtableHeaderFooter(odocstream & os, os << "\\hline\n"; ++ret; } - for (row_type i = 0; i < row_info.size(); ++i) { - if (row_info[i].endfirsthead) { - ret += TeXRow(os, i, runparams); + for (row_type r = 0; r < nrows(); ++r) { + if (row_info[r].endfirsthead) { + ret += TeXRow(os, r, runparams); } } if (endfirsthead.bottomDL) { @@ -2262,9 +2320,9 @@ int Tabular::TeXLongtableHeaderFooter(odocstream & os, os << "\\hline\n"; ++ret; } - for (row_type i = 0; i < row_info.size(); ++i) { - if (row_info[i].endhead) { - ret += TeXRow(os, i, runparams); + for (row_type r = 0; r < nrows(); ++r) { + if (row_info[r].endhead) { + ret += TeXRow(os, r, runparams); } } if (endhead.bottomDL) { @@ -2280,9 +2338,9 @@ int Tabular::TeXLongtableHeaderFooter(odocstream & os, os << "\\hline\n"; ++ret; } - for (row_type i = 0; i < row_info.size(); ++i) { - if (row_info[i].endfoot) { - ret += TeXRow(os, i, runparams); + for (row_type r = 0; r < nrows(); ++r) { + if (row_info[r].endfoot) { + ret += TeXRow(os, r, runparams); } } if (endfoot.bottomDL) { @@ -2302,9 +2360,9 @@ int Tabular::TeXLongtableHeaderFooter(odocstream & os, os << "\\hline\n"; ++ret; } - for (row_type i = 0; i < row_info.size(); ++i) { - if (row_info[i].endlastfoot) { - ret += TeXRow(os, i, runparams); + for (row_type r = 0; r < nrows(); ++r) { + if (row_info[r].endlastfoot) { + ret += TeXRow(os, r, runparams); } } if (endlastfoot.bottomDL) { @@ -2328,43 +2386,48 @@ bool Tabular::isValidRow(row_type row) const } -int Tabular::TeXRow(odocstream & os, row_type i, +int Tabular::TeXRow(odocstream & os, row_type row, OutputParams const & runparams) const { - idx_type cell = cellIndex(i, 0); + idx_type cell = cellIndex(row, 0); shared_ptr inset = cellInset(cell); Paragraph const & par = inset->paragraphs().front(); string const lang = par.getParLanguage(buffer().params())->lang(); //output the top line - int ret = TeXTopHLine(os, i, lang); + int ret = TeXTopHLine(os, row, lang); - if (row_info[i].top_space_default) { + if (row_info[row].top_space_default) { if (use_booktabs) os << "\\addlinespace\n"; else os << "\\noalign{\\vskip\\doublerulesep}\n"; ++ret; - } else if(!row_info[i].top_space.zero()) { + } else if(!row_info[row].top_space.zero()) { if (use_booktabs) os << "\\addlinespace[" - << from_ascii(row_info[i].top_space.asLatexString()) + << from_ascii(row_info[row].top_space.asLatexString()) << "]\n"; else { os << "\\noalign{\\vskip" - << from_ascii(row_info[i].top_space.asLatexString()) + << from_ascii(row_info[row].top_space.asLatexString()) << "}\n"; } ++ret; } bool ismulticol = false; bool ismultirow = false; - for (col_type j = 0; j < column_info.size(); ++j) { - if (isPartOfMultiRow(i, j)) - os << " & "; // we need to add a further column - if (isPartOfMultiColumn(i, j) || isPartOfMultiRow(i, j)) + for (col_type c = 0; c < ncols(); ++c) { + if (isPartOfMultiColumn(row, c)) + continue; + + if (isPartOfMultiRow(row, c) && + column_info[c].alignment != LYX_ALIGN_DECIMAL) { + os << " & "; continue; - cell = cellIndex(i, j); + } + + cell = cellIndex(row, c); ret += TeXCellPreamble(os, cell, ismulticol, ismultirow); shared_ptr inset = cellInset(cell); @@ -2392,55 +2455,70 @@ int Tabular::TeXRow(odocstream & os, row_type i, 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) { + // 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 << '}'; ret += TeXCellPostamble(os, cell, ismulticol, ismultirow); - if (cell != getLastCellInRow(i)) { // not last cell in row + if (cell != getLastCellInRow(row)) { // not last cell in row os << " & "; } } - if (row_info[i].caption && !endfirsthead.empty && !haveLTFirstHead()) + if (row_info[row].caption && !endfirsthead.empty && !haveLTFirstHead()) // if no first header and no empty first header is used, // the caption needs to be terminated by \endfirsthead // (bug 6057) os << "\\endfirsthead"; else os << "\\tabularnewline"; - if (row_info[i].bottom_space_default) { + if (row_info[row].bottom_space_default) { if (use_booktabs) os << "\\addlinespace"; else os << "[\\doublerulesep]"; - } else if (!row_info[i].bottom_space.zero()) { + } else if (!row_info[row].bottom_space.zero()) { if (use_booktabs) os << "\\addlinespace"; os << '[' - << from_ascii(row_info[i].bottom_space.asLatexString()) + << from_ascii(row_info[row].bottom_space.asLatexString()) << ']'; } os << '\n'; ++ret; //output the bottom line - ret += TeXBottomHLine(os, i, lang); + ret += TeXBottomHLine(os, row, lang); - if (row_info[i].interline_space_default) { + if (row_info[row].interline_space_default) { if (use_booktabs) os << "\\addlinespace\n"; else os << "\\noalign{\\vskip\\doublerulesep}\n"; ++ret; - } else if (!row_info[i].interline_space.zero()) { + } else if (!row_info[row].interline_space.zero()) { if (use_booktabs) os << "\\addlinespace[" - << from_ascii(row_info[i].interline_space.asLatexString()) + << from_ascii(row_info[row].interline_space.asLatexString()) << "]\n"; else os << "\\noalign{\\vskip" - << from_ascii(row_info[i].interline_space.asLatexString()) + << from_ascii(row_info[row].interline_space.asLatexString()) << "}\n"; ++ret; } @@ -2488,14 +2566,14 @@ int Tabular::latex(odocstream & os, OutputParams const & runparams) const os << "{"; - for (col_type i = 0; i < column_info.size(); ++i) { - if (columnLeftLine(i)) + for (col_type c = 0; c < ncols(); ++c) { + if (columnLeftLine(c)) os << '|'; - if (!column_info[i].align_special.empty()) { - os << column_info[i].align_special; + if (!column_info[c].align_special.empty()) { + os << column_info[c].align_special; } else { - if (!column_info[i].p_width.zero()) { - switch (column_info[i].alignment) { + if (!column_info[c].p_width.zero()) { + switch (column_info[c].alignment) { case LYX_ALIGN_LEFT: os << ">{\\raggedright}"; break; @@ -2509,10 +2587,11 @@ 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; } - switch (column_info[i].valignment) { + switch (column_info[c].valignment) { case LYX_VALIGN_TOP: os << 'p'; break; @@ -2524,23 +2603,26 @@ int Tabular::latex(odocstream & os, OutputParams const & runparams) const break; } os << '{' - << from_ascii(column_info[i].p_width.asLatexString()) + << from_ascii(column_info[c].p_width.asLatexString()) << '}'; } else { - switch (column_info[i].alignment) { + switch (column_info[c].alignment) { case LYX_ALIGN_LEFT: os << 'l'; break; 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; } } // end if else !column_info[i].p_width } // end if else !column_info[i].align_special - if (columnRightLine(i)) + if (columnRightLine(c)) os << '|'; } os << "}\n"; @@ -2552,10 +2634,10 @@ int Tabular::latex(odocstream & os, OutputParams const & runparams) const //+ the single row and columns (cells) + //+--------------------------------------------------------------------- - for (row_type i = 0; i < row_info.size(); ++i) { - if (isValidRow(i)) { - ret += TeXRow(os, i, runparams); - if (is_long_tabular && row_info[i].newpage) { + for (row_type r = 0; r < nrows(); ++r) { + if (isValidRow(r)) { + ret += TeXRow(os, r, runparams); + if (is_long_tabular && row_info[r].newpage) { os << "\\newpage\n"; ++ret; } @@ -2586,8 +2668,8 @@ int Tabular::docbookRow(odocstream & os, row_type row, idx_type cell = getFirstCellInRow(row); os << "\n"; - for (col_type j = 0; j < column_info.size(); ++j) { - if (isPartOfMultiColumn(row, j)) + for (col_type c = 0; c < ncols(); ++c) { + if (isPartOfMultiColumn(row, c)) continue; os << "'; @@ -2639,12 +2721,12 @@ int Tabular::docbook(odocstream & os, OutputParams const & runparams) const //+ first the opening preamble + //+--------------------------------------------------------------------- - os << "\n"; - for (col_type i = 0; i < column_info.size(); ++i) { - os << "\n"; ++ret; - for (row_type i = 0; i < row_info.size(); ++i) { - if (row_info[i].caption) { - ret += docbookRow(os, i, runparams); + for (row_type r = 0; r < nrows(); ++r) { + if (row_info[r].caption) { + ret += docbookRow(os, r, runparams); } } os << "\n"; @@ -2682,9 +2764,9 @@ int Tabular::docbook(odocstream & os, OutputParams const & runparams) const if (haveLTHead() || haveLTFirstHead()) { os << "\n"; ++ret; - for (row_type i = 0; i < row_info.size(); ++i) { - if (row_info[i].endhead || row_info[i].endfirsthead) { - ret += docbookRow(os, i, runparams); + for (row_type r = 0; r < nrows(); ++r) { + if (row_info[r].endhead || row_info[r].endfirsthead) { + ret += docbookRow(os, r, runparams); } } os << "\n"; @@ -2694,9 +2776,9 @@ int Tabular::docbook(odocstream & os, OutputParams const & runparams) const if (haveLTFoot() || haveLTLastFoot()) { os << "\n"; ++ret; - for (row_type i = 0; i < row_info.size(); ++i) { - if (row_info[i].endfoot || row_info[i].endlastfoot) { - ret += docbookRow(os, i, runparams); + for (row_type r = 0; r < nrows(); ++r) { + if (row_info[r].endfoot || row_info[r].endlastfoot) { + ret += docbookRow(os, r, runparams); } } os << "\n"; @@ -2709,9 +2791,9 @@ int Tabular::docbook(odocstream & os, OutputParams const & runparams) const os << "\n"; ++ret; - for (row_type i = 0; i < row_info.size(); ++i) { - if (isValidRow(i)) { - ret += docbookRow(os, i, runparams); + for (row_type r = 0; r < nrows(); ++r) { + if (isValidRow(r)) { + ret += docbookRow(os, r, runparams); } } os << "\n"; @@ -2734,8 +2816,8 @@ docstring Tabular::xhtmlRow(XHTMLStream & xs, row_type row, idx_type cell = getFirstCellInRow(row); xs << html::StartTag("tr"); - for (col_type j = 0; j < column_info.size(); ++j) { - if (isPartOfMultiColumn(row, j)) + for (col_type c = 0; c < ncols(); ++c) { + if (isPartOfMultiColumn(row, c)) continue; stringstream attr; @@ -2785,9 +2867,9 @@ docstring Tabular::xhtml(XHTMLStream & xs, OutputParams const & runparams) const // We can borrow that too from docbook, if so. xs << html::StartTag("tbody"); - for (row_type i = 0; i < row_info.size(); ++i) { - if (isValidRow(i)) { - ret += xhtmlRow(xs, i, runparams); + for (row_type r = 0; r < nrows(); ++r) { + if (isValidRow(r)) { + ret += xhtmlRow(xs, r, runparams); } } xs << html::EndTag("tbody"); @@ -2825,7 +2907,7 @@ bool Tabular::plaintextTopHLine(odocstream & os, row_type row, } col_type column = cellColumn(i); int len = clen[column]; - while (column < column_info.size() - 1 + while (column < ncols() - 1 && isPartOfMultiColumn(row, ++column)) len += clen[column] + 4; os << docstring(len, ch); @@ -2873,8 +2955,7 @@ bool Tabular::plaintextBottomHLine(odocstream & os, row_type row, } col_type column = cellColumn(i); int len = clen[column]; - while (column < column_info.size() -1 - && isPartOfMultiColumn(row, ++column)) + while (column < ncols() - 1 && isPartOfMultiColumn(row, ++column)) len += clen[column] + 4; os << docstring(len, ch); if (bottomLine(i)) { @@ -2912,8 +2993,7 @@ void Tabular::plaintextPrintCell(odocstream & os, unsigned int len1 = sstr.str().length(); unsigned int len2 = clen[column]; - while (column < column_info.size() -1 - && isPartOfMultiColumn(row, ++column)) + while (column < ncols() - 1 && isPartOfMultiColumn(row, ++column)) len2 += clen[column] + 4; len2 -= len1; @@ -2947,57 +3027,57 @@ void Tabular::plaintext(odocstream & os, bool onlydata, char_type delim) const { // first calculate the width of the single columns - vector clen(column_info.size()); + vector clen(ncols()); if (!onlydata) { - // first all non (real) multicolumn cells! - for (col_type j = 0; j < column_info.size(); ++j) { - clen[j] = 0; - for (row_type i = 0; i < row_info.size(); ++i) { - idx_type cell = cellIndex(i, j); - if (isMultiColumnReal(cell)) + // first all non multicolumn cells! + for (col_type c = 0; c < ncols(); ++c) { + clen[c] = 0; + for (row_type r = 0; r < nrows(); ++r) { + idx_type cell = cellIndex(r, c); + if (isMultiColumn(cell)) continue; odocstringstream sstr; cellInset(cell)->plaintext(sstr, runparams); - if (clen[j] < sstr.str().length()) - clen[j] = sstr.str().length(); + if (clen[c] < sstr.str().length()) + clen[c] = sstr.str().length(); } } - // then all (real) multicolumn cells! - for (col_type j = 0; j < column_info.size(); ++j) { - for (row_type i = 0; i < row_info.size(); ++i) { - idx_type cell = cellIndex(i, j); - if (!isMultiColumnReal(cell) || isPartOfMultiColumn(i, j)) + // then all multicolumn cells! + for (col_type c = 0; c < ncols(); ++c) { + for (row_type r = 0; r < nrows(); ++r) { + idx_type cell = cellIndex(r, c); + if (cell_info[r][c].multicolumn != CELL_BEGIN_OF_MULTICOLUMN) continue; odocstringstream sstr; cellInset(cell)->plaintext(sstr, runparams); int len = int(sstr.str().length()); idx_type const n = columnSpan(cell); - for (col_type k = j; len > 0 && k < j + n - 1; ++k) + for (col_type k = c; len > 0 && k < c + n - 1; ++k) len -= clen[k]; - if (len > int(clen[j + n - 1])) - clen[j + n - 1] = len; + if (len > int(clen[c + n - 1])) + clen[c + n - 1] = len; } } } idx_type cell = 0; - for (row_type i = 0; i < row_info.size(); ++i) { - if (!onlydata && plaintextTopHLine(os, i, clen)) + for (row_type r = 0; r < nrows(); ++r) { + if (!onlydata && plaintextTopHLine(os, r, clen)) os << docstring(depth * 2, ' '); - for (col_type j = 0; j < column_info.size(); ++j) { - if (isPartOfMultiColumn(i, j)) + for (col_type c = 0; c < ncols(); ++c) { + if (isPartOfMultiColumn(r, c)) continue; - if (onlydata && j > 0) + if (onlydata && c > 0) // we don't use operator<< for single UCS4 character. // see explanation in docstream.h os.put(delim); - plaintextPrintCell(os, runparams, cell, i, j, clen, onlydata); + plaintextPrintCell(os, runparams, cell, r, c, clen, onlydata); ++cell; } os << endl; if (!onlydata) { os << docstring(depth * 2, ' '); - if (plaintextBottomHLine(os, i, clen)) + if (plaintextBottomHLine(os, r, clen)) os << docstring(depth * 2, ' '); } } @@ -3088,7 +3168,7 @@ bool InsetTableCell::getStatus(Cursor & cur, FuncRequest const & cmd, FuncStatus & status) const { bool enabled; - switch (cmd.action) { + switch (cmd.action()) { case LFUN_LAYOUT: enabled = !forcePlainLayout(); break; @@ -3165,11 +3245,19 @@ void InsetTabular::setBuffer(Buffer & buf) bool InsetTabular::insetAllowed(InsetCode code) const { - if (code == MATHMACRO_CODE - || (code == CAPTION_CODE && !tabular.is_long_tabular)) + switch (code) { + case FLOAT_CODE: + case MARGIN_CODE: + case MATHMACRO_CODE: + case WRAP_CODE: return false; - return true; + case CAPTION_CODE: + return tabular.is_long_tabular; + + default: + return true; + } } @@ -3211,9 +3299,8 @@ int InsetTabular::rowFromY(Cursor & cur, int y) const { // top y coordinate of tabular int h = yo(cur.bv()) - tabular.rowAscent(0); - size_t nrows = tabular.row_info.size(); row_type r = 0; - for (; r < nrows && y > h; ++r) + for (; r < tabular.nrows() && y > h; ++r) h += tabular.rowAscent(r) + tabular.rowDescent(r) + tabular.interRowSpace(r); @@ -3225,10 +3312,9 @@ int InsetTabular::columnFromX(Cursor & cur, int x) const { // left x coordinate of tabular int w = xo(cur.bv()) + ADD_TO_TABULAR_WIDTH; - size_t ncols = tabular.column_info.size(); col_type c = 0; - for (; c < ncols && x > w; ++c) - w += tabular.columnWidth(c); + for (; c < tabular.ncols() && x > w; ++c) + w += tabular.cellWidth(c); return c - 1; } @@ -3242,40 +3328,81 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const LASSERT(false, /**/); } - for (row_type i = 0; i < tabular.row_info.size(); ++i) { - int maxAsc = 0; - int maxDesc = 0; - for (col_type j = 0; j < tabular.column_info.size(); ++j) { - if (tabular.isPartOfMultiColumn(i, j) - || tabular.isPartOfMultiRow(i, j)) + for (row_type r = 0; r < tabular.nrows(); ++r) { + int maxasc = 0; + int maxdes = 0; + for (col_type c = 0; c < tabular.ncols(); ++c) { + if (tabular.isPartOfMultiColumn(r, c) + || tabular.isPartOfMultiRow(r, c)) // multicolumn or multirow cell, but not first one continue; - idx_type const cell = tabular.cellIndex(i, j); + idx_type const cell = tabular.cellIndex(r, c); Dimension dim; MetricsInfo m = mi; - Length p_width; - if (tabular.cell_info[i][j].multicolumn == - Tabular::CELL_BEGIN_OF_MULTICOLUMN) - p_width = tabular.cellInfo(cell).p_width; - else - p_width = tabular.column_info[j].p_width; + Length const p_width = tabular.getPWidth(cell); if (!p_width.zero()) m.base.textwidth = p_width.inPixels(mi.base.textwidth); tabular.cellInset(cell)->metrics(m, dim); if (!p_width.zero()) dim.wid = m.base.textwidth; - tabular.setCellWidth(cell, dim.wid); - maxAsc = max(maxAsc, dim.asc); - maxDesc = max(maxDesc, dim.des); + tabular.cellInfo(cell).width = dim.wid + 2 * WIDTH_OF_LINE + + tabular.interColumnSpace(cell); + + // 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.getAlignment(cell) == LYX_ALIGN_DECIMAL) { + // 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() + + TEXT_TO_INSET_OFFSET; + int offset = 0; + switch (tabular.getVAlignment(cell)) { + case Tabular::LYX_VALIGN_TOP: + break; + case Tabular::LYX_VALIGN_MIDDLE: + offset = -(dim.des - lastpardes)/2; + break; + case Tabular::LYX_VALIGN_BOTTOM: + offset = -(dim.des - lastpardes); + break; + } + tabular.cell_info[r][c].voffset = offset; + maxasc = max(maxasc, dim.asc - offset); + maxdes = max(maxdes, dim.des + offset); } - int const top_space = tabular.row_info[i].top_space_default ? + int const top_space = tabular.row_info[r].top_space_default ? default_line_space : - tabular.row_info[i].top_space.inPixels(mi.base.textwidth); - tabular.setRowAscent(i, maxAsc + ADD_TO_HEIGHT + top_space); - int const bottom_space = tabular.row_info[i].bottom_space_default ? + tabular.row_info[r].top_space.inPixels(mi.base.textwidth); + 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[i].bottom_space.inPixels(mi.base.textwidth); - tabular.setRowDescent(i, maxDesc + ADD_TO_HEIGHT + bottom_space); + tabular.row_info[r].bottom_space.inPixels(mi.base.textwidth); + tabular.setRowDescent(r, maxdes + ADD_TO_HEIGHT + bottom_space); } tabular.updateColumnWidths(); dim.asc = tabular.rowAscent(0); @@ -3283,6 +3410,7 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const dim.wid = tabular.width() + 2 * ADD_TO_TABULAR_WIDTH; } + bool InsetTabular::isCellSelected(Cursor & cur, row_type row, col_type col) const { @@ -3292,7 +3420,11 @@ bool InsetTabular::isCellSelected(Cursor & cur, row_type row, col_type col) col_type cs, ce; getSelection(cur, rs, re, cs, ce); - if (col >= cs && col <= ce && row >= rs && row <= re) + idx_type const cell = tabular.cellIndex(row, col); + col_type const cspan = tabular.columnSpan(cell); + row_type const rspan = tabular.rowSpan(cell); + if (col + cspan - 1 >= cs && col <= ce + && row + rspan - 1 >= rs && row <= re) return true; } else if (col == tabular.cellColumn(cur.idx()) @@ -3326,36 +3458,36 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const idx_type idx = 0; first_visible_cell = Tabular::npos; - for (row_type i = 0; i < tabular.row_info.size(); ++i) { + for (row_type r = 0; r < tabular.nrows(); ++r) { int nx = x; - for (col_type j = 0; j < tabular.column_info.size(); ++j) { - if (tabular.isPartOfMultiColumn(i, j)) + for (col_type c = 0; c < tabular.ncols(); ++c) { + if (tabular.isPartOfMultiColumn(r, c)) continue; - idx = tabular.cellIndex(i, j); + idx = tabular.cellIndex(r, c); - if (tabular.isPartOfMultiRow(i, j)) { - nx += tabular.columnWidth(idx); + if (tabular.isPartOfMultiRow(r, c)) { + nx += tabular.cellWidth(idx); continue; } if (first_visible_cell == Tabular::npos) first_visible_cell = idx; - pi.selected |= isCellSelected(cur, i, j); + pi.selected |= isCellSelected(cur, r, c); int const cx = nx + tabular.textHOffset(idx); int const cy = y + tabular.textVOffset(idx); // Cache the Inset position. - bv->coordCache().insets().add(cell(idx).get(), cx, y); + bv->coordCache().insets().add(cell(idx).get(), cx, cy); cell(idx)->draw(pi, cx, cy); - drawCellLines(pi.pain, nx, y, i, idx, pi.change_); - nx += tabular.columnWidth(idx); + drawCellLines(pi.pain, nx, y, r, idx, pi.change_); + nx += tabular.cellWidth(idx); pi.selected = original_selection_state; } - if (i + 1 < tabular.row_info.size()) - y += tabular.rowDescent(i) + tabular.rowAscent(i + 1) - + tabular.interRowSpace(i + 1); + if (r + 1 < tabular.nrows()) + y += tabular.rowDescent(r) + tabular.rowAscent(r + 1) + + tabular.interRowSpace(r + 1); } } @@ -3387,26 +3519,26 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const tabular.cellRow(cur.idx()), tabular.cellColumn(cur.idx())); if (cur.selIsMultiCell() || full_cell_selected) { - y -= tabular.rowAscent(0); - for (row_type r = 0; r < tabular.row_info.size(); ++r) { + for (row_type r = 0; r < tabular.nrows(); ++r) { int xx = x; - for (col_type c = 0; c < tabular.column_info.size(); ++c) { + for (col_type c = 0; c < tabular.ncols(); ++c) { if (tabular.isPartOfMultiColumn(r, c)) continue; idx_type const cell = tabular.cellIndex(r, c); if (tabular.isPartOfMultiRow(r, c)) { - xx += tabular.columnWidth(cell); + xx += tabular.cellWidth(cell); continue; } - int const w = tabular.columnWidth(cell); - int const h = tabular.rowHeight(cell); + int const w = tabular.cellWidth(cell); + int const h = tabular.cellHeight(cell); + int const yy = y - tabular.rowAscent(r); if (isCellSelected(cur, r, c)) - pi.pain.fillRectangle(xx, y, w, h, Color_selection); + pi.pain.fillRectangle(xx, yy, w, h, Color_selection); xx += w; } - if (r + 1 < tabular.row_info.size()) + if (r + 1 < tabular.nrows()) y += tabular.rowDescent(r) + tabular.rowAscent(r + 1) + tabular.interRowSpace(r + 1); } @@ -3420,49 +3552,43 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const void InsetTabular::drawCellLines(Painter & pain, int x, int y, - row_type row, idx_type cell, Change const & change) const -{ - y = y - tabular.rowAscent(row); - int const w = tabular.columnWidth(cell); - int const h = tabular.rowHeight(cell); - bool on_off = false; - Color col = Color_tabularline; - Color onoffcol = Color_tabularonoffline; - - if (change.changed()) { - col = change.color(); - onoffcol = change.color(); - } - - bool topalreadydrawn = row > 0 && !tabular.rowTopLine(row) - && tabular.bottomLine(tabular.cellAbove(cell)); - - if (!topalreadydrawn) { - on_off = !tabular.topLine(cell); - pain.line(x, y, x + w, y, - on_off ? onoffcol : col, - on_off ? Painter::line_onoffdash : Painter::line_solid); - } - on_off = !tabular.bottomLine(cell); + row_type row, idx_type cell, Change const & change) const +{ + y -= tabular.rowAscent(row); + int const w = tabular.cellWidth(cell); + int const h = tabular.cellHeight(cell); + Color linecolor = change.changed() ? change.color() : Color_tabularline; + Color gridcolor = change.changed() ? change.color() : Color_tabularonoffline; + + // Top + bool drawline = tabular.topLine(cell) + || (row > 0 && tabular.bottomLine(tabular.cellAbove(cell))); + pain.line(x, y, x + w, y, + drawline ? linecolor : gridcolor, + drawline ? Painter::line_solid : Painter::line_onoffdash); + + // Bottom + drawline = tabular.bottomLine(cell); pain.line(x, y + h, x + w, y + h, - on_off ? onoffcol : col, - on_off ? Painter::line_onoffdash : Painter::line_solid); + drawline ? linecolor : gridcolor, + drawline ? Painter::line_solid : Painter::line_onoffdash); - col_type const column = tabular.cellColumn(cell); - bool leftalreadydrawn = column > 0 && !tabular.leftLine(cell) - && tabular.rightLine(tabular.cellIndex(row, column - 1)); + // Left + col_type const col = tabular.cellColumn(cell); + drawline = tabular.leftLine(cell) + || (col > 0 && tabular.rightLine(tabular.cellIndex(row, col - 1))); + pain.line(x, y, x, y + h, + drawline ? linecolor : gridcolor, + drawline ? Painter::line_solid : Painter::line_onoffdash); - if (!leftalreadydrawn) { - on_off = !tabular.leftLine(cell); - pain.line(x, y, x, y + h, - on_off ? onoffcol : col, - on_off ? Painter::line_onoffdash : Painter::line_solid); - } - on_off = !tabular.rightLine(cell); - pain.line(x + w - tabular.interColumnSpace(cell), y, - x + w - tabular.interColumnSpace(cell), y + h, - on_off ? onoffcol : col, - on_off ? Painter::line_onoffdash : Painter::line_solid); + // Right + x -= tabular.interColumnSpace(cell); + drawline = tabular.rightLine(cell) + || (col + 1 < tabular.ncols() + && tabular.leftLine(tabular.cellIndex(row, col + 1))); + pain.line(x + w, y, x + w, y + h, + drawline ? linecolor : gridcolor, + drawline ? Painter::line_solid : Painter::line_onoffdash); } @@ -3481,7 +3607,7 @@ void InsetTabular::edit(Cursor & cur, bool front, EntryDirection) cur.pos() = 0; } else { if (isRightToLeft(cur)) - cur.idx() = tabular.getFirstCellInRow(tabular.row_info.size() - 1); + cur.idx() = tabular.getFirstCellInRow(tabular.nrows() - 1); else cur.idx() = tabular.numberofcells - 1; cur.pit() = 0; @@ -3531,14 +3657,16 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) CursorSlice sl = cur.top(); Cursor & bvcur = cur.bv().cursor(); - switch (cmd.action) { + FuncCode const act = cmd.action(); + + switch (act) { case LFUN_MOUSE_PRESS: { //lyxerr << "# InsetTabular::MousePress\n" << cur.bv().cursor() << endl; // select row - if (cmd.x < xo(cur.bv()) + ADD_TO_TABULAR_WIDTH - || cmd.x > xo(cur.bv()) + tabular.width()) { - row_type r = rowFromY(cur, cmd.y); + if (cmd.x() < xo(cur.bv()) + ADD_TO_TABULAR_WIDTH + || cmd.x() > xo(cur.bv()) + tabular.width()) { + row_type r = rowFromY(cur, cmd.y()); cur.idx() = tabular.getFirstCellInRow(r); cur.pos() = 0; cur.resetAnchor(); @@ -3551,13 +3679,13 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) } // select column int const y0 = yo(cur.bv()) - tabular.rowAscent(0); - if (cmd.y < y0 + ADD_TO_TABULAR_WIDTH - || cmd.y > y0 + tabular.height()) { - col_type c = columnFromX(cur, cmd.x); + if (cmd.y() < y0 + ADD_TO_TABULAR_WIDTH + || cmd.y() > y0 + tabular.height()) { + col_type c = columnFromX(cur, cmd.x()); cur.idx() = tabular.cellIndex(0, c); cur.pos() = 0; cur.resetAnchor(); - cur.idx() = tabular.cellIndex(tabular.row_info.size() - 1, c); + cur.idx() = tabular.cellIndex(tabular.nrows() - 1, c); cur.pos() = cur.lastpos(); cur.setSelection(true); bvcur = cur; @@ -3579,13 +3707,13 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) //lyxerr << "# InsetTabular::MouseMotion\n" << bvcur << endl; if (cmd.button() == mouse_button::button1) { // only accept motions to places not deeper nested than the real anchor - if (!bvcur.anchor_.hasPart(cur)) { + if (!bvcur.realAnchor().hasPart(cur)) { cur.undispatched(); break; } // select (additional) row if (rowselect_) { - row_type r = rowFromY(cur, cmd.y); + row_type r = rowFromY(cur, cmd.y()); cur.idx() = tabular.getLastCellInRow(r); // we need to reset the cursor's pit and pos now, as the old ones // may no longer be valid. @@ -3597,8 +3725,8 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) } // select (additional) column if (colselect_) { - col_type c = columnFromX(cur, cmd.x); - cur.idx() = tabular.cellIndex(tabular.row_info.size() - 1, c); + col_type c = columnFromX(cur, cmd.x()); + cur.idx() = tabular.cellIndex(tabular.nrows() - 1, c); // we need to reset the cursor's pit and pos now, as the old ones // may no longer be valid. cur.pit() = 0; @@ -3609,9 +3737,9 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) } // only update if selection changes if (bvcur.idx() == cur.idx() && - !(bvcur.anchor_.idx() == cur.idx() && bvcur.pos() != cur.pos())) - cur.noUpdate(); - setCursorFromCoordinates(cur, cmd.x, cmd.y); + !(bvcur.realAnchor().idx() == cur.idx() && bvcur.pos() != cur.pos())) + cur.noScreenUpdate(); + setCursorFromCoordinates(cur, cmd.x(), cmd.y()); bvcur.setCursor(cur); bvcur.setSelection(true); // if this is a multicell selection, we just set the cursor to @@ -3653,21 +3781,21 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) EntryDirection entry_from = ENTRY_DIRECTION_IGNORE; FuncCode finish_lfun; - if (cmd.action == LFUN_CHAR_FORWARD - || cmd.action == LFUN_CHAR_FORWARD_SELECT) { + if (act == LFUN_CHAR_FORWARD + || act == LFUN_CHAR_FORWARD_SELECT) { next_cell = true; finish_lfun = LFUN_FINISHED_FORWARD; } - else if (cmd.action == LFUN_CHAR_BACKWARD - || cmd.action == LFUN_CHAR_BACKWARD_SELECT) { + else if (act == LFUN_CHAR_BACKWARD + || act == LFUN_CHAR_BACKWARD_SELECT) { next_cell = false; finish_lfun = LFUN_FINISHED_BACKWARD; } // LEFT or RIGHT commands --- the interpretation will depend on the // table's direction. else { - bool const right = cmd.action == LFUN_CHAR_RIGHT - || cmd.action == LFUN_CHAR_RIGHT_SELECT; + bool const right = act == LFUN_CHAR_RIGHT + || act == LFUN_CHAR_RIGHT_SELECT; next_cell = isRightToLeft(cur) != right; if (lyxrc.visual_cursor) @@ -3676,10 +3804,10 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) finish_lfun = right ? LFUN_FINISHED_RIGHT : LFUN_FINISHED_LEFT; } - bool const select = cmd.action == LFUN_CHAR_FORWARD_SELECT || - cmd.action == LFUN_CHAR_BACKWARD_SELECT || - cmd.action == LFUN_CHAR_RIGHT_SELECT || - cmd.action == LFUN_CHAR_LEFT_SELECT; + bool const select = act == LFUN_CHAR_FORWARD_SELECT || + act == LFUN_CHAR_BACKWARD_SELECT || + act == LFUN_CHAR_RIGHT_SELECT || + act == LFUN_CHAR_LEFT_SELECT; // If we have a multicell selection or we're // not doing some LFUN_*_SELECT thing anyway... @@ -3741,8 +3869,8 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) // if our Text didn't do anything to the cursor // then we try to put the cursor into the cell below // setting also the right targetX. - cur.selHandle(cmd.action == LFUN_DOWN_SELECT); - if (tabular.cellRow(cur.idx()) != tabular.row_info.size() - 1) { + cur.selHandle(act == LFUN_DOWN_SELECT); + if (tabular.cellRow(cur.idx()) != tabular.nrows() - 1) { cur.idx() = tabular.cellBelow(cur.idx()); cur.pit() = 0; TextMetrics const & tm = @@ -3774,7 +3902,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) // if our Text didn't do anything to the cursor // then we try to put the cursor into the cell above // setting also the right targetX. - cur.selHandle(cmd.action == LFUN_UP_SELECT); + cur.selHandle(act == LFUN_UP_SELECT); if (tabular.cellRow(cur.idx()) != 0) { cur.idx() = tabular.cellAbove(cur.idx()); cur.pit() = cur.lastpit(); @@ -3804,7 +3932,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) // col_type const col = tabular.cellColumn(cur.idx()); // int const t = cur.bv().top_y() + cur.bv().height(); // if (t < yo() + tabular.getHeightOfTabular()) { -// cur.bv().scrollDocView(t); +// cur.bv().scrollDocView(t, true); // cur.idx() = tabular.cellBelow(first_visible_cell) + col; // } else { // cur.idx() = tabular.getFirstCellInRow(tabular.rows() - 1) + col; @@ -3820,7 +3948,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) // col_type const col = tabular.cellColumn(cur.idx()); // int const t = cur.bv().top_y() + cur.bv().height(); // if (yo() < 0) { -// cur.bv().scrollDocView(t); +// cur.bv().scrollDocView(t, true); // if (yo() > 0) // cur.idx() = col; // else @@ -3902,7 +4030,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) case LFUN_CLIPBOARD_PASTE: case LFUN_PRIMARY_SELECTION_PASTE: { - docstring const clip = (cmd.action == LFUN_CLIPBOARD_PASTE) ? + docstring const clip = (act == LFUN_CLIPBOARD_PASTE) ? theClipboard().getAsText() : theSelection().get(); if (clip.empty()) @@ -3964,10 +4092,10 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) col_type cs, ce; getSelection(cur, rs, re, cs, ce); Cursor tmpcur = cur; - for (row_type i = rs; i <= re; ++i) { - for (col_type j = cs; j <= ce; ++j) { + for (row_type r = rs; r <= re; ++r) { + for (col_type c = cs; c <= ce; ++c) { // cursor follows cell: - tmpcur.idx() = tabular.cellIndex(i, j); + tmpcur.idx() = tabular.cellIndex(r, c); // select this cell only: tmpcur.pit() = 0; tmpcur.pos() = 0; @@ -4003,35 +4131,28 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd) bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, FuncStatus & status) const { - switch (cmd.action) { + switch (cmd.action()) { case LFUN_INSET_MODIFY: { - istringstream is(to_utf8(cmd.argument())); - string s; - is >> s; - if (insetCode(s) != TABULAR_CODE) { - status.clear(); - status.setEnabled(false); + if (&cur.inset() != this || cmd.getArg(0) != "tabular") break; - } - is >> s; + + string const s = cmd.getArg(1); // FIXME: We only check for the very first argument... int action = Tabular::LAST_ACTION; int i = 0; for (; tabularFeature[i].action != Tabular::LAST_ACTION; ++i) { - string const tmp = tabularFeature[i].feature; - if (tmp == s.substr(0, tmp.length())) { + if (tabularFeature[i].feature == s) { action = tabularFeature[i].action; break; } } if (action == Tabular::LAST_ACTION) { status.clear(); - status.unknown(true); + status.setUnknown(true); return true; } - string const argument - = ltrim(s.substr(tabularFeature[i].feature.length())); + string const argument = cmd.getLongArg(2); row_type sel_row_start = 0; row_type sel_row_end = 0; @@ -4060,23 +4181,24 @@ 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. - // don't allow to set a multirow as multicolumn status.setEnabled(sel_row_start == sel_row_end - && !tabular.ltCaption(tabular.cellRow(cur.idx())) - && !tabular.isMultiRow(cur.idx()) ); + && !tabular.ltCaption(tabular.cellRow(cur.idx()))); 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. - // don't allow to set a multicolumn as multirow status.setEnabled(sel_col_start == sel_col_end - && !tabular.ltCaption(tabular.cellRow(cur.idx())) - && !tabular.isMultiColumn(cur.idx()) ); + && !tabular.ltCaption(tabular.cellRow(cur.idx()))); status.setOnOff(tabular.isMultiRow(cur.idx())); break; @@ -4116,29 +4238,41 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, case Tabular::M_ALIGN_LEFT: flag = false; case Tabular::ALIGN_LEFT: + status.setEnabled(!tabular.isMultiRow(cur.idx())); status.setOnOff(tabular.getAlignment(cur.idx(), flag) == LYX_ALIGN_LEFT); break; case Tabular::M_ALIGN_RIGHT: flag = false; case Tabular::ALIGN_RIGHT: + status.setEnabled(!tabular.isMultiRow(cur.idx())); status.setOnOff(tabular.getAlignment(cur.idx(), flag) == LYX_ALIGN_RIGHT); break; case Tabular::M_ALIGN_CENTER: flag = false; case Tabular::ALIGN_CENTER: + status.setEnabled(!tabular.isMultiRow(cur.idx())); status.setOnOff(tabular.getAlignment(cur.idx(), flag) == LYX_ALIGN_CENTER); break; case Tabular::ALIGN_BLOCK: - status.setEnabled(!tabular.getPWidth(cur.idx()).zero()); + status.setEnabled(!tabular.getPWidth(cur.idx()).zero() + && !tabular.isMultiRow(cur.idx())); 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: + status.setEnabled(!tabular.getPWidth(cur.idx()).zero() + && !tabular.isMultiRow(cur.idx())); status.setOnOff( tabular.getVAlignment(cur.idx(), flag) == Tabular::LYX_VALIGN_TOP); break; @@ -4146,6 +4280,8 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, case Tabular::M_VALIGN_BOTTOM: flag = false; case Tabular::VALIGN_BOTTOM: + status.setEnabled(!tabular.getPWidth(cur.idx()).zero() + && !tabular.isMultiRow(cur.idx())); status.setOnOff( tabular.getVAlignment(cur.idx(), flag) == Tabular::LYX_VALIGN_BOTTOM); break; @@ -4153,6 +4289,8 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, case Tabular::M_VALIGN_MIDDLE: flag = false; case Tabular::VALIGN_MIDDLE: + status.setEnabled(!tabular.getPWidth(cur.idx()).zero() + && !tabular.isMultiRow(cur.idx())); status.setOnOff( tabular.getVAlignment(cur.idx(), flag) == Tabular::LYX_VALIGN_MIDDLE); break; @@ -4310,11 +4448,12 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_MATH_MUTATE: case LFUN_MATH_DISPLAY: case LFUN_NOTE_INSERT: - case LFUN_OPTIONAL_INSERT: + case LFUN_ARGUMENT_INSERT: case LFUN_BOX_INSERT: case LFUN_BRANCH_INSERT: case LFUN_PHANTOM_INSERT: case LFUN_WRAP_INSERT: + case LFUN_PREVIEW_INSERT: case LFUN_ERT_INSERT: { if (cur.selIsMultiCell()) { status.setEnabled(false); @@ -4343,8 +4482,8 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, row_type rs, re; col_type cs, ce; getSelection(cur, rs, re, cs, ce); - if (paste_tabular && paste_tabular->column_info.size() == ce - cs + 1 - && paste_tabular->row_info.size() == re - rs + 1) + if (paste_tabular && paste_tabular->ncols() == ce - cs + 1 + && paste_tabular->nrows() == re - rs + 1) status.setEnabled(true); else { status.setEnabled(false); @@ -4475,16 +4614,10 @@ void InsetTabular::cursorPos(BufferView const & bv, int const col = tabular.cellColumn(sl.idx()); // y offset correction - for (int i = 0; i <= row; ++i) { - if (tabular.isPartOfMultiRow(i, col)) - continue; - if (i != 0) { - y += tabular.rowAscent(i); - y += tabular.interRowSpace(i); - } - if (i != row) - y += tabular.rowDescent(i); - } + for (int r = 0; r < row; ++r) + y += tabular.rowDescent(r) + tabular.rowAscent(r + 1) + + tabular.interRowSpace(r + 1); + y += tabular.textVOffset(sl.idx()); // x offset correction @@ -4504,11 +4637,11 @@ int InsetTabular::dist(BufferView & bv, idx_type const cell, int x, int y) const Inset const & inset = *tabular.cellInset(cell); Point o = bv.coordCache().getInsets().xy(&inset); int const xbeg = o.x_ - tabular.textHOffset(cell); - int const xend = xbeg + tabular.columnWidth(cell); + int const xend = xbeg + tabular.cellWidth(cell); row_type const row = tabular.cellRow(cell); int const ybeg = o.y_ - tabular.rowAscent(row) - tabular.interRowSpace(row); - int const yend = o.y_ + tabular.rowDescent(row); + int const yend = ybeg + tabular.cellHeight(cell); if (x < xbeg) xx = xbeg - x; @@ -4568,7 +4701,7 @@ int InsetTabular::cellXPos(idx_type const cell) const col_type col = tabular.cellColumn(cell); int lx = 0; for (col_type c = 0; c < col; ++c) - lx += tabular.columnWidth(c); + lx += tabular.column_info[c].width; return lx; } @@ -4588,7 +4721,7 @@ void InsetTabular::resetPos(Cursor & cur) const int const X2 = maxwidth; int const offset = ADD_TO_TABULAR_WIDTH + 2; int const x1 = xo(cur.bv()) + cellXPos(cur[i].idx()) + offset; - int const x2 = x1 + tabular.columnWidth(cur[i].idx()); + int const x2 = x1 + tabular.cellWidth(cur[i].idx()); if (x1 < X1) scx_ = X1 + 20 - x1; @@ -4600,7 +4733,7 @@ void InsetTabular::resetPos(Cursor & cur) const // only update if offset changed if (scx_ != scx_old) - cur.updateFlags(Update::Force | Update::FitCursor); + cur.screenUpdateFlags(Update::Force | Update::FitCursor); } @@ -4611,7 +4744,7 @@ void InsetTabular::moveNextCell(Cursor & cur, EntryDirection entry_from) if (isRightToLeft(cur)) { if (tabular.cellColumn(cur.idx()) == 0) { - if (row == tabular.row_info.size() - 1) + if (row == tabular.nrows() - 1) return; cur.idx() = tabular.cellBelow(tabular.getLastCellInRow(row)); } else { @@ -4627,8 +4760,10 @@ void InsetTabular::moveNextCell(Cursor & cur, EntryDirection entry_from) return; if (cur.idx() == tabular.getLastCellInRow(row)) cur.idx() = tabular.cellIndex(row + 1, 0); - else - cur.idx() = tabular.cellIndex(row, col + 1); + else { + col_type const colnextcell = col + tabular.columnSpan(cur.idx()); + cur.idx() = tabular.cellIndex(row, colnextcell); + } } cur.boundary(false); @@ -4782,18 +4917,16 @@ static void checkLongtableSpecial(Tabular::ltType & ltt, } } + bool InsetTabular::oneCellHasRotationState(bool rotated, row_type row_start, row_type row_end, - col_type col_start, col_type col_end) const { - - for (row_type i = row_start; i <= row_end; ++i) { - for (col_type j = col_start; j <= col_end; ++j) { - if (tabular.getRotateCell(tabular.cellIndex(i, j)) - == rotated) { + col_type col_start, col_type col_end) const +{ + for (row_type r = row_start; r <= row_end; ++r) + for (col_type c = col_start; c <= col_end; ++c) + if (tabular.getRotateCell(tabular.cellIndex(r, c)) == rotated) return true; - } - } - } + return false; } @@ -4829,6 +4962,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; @@ -4880,7 +5017,7 @@ void InsetTabular::tabularFeatures(Cursor & cur, break; case Tabular::SET_SPECIAL_MULTIROW: - //FIXME: noting to do here? + // nothing to do break; case Tabular::APPEND_ROW: @@ -4895,9 +5032,9 @@ void InsetTabular::tabularFeatures(Cursor & cur, break; case Tabular::DELETE_ROW: - for (row_type i = sel_row_start; i <= sel_row_end; ++i) + for (row_type r = sel_row_start; r <= sel_row_end; ++r) tabular.deleteRow(sel_row_start); - if (sel_row_start >= tabular.row_info.size()) + if (sel_row_start >= tabular.nrows()) --sel_row_start; cur.idx() = tabular.cellIndex(sel_row_start, column); cur.pit() = 0; @@ -4906,9 +5043,9 @@ void InsetTabular::tabularFeatures(Cursor & cur, break; case Tabular::DELETE_COLUMN: - for (col_type i = sel_col_start; i <= sel_col_end; ++i) + for (col_type c = sel_col_start; c <= sel_col_end; ++c) tabular.deleteColumn(sel_col_start); - if (sel_col_start >= tabular.column_info.size()) + if (sel_col_start >= tabular.ncols()) --sel_col_start; cur.idx() = tabular.cellIndex(row, sel_col_start); cur.pit() = 0; @@ -4929,9 +5066,9 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::TOGGLE_LINE_TOP: { bool lineSet = (feature == Tabular::SET_LINE_TOP) ? (value == "true") : !tabular.topLine(cur.idx()); - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - for (col_type j = sel_col_start; j <= sel_col_end; ++j) - tabular.setTopLine(tabular.cellIndex(i, j), lineSet); + 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.setTopLine(tabular.cellIndex(r, c), lineSet); break; } @@ -4939,9 +5076,9 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::TOGGLE_LINE_BOTTOM: { bool lineSet = (feature == Tabular::SET_LINE_BOTTOM) ? (value == "true") : !tabular.bottomLine(cur.idx()); - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - for (col_type j = sel_col_start; j <= sel_col_end; ++j) - tabular.setBottomLine(tabular.cellIndex(i, j), lineSet); + 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.setBottomLine(tabular.cellIndex(r, c), lineSet); break; } @@ -4949,9 +5086,9 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::TOGGLE_LINE_LEFT: { bool lineSet = (feature == Tabular::SET_LINE_LEFT) ? (value == "true") : !tabular.leftLine(cur.idx()); - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - for (col_type j = sel_col_start; j <= sel_col_end; ++j) - tabular.setLeftLine(tabular.cellIndex(i, j), lineSet); + 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.setLeftLine(tabular.cellIndex(r, c), lineSet); break; } @@ -4959,9 +5096,9 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::TOGGLE_LINE_RIGHT: { bool lineSet = (feature == Tabular::SET_LINE_RIGHT) ? (value == "true") : !tabular.rightLine(cur.idx()); - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - for (col_type j = sel_col_start; j <= sel_col_end; ++j) - tabular.setRightLine(tabular.cellIndex(i, j), lineSet); + 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.setRightLine(tabular.cellIndex(r, c), lineSet); break; } @@ -4973,9 +5110,10 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::ALIGN_RIGHT: case Tabular::ALIGN_CENTER: case Tabular::ALIGN_BLOCK: - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - for (col_type j = sel_col_start; j <= sel_col_end; ++j) - tabular.setAlignment(tabular.cellIndex(i, j), setAlign, flag); + 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); break; case Tabular::M_VALIGN_TOP: @@ -4985,9 +5123,9 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::VALIGN_TOP: case Tabular::VALIGN_BOTTOM: case Tabular::VALIGN_MIDDLE: - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - for (col_type j = sel_col_start; j <= sel_col_end; ++j) - tabular.setVAlignment(tabular.cellIndex(i, j), setVAlign, flag); + 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.setVAlignment(tabular.cellIndex(r, c), setVAlign, flag); break; case Tabular::MULTICOLUMN: { @@ -5005,8 +5143,7 @@ void InsetTabular::tabularFeatures(Cursor & cur, idx_type const s_start = cur.selBegin().idx(); row_type const col_start = tabular.cellColumn(s_start); row_type const col_end = tabular.cellColumn(cur.selEnd().idx()); - tabular.setMultiColumn(s_start, col_end - col_start + 1); - cur.idx() = s_start; + cur.idx() = tabular.setMultiColumn(s_start, col_end - col_start + 1); cur.pit() = 0; cur.pos() = 0; cur.setSelection(false); @@ -5028,8 +5165,7 @@ void InsetTabular::tabularFeatures(Cursor & cur, idx_type const s_start = cur.selBegin().idx(); row_type const row_start = tabular.cellRow(s_start); row_type const row_end = tabular.cellRow(cur.selEnd().idx()); - tabular.setMultiRow(s_start, row_end - row_start + 1); - cur.idx() = s_start; + cur.idx() = tabular.setMultiRow(s_start, row_end - row_start + 1); cur.pit() = 0; cur.pos() = 0; cur.setSelection(false); @@ -5039,20 +5175,24 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::SET_ALL_LINES: setLines = true; case Tabular::UNSET_ALL_LINES: - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - for (col_type j = sel_col_start; j <= sel_col_end; ++j) - tabular.setAllLines( - tabular.cellIndex(i,j), setLines); + for (row_type r = sel_row_start; r <= sel_row_end; ++r) + for (col_type c = sel_col_start; c <= sel_col_end; ++c) { + idx_type const cell = tabular.cellIndex(r, c); + tabular.setTopLine(cell, setLines); + tabular.setBottomLine(cell, setLines); + tabular.setRightLine(cell, setLines); + tabular.setLeftLine(cell, setLines); + } break; case Tabular::SET_BORDER_LINES: - for (row_type i = sel_row_start; i <= sel_row_end; ++i) { - tabular.setLeftLine(tabular.cellIndex(i, sel_col_start), true); - tabular.setRightLine(tabular.cellIndex(i, sel_col_end), true); + for (row_type r = sel_row_start; r <= sel_row_end; ++r) { + tabular.setLeftLine(tabular.cellIndex(r, sel_col_start), true); + tabular.setRightLine(tabular.cellIndex(r, sel_col_end), true); } - for (col_type j = sel_col_start; j <= sel_col_end; ++j) { - tabular.setTopLine(tabular.cellIndex(sel_row_start, j), true); - tabular.setBottomLine(tabular.cellIndex(sel_row_end, j), true); + for (col_type c = sel_col_start; c <= sel_col_end; ++c) { + tabular.setTopLine(tabular.cellIndex(sel_row_start, c), true); + tabular.setBottomLine(tabular.cellIndex(sel_row_end, c), true); } break; @@ -5061,9 +5201,9 @@ void InsetTabular::tabularFeatures(Cursor & cur, break; case Tabular::UNSET_LONGTABULAR: - for (row_type i = 0; i < tabular.row_info.size(); ++i) { - if (tabular.ltCaption(i)) { - cur.idx() = tabular.cellIndex(i, 0); + for (row_type r = 0; r < tabular.nrows(); ++r) { + if (tabular.ltCaption(r)) { + cur.idx() = tabular.cellIndex(r, 0); cur.pit() = 0; cur.pos() = 0; tabularFeatures(cur, Tabular::TOGGLE_LTCAPTION); @@ -5111,16 +5251,15 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::SET_ROTATE_CELL: - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - for (col_type j = sel_col_start; j <= sel_col_end; ++j) - tabular.setRotateCell( - tabular.cellIndex(i, j), true); + 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.setRotateCell(tabular.cellIndex(r, c), true); break; case Tabular::UNSET_ROTATE_CELL: - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - for (col_type j = sel_col_start; j <= sel_col_end; ++j) - tabular.setRotateCell(tabular.cellIndex(i, j), false); + 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.setRotateCell(tabular.cellIndex(r, c), false); break; case Tabular::TOGGLE_ROTATE_CELL: @@ -5128,9 +5267,9 @@ void InsetTabular::tabularFeatures(Cursor & cur, bool oneNotRotated = oneCellHasRotationState(false, sel_row_start, sel_row_end, sel_col_start, sel_col_end); - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - for (col_type j = sel_col_start; j <= sel_col_end; ++j) - tabular.setRotateCell(tabular.cellIndex(i, j), + 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.setRotateCell(tabular.cellIndex(r, c), oneNotRotated); } break; @@ -5139,9 +5278,9 @@ void InsetTabular::tabularFeatures(Cursor & cur, Tabular::BoxType val = Tabular::BoxType(convert(value)); if (val == tabular.getUsebox(cur.idx())) val = Tabular::BOX_NONE; - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - for (col_type j = sel_col_start; j <= sel_col_end; ++j) - tabular.setUsebox(tabular.cellIndex(i, j), val); + 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.setUsebox(tabular.cellIndex(r, c), val); break; } @@ -5212,17 +5351,17 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::SET_TOP_SPACE: { Length len; if (value == "default") - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - tabular.row_info[i].top_space_default = true; + for (row_type r = sel_row_start; r <= sel_row_end; ++r) + tabular.row_info[r].top_space_default = true; else if (value == "none") - for (row_type i = sel_row_start; i <= sel_row_end; ++i) { - tabular.row_info[i].top_space_default = false; - tabular.row_info[i].top_space = len; + for (row_type r = sel_row_start; r <= sel_row_end; ++r) { + tabular.row_info[r].top_space_default = false; + tabular.row_info[r].top_space = len; } else if (isValidLength(value, &len)) - for (row_type i = sel_row_start; i <= sel_row_end; ++i) { - tabular.row_info[i].top_space_default = false; - tabular.row_info[i].top_space = len; + for (row_type r = sel_row_start; r <= sel_row_end; ++r) { + tabular.row_info[r].top_space_default = false; + tabular.row_info[r].top_space = len; } break; } @@ -5230,17 +5369,17 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::SET_BOTTOM_SPACE: { Length len; if (value == "default") - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - tabular.row_info[i].bottom_space_default = true; + for (row_type r = sel_row_start; r <= sel_row_end; ++r) + tabular.row_info[r].bottom_space_default = true; else if (value == "none") - for (row_type i = sel_row_start; i <= sel_row_end; ++i) { - tabular.row_info[i].bottom_space_default = false; - tabular.row_info[i].bottom_space = len; + for (row_type r = sel_row_start; r <= sel_row_end; ++r) { + tabular.row_info[r].bottom_space_default = false; + tabular.row_info[r].bottom_space = len; } else if (isValidLength(value, &len)) - for (row_type i = sel_row_start; i <= sel_row_end; ++i) { - tabular.row_info[i].bottom_space_default = false; - tabular.row_info[i].bottom_space = len; + for (row_type r = sel_row_start; r <= sel_row_end; ++r) { + tabular.row_info[r].bottom_space_default = false; + tabular.row_info[r].bottom_space = len; } break; } @@ -5248,21 +5387,26 @@ void InsetTabular::tabularFeatures(Cursor & cur, case Tabular::SET_INTERLINE_SPACE: { Length len; if (value == "default") - for (row_type i = sel_row_start; i <= sel_row_end; ++i) - tabular.row_info[i].interline_space_default = true; + for (row_type r = sel_row_start; r <= sel_row_end; ++r) + tabular.row_info[r].interline_space_default = true; else if (value == "none") - for (row_type i = sel_row_start; i <= sel_row_end; ++i) { - tabular.row_info[i].interline_space_default = false; - tabular.row_info[i].interline_space = len; + for (row_type r = sel_row_start; r <= sel_row_end; ++r) { + tabular.row_info[r].interline_space_default = false; + tabular.row_info[r].interline_space = len; } else if (isValidLength(value, &len)) - for (row_type i = sel_row_start; i <= sel_row_end; ++i) { - tabular.row_info[i].interline_space_default = false; - tabular.row_info[i].interline_space = len; + for (row_type r = sel_row_start; r <= sel_row_end; ++r) { + tabular.row_info[r].interline_space_default = false; + tabular.row_info[r].interline_space = len; } 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; @@ -5281,18 +5425,18 @@ bool InsetTabular::copySelection(Cursor & cur) paste_tabular.reset(new Tabular(tabular)); - for (row_type i = 0; i < rs; ++i) + for (row_type r = 0; r < rs; ++r) paste_tabular->deleteRow(0); row_type const rows = re - rs + 1; - while (paste_tabular->row_info.size() > rows) + while (paste_tabular->nrows() > rows) paste_tabular->deleteRow(rows); - for (col_type i = 0; i < cs; ++i) + for (col_type c = 0; c < cs; ++c) paste_tabular->deleteColumn(0); col_type const columns = ce - cs + 1; - while (paste_tabular->column_info.size() > columns) + while (paste_tabular->ncols() > columns) paste_tabular->deleteColumn(columns); paste_tabular->setBuffer(tabular.buffer()); @@ -5327,10 +5471,10 @@ bool InsetTabular::pasteClipboard(Cursor & cur) } for (row_type r1 = 0, r2 = actrow; - r1 < paste_tabular->row_info.size() && r2 < tabular.row_info.size(); + r1 < paste_tabular->nrows() && r2 < tabular.nrows(); ++r1, ++r2) { for (col_type c1 = 0, c2 = actcol; - c1 < paste_tabular->column_info.size() && c2 < tabular.column_info.size(); + c1 < paste_tabular->ncols() && c2 < tabular.ncols(); ++c1, ++c2) { if (paste_tabular->isPartOfMultiColumn(r1, c1) && tabular.isPartOfMultiColumn(r2, c2)) @@ -5367,10 +5511,10 @@ void InsetTabular::cutSelection(Cursor & cur) row_type rs, re; col_type cs, ce; getSelection(cur, rs, re, cs, ce); - for (row_type i = rs; i <= re; ++i) { - for (col_type j = cs; j <= ce; ++j) { + for (row_type r = rs; r <= re; ++r) { + for (col_type c = cs; c <= ce; ++c) { shared_ptr t - = cell(tabular.cellIndex(i, j)); + = cell(tabular.cellIndex(r, c)); if (buffer().params().trackChanges) // FIXME: Change tracking (MG) t->setChange(Change(Change::DELETED)); @@ -5397,6 +5541,7 @@ bool InsetTabular::isRightToLeft(Cursor & cur) const parentpos).language()->rightToLeft(); } + docstring InsetTabular::asString(idx_type stidx, idx_type enidx, bool intoInsets) { @@ -5426,12 +5571,8 @@ void InsetTabular::getSelection(Cursor & cur, CursorSlice const & end = cur.selEnd(); cs = tabular.cellColumn(beg.idx()); ce = tabular.cellColumn(end.idx()); - if (cs > ce) { - ce = cs; - cs = tabular.cellColumn(end.idx()); - } else { - ce = tabular.cellRightColumn(end.idx()); - } + if (cs > ce) + swap(cs, ce); rs = tabular.cellRow(beg.idx()); re = tabular.cellRow(end.idx()); @@ -5527,8 +5668,8 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf, idx_type const cells = loctab->numberofcells; p = 0; cols = ocol; - rows = loctab->row_info.size(); - col_type const columns = loctab->column_info.size(); + rows = loctab->nrows(); + col_type const columns = loctab->ncols(); while (cell < cells && p < len && row < rows && (p = buf.find_first_of(from_ascii("\t\n"), p)) != docstring::npos) @@ -5580,15 +5721,13 @@ bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf, void InsetTabular::addPreview(DocIterator const & inset_pos, PreviewLoader & loader) const { - row_type const rows = tabular.row_info.size(); - col_type const columns = tabular.column_info.size(); DocIterator cell_pos = inset_pos; cell_pos.push_back(CursorSlice(*const_cast(this))); - for (row_type i = 0; i < rows; ++i) { - for (col_type j = 0; j < columns; ++j) { - cell_pos.top().idx() = tabular.cellIndex(i, j); - tabular.cellInset(i, j)->addPreview(cell_pos, loader); + for (row_type r = 0; r < tabular.nrows(); ++r) { + for (col_type c = 0; c < tabular.ncols(); ++c) { + cell_pos.top().idx() = tabular.cellIndex(r, c); + tabular.cellInset(r, c)->addPreview(cell_pos, loader); } } }