using namespace std;
using namespace lyx::support;
-using boost::shared_ptr;
namespace lyx {
{ 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 },
{ 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 }
};
return "layout";
case LYX_ALIGN_SPECIAL:
return "special";
+ case LYX_ALIGN_DECIMAL:
+ return "decimal";
}
return string();
}
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;
}
+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;
+}
+
/////////////////////////////////////////////////////////////////////
//
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),
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),
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);
rowofcell[i] = row;
columnofcell[i] = column;
setFixedWidth(row, column);
- updateContentAlignment(row, column);
+ cell_info[row][column].inset->setContentAlignment(
+ getAlignment(cellIndex(row, column)));
++i;
}
}
}
-int Tabular::columnWidth(idx_type cell) const
+int Tabular::cellWidth(idx_type cell) const
{
int w = 0;
col_type const span = columnSpan(cell);
bool Tabular::updateColumnWidths()
{
+ vector<int> 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) {
int new_width = 0;
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) {
}
-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);
+ }
}
}
-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)
{
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;
}
}
-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;
os << ">\n";
for (col_type c = 0; c < ncols(); ++c) {
os << "<column"
- << write_attribute("alignment", column_info[c].alignment)
- << write_attribute("valignment", column_info[c].valignment)
+ << write_attribute("alignment", column_info[c].alignment);
+ if (column_info[c].alignment == LYX_ALIGN_DECIMAL)
+ os << write_attribute("decimal_point", column_info[c].decimal_point);
+ os << write_attribute("valignment", column_info[c].valignment)
<< write_attribute("width", column_info[c].p_width.asString())
<< write_attribute("special", column_info[c].align_special)
<< ">\n";
return;
}
getTokenValue(line, "alignment", column_info[c].alignment);
+ getTokenValue(line, "decimal_point", column_info[c].decimal_point);
getTokenValue(line, "valignment", column_info[c].valignment);
getTokenValue(line, "width", column_info[c].p_width);
getTokenValue(line, "special", column_info[c].align_special);
cell = cellIndex(row, col);
CellData & cs = cellInfo(cell);
cs.multicolumn = CELL_BEGIN_OF_MULTICOLUMN;
- cs.alignment = column_info[col].alignment;
+ if (column_info[col].alignment != LYX_ALIGN_DECIMAL)
+ cs.alignment = column_info[col].alignment;
if (col > 0)
setRightLine(cell, rightLine(cellIndex(row, col - 1)));
// change (assigning this to uwestoehr)
// until LyX supports this, use the deault alignment of multirow
// cells: left
- cs.alignment = LYX_ALIGN_LEFT;
+ cs.alignment = LYX_ALIGN_CENTER;
// set the bottom row of the last selected cell
setBottomLine(cell, bottomLine(cell + (number - 1)*ncols()));
Tabular::idx_type Tabular::columnSpan(idx_type cell) const
{
row_type const row = cellRow(cell);
- col_type column = cellColumn(cell) + 1;
- while (column < ncols() && isPartOfMultiColumn(row, column))
- ++column;
+ col_type const col = cellColumn(cell);
+ int span = 1;
+ while (col + span < ncols() && isPartOfMultiColumn(row, col + span))
+ ++span;
- return column - cellColumn(cell);
+ return span;
}
}
} else if (row == 0) {
for (col_type c = 0; c < ncols(); ++c) {
- if (topline[c]) {
- //babel makes the "-" character an active one, so we have to suppress this here
- //see http://groups.google.com/group/comp.text.tex/browse_thread/thread/af769424a4a0f289#
- if (lang == "slovak" || lang == "czech")
- os << (use_booktabs ? "\\expandafter\\cmidrule\\expandafter{\\expandafter" :
- "\\expandafter\\cline\\expandafter{\\expandafter")
- << c + 1 << "\\string-";
- else
- os << (use_booktabs ? "\\cmidrule{" : "\\cline{") << c + 1 << '-';
- // get to last column of line span
- while (c < ncols() && topline[c])
- ++c;
- os << c << "} ";
- }
+ for ( ; c < ncols() && !topline[c]; ++c) {}
+
+ col_type offset = 0;
+ for (col_type j = 0 ; j < c; ++j)
+ if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
+ ++offset;
+
+ //babel makes the "-" character an active one, so we have to suppress this here
+ //see http://groups.google.com/group/comp.text.tex/browse_thread/thread/af769424a4a0f289#
+ if (lang == "slovak" || lang == "czech")
+ os << "\\expandafter" << (use_booktabs ? "\\cmidrule" : "\\cline")
+ << "\\expandafter{\\expandafter" << c + 1 + offset << "\\string-";
+ else
+ os << (use_booktabs ? "\\cmidrule{" : "\\cline{") << c + 1 + offset << '-';
+
+ col_type cstart = c;
+ for ( ; c < ncols() && topline[c]; ++c) {}
+
+ for (col_type j = cstart ; j < c ; ++j)
+ if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
+ ++offset;
+
+ os << c + offset << "} ";
}
}
os << "\n";
os << "\\hline ";
} else {
for (col_type c = 0; c < ncols(); ++c) {
- if (bottomline[c]) {
- //babel makes the "-" character an active one, so we have to suppress this here
- //see http://groups.google.com/group/comp.text.tex/browse_thread/thread/af769424a4a0f289#
- if (lang == "slovak" || lang == "czech")
- os << (use_booktabs ? "\\expandafter\\cmidrule\\expandafter{\\expandafter" :
- "\\expandafter\\cline\\expandafter{\\expandafter")
- << c + 1 << "\\string-";
- else
- os << (use_booktabs ? "\\cmidrule{" : "\\cline{") << c + 1 << '-';
- // get to last column of line span
- while (c < ncols() && bottomline[c])
- ++c;
- os << c << "} ";
- }
+ for ( ; c < ncols() && !bottomline[c]; ++c) {}
+
+ col_type offset = 0;
+ for (col_type j = 0 ; j < c; ++j)
+ if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
+ ++offset;
+
+ //babel makes the "-" character an active one, so we have to suppress this here
+ //see http://groups.google.com/group/comp.text.tex/browse_thread/thread/af769424a4a0f289#
+ if (lang == "slovak" || lang == "czech")
+ os << "\\expandafter" << (use_booktabs ? "\\cmidrule" : "\\cline")
+ << "\\expandafter{\\expandafter" << c + 1 + offset << "\\string-";
+ else
+ os << (use_booktabs ? "\\cmidrule{" : "\\cline{") << c + 1 + offset << '-';
+
+ col_type cstart = c;
+ for ( ; c < ncols() && bottomline[c]; ++c) {}
+
+ for (col_type j = cstart ; j < c ; ++j)
+ if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
+ ++offset;
+
+ os << c + offset << "} ";
}
}
os << "\n";
|| ((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()) {
// 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);
// needs to be discussed
os << "*";
os << "}{";
- } // end if ismultirow
+ } // end if ismultirow
if (getRotateCell(cell)) {
os << "\\begin{sideways}\n";
os << "%\n\\end{sideways}";
++ret;
}
- if (ismulticol || ismultirow) {
+ if (ismultirow)
os << '}';
- }
+ if (ismulticol)
+ os << '}';
+
return ret;
}
bool ismulticol = false;
bool ismultirow = false;
for (col_type c = 0; c < ncols(); ++c) {
- if (isPartOfMultiRow(row, c))
- os << " & "; // we need to add a further column
- if (isPartOfMultiColumn(row, c) || isPartOfMultiRow(row, c))
+ if (isPartOfMultiColumn(row, c))
+ continue;
+
+ if (isPartOfMultiRow(row, c) &&
+ column_info[c].alignment != LYX_ALIGN_DECIMAL) {
+ os << " & ";
continue;
+ }
+
cell = cellIndex(row, c);
ret += TeXCellPreamble(os, cell, ismulticol, ismultirow);
shared_ptr<InsetTableCell> inset = cellInset(cell);
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 << '}';
case LYX_ALIGN_BLOCK:
case LYX_ALIGN_LAYOUT:
case LYX_ALIGN_SPECIAL:
+ case LYX_ALIGN_DECIMAL:
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;
bool InsetTabular::insetAllowed(InsetCode code) const
{
- if (code == MATHMACRO_CODE
- || (code == CAPTION_CODE && !tabular.is_long_tabular))
+ switch (code)
+ {
+ case MARGIN_CODE:
+ case MATHMACRO_CODE:
return false;
- return true;
+ case CAPTION_CODE:
+ return tabular.is_long_tabular;
+
+ default:
+ return true;
+ }
}
int w = xo(cur.bv()) + ADD_TO_TABULAR_WIDTH;
col_type c = 0;
for (; c < tabular.ncols() && x > w; ++c)
- w += tabular.columnWidth(c);
+ w += tabular.cellWidth(c);
return c - 1;
}
tabular.cellInset(cell)->metrics(m, dim);
if (!p_width.zero())
dim.wid = m.base.textwidth;
- tabular.setCellWidth(cell, dim.wid);
+ 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()
idx = tabular.cellIndex(r, c);
if (tabular.isPartOfMultiRow(r, c)) {
- nx += tabular.columnWidth(idx);
+ nx += tabular.cellWidth(idx);
continue;
}
bv->coordCache().insets().add(cell(idx).get(), cx, cy);
cell(idx)->draw(pi, cx, cy);
drawCellLines(pi.pain, nx, y, r, idx, pi.change_);
- nx += tabular.columnWidth(idx);
+ nx += tabular.cellWidth(idx);
pi.selected = original_selection_state;
}
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 w = tabular.cellWidth(cell);
int const h = tabular.cellHeight(cell);
int const yy = y - tabular.rowAscent(r);
if (isCellSelected(cur, r, c))
row_type row, idx_type cell, Change const & change) const
{
y -= tabular.rowAscent(row);
- int const w = tabular.columnWidth(cell);
+ 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;
}
if (action == Tabular::LAST_ACTION) {
status.clear();
- status.unknown(true);
+ status.setUnknown(true);
return true;
}
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.
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:
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:
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);
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;
}
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;
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;
case Tabular::ALIGN_RIGHT:
case Tabular::ALIGN_CENTER:
case Tabular::ALIGN_BLOCK:
+ case Tabular::ALIGN_DECIMAL:
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
tabular.setAlignment(tabular.cellIndex(r, c), setAlign, flag);
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;