mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 05:16:21 +00:00
Support varwidth's V tabular column type
This effectively enables linebreaks, multipars and layout changes in non-fixed width (i.e., standard) table columns. Fixes: #6577 TODO: metrics are wrong (too wide) on screen with linebreaks.
This commit is contained in:
parent
620efb3540
commit
9dcb24d578
@ -7,6 +7,11 @@ changes happened in particular if possible. A good example would be
|
||||
|
||||
-----------------------
|
||||
|
||||
2018-07-01 Jürgen Spitzmüller <spitz@lyx.org>
|
||||
* format incremented to 555: Support varwidth's V tabular column type.
|
||||
This effectively enables linebreaks, multipars and layout changes in
|
||||
non-fixed width (i.e., standard) table columns.
|
||||
|
||||
2018-06-23 Jürgen Spitzmüller <spitz@lyx.org>
|
||||
* format incremented to 554: Support tabularx and xltabular:
|
||||
- add column flag "varwidth=true", which will output column type 'X'
|
||||
|
@ -5431,6 +5431,35 @@ varioref
|
||||
the page of the referred label.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
varwidth
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Found:
|
||||
\begin_inset Info
|
||||
type "package"
|
||||
arg "varwidth"
|
||||
\end_inset
|
||||
|
||||
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
CTAN:
|
||||
\family typewriter
|
||||
macros/latex/contrib/varwidth/
|
||||
\end_layout
|
||||
|
||||
\begin_layout Description
|
||||
Notes: The package
|
||||
\family sans
|
||||
varwidth
|
||||
\family default
|
||||
\color none
|
||||
is needed to allow for line and paragraph breaks in standard tabular columns.
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsection
|
||||
xltabular
|
||||
\end_layout
|
||||
@ -6750,7 +6779,7 @@ Notes: The package
|
||||
varwidth
|
||||
\family default
|
||||
\color none
|
||||
is used to produce minipages variable (i.
|
||||
is used to produce minipages of variable (i.
|
||||
\begin_inset space \thinspace{}
|
||||
\end_inset
|
||||
|
||||
|
@ -24,14 +24,14 @@ import sys, os
|
||||
|
||||
# Uncomment only what you need to import, please.
|
||||
|
||||
from parser_tools import (find_end_of_inset, find_end_of_layout, find_token,
|
||||
get_bool_value, get_value, get_quoted_value)
|
||||
from parser_tools import (count_pars_in_inset, find_end_of_inset, find_end_of_layout,
|
||||
find_token, get_bool_value, get_option_value, get_value, get_quoted_value)
|
||||
# del_token, del_value, del_complete_lines,
|
||||
# find_complete_lines, find_end_of,
|
||||
# find_re, find_substring, find_token_backwards,
|
||||
# get_containing_inset, get_containing_layout,
|
||||
# is_in_inset, set_bool_value
|
||||
# find_tokens, find_token_exact, check_token, get_option_value
|
||||
# find_tokens, find_token_exact, check_token
|
||||
|
||||
from lyx2lyx_tools import (put_cmd_in_ert, add_to_preamble)
|
||||
# revert_font_attrs, insert_to_preamble, latex_length
|
||||
@ -118,15 +118,15 @@ def revert_paratype(document):
|
||||
document.header[i1] = document.header[i1].replace("PTSerif-TLF", "default")
|
||||
if j!= -1:
|
||||
if sfoption != "":
|
||||
add_to_preamble(document, ["\\usepackage[" + sfoption + "]{PTSans}"])
|
||||
add_to_preamble(document, ["\\usepackage[" + sfoption + "]{PTSans}"])
|
||||
else:
|
||||
add_to_preamble(document, ["\\usepackage{PTSans}"])
|
||||
add_to_preamble(document, ["\\usepackage{PTSans}"])
|
||||
document.header[j] = document.header[j].replace("PTSans-TLF", "default")
|
||||
if k!= -1:
|
||||
if ttoption != "":
|
||||
add_to_preamble(document, ["\\usepackage[" + ttoption + "]{PTMono}"])
|
||||
add_to_preamble(document, ["\\usepackage[" + ttoption + "]{PTMono}"])
|
||||
else:
|
||||
add_to_preamble(document, ["\\usepackage{PTMono}"])
|
||||
add_to_preamble(document, ["\\usepackage{PTMono}"])
|
||||
document.header[k] = document.header[k].replace("PTMono-TLF", "default")
|
||||
|
||||
|
||||
@ -345,6 +345,100 @@ def revert_stretchcolumn(document):
|
||||
i = i + 1
|
||||
|
||||
|
||||
def revert_vcolumns(document):
|
||||
" Revert standard columns with line breaks etc. "
|
||||
i = 0
|
||||
needvarwidth = False
|
||||
needarray = False
|
||||
try:
|
||||
while True:
|
||||
i = find_token(document.body, "\\begin_inset Tabular", i)
|
||||
if i == -1:
|
||||
return
|
||||
j = find_end_of_inset(document.body, i)
|
||||
if j == -1:
|
||||
document.warning("Malformed LyX document: Could not find end of tabular.")
|
||||
i += 1
|
||||
continue
|
||||
|
||||
# Collect necessary column information
|
||||
m = i + 1
|
||||
nrows = int(document.body[i+1].split('"')[3])
|
||||
ncols = int(document.body[i+1].split('"')[5])
|
||||
col_info = []
|
||||
for k in range(ncols):
|
||||
m = find_token(document.body, "<column", m)
|
||||
width = get_option_value(document.body[m], 'width')
|
||||
varwidth = get_option_value(document.body[m], 'varwidth')
|
||||
alignment = get_option_value(document.body[m], 'alignment')
|
||||
special = get_option_value(document.body[m], 'special')
|
||||
col_info.append([width, varwidth, alignment, special, m])
|
||||
|
||||
# Now parse cells
|
||||
m = i + 1
|
||||
lines = []
|
||||
for row in range(nrows):
|
||||
for col in range(ncols):
|
||||
m = find_token(document.body, "<cell", m)
|
||||
multicolumn = get_option_value(document.body[m], 'multicolumn')
|
||||
multirow = get_option_value(document.body[m], 'multirow')
|
||||
width = get_option_value(document.body[m], 'width')
|
||||
rotate = get_option_value(document.body[m], 'rotate')
|
||||
# Check for: linebreaks, multipars, non-standard environments
|
||||
begcell = m
|
||||
endcell = find_token(document.body, "</cell>", begcell)
|
||||
vcand = False
|
||||
if find_token(document.body, "\\begin_inset Newline", begcell, endcell) != -1:
|
||||
vcand = True
|
||||
elif count_pars_in_inset(document.body, begcell + 2) > 1:
|
||||
vcand = True
|
||||
elif get_value(document.body, "\\begin_layout", begcell) != "Plain Layout":
|
||||
vcand = True
|
||||
if vcand and rotate == "" and ((multicolumn == "" and multirow == "") or width == ""):
|
||||
if col_info[col][0] == "" and col_info[col][1] == "" and col_info[col][3] == "":
|
||||
needvarwidth = True
|
||||
alignment = col_info[col][2]
|
||||
col_line = col_info[col][4]
|
||||
vval = ""
|
||||
if alignment == "center":
|
||||
vval = ">{\\centering}"
|
||||
elif alignment == "left":
|
||||
vval = ">{\\raggedright}"
|
||||
elif alignment == "right":
|
||||
vval = ">{\\raggedleft}"
|
||||
if vval != "":
|
||||
needarray = True
|
||||
vval += "V{\\linewidth}"
|
||||
|
||||
document.body[col_line] = document.body[col_line][:-1] + " special=\"" + vval + "\">"
|
||||
# ERT newlines and linebreaks (since LyX < 2.4 automatically inserts parboxes
|
||||
# with newlines, and we do not want that)
|
||||
while True:
|
||||
endcell = find_token(document.body, "</cell>", begcell)
|
||||
linebreak = False
|
||||
nl = find_token(document.body, "\\begin_inset Newline newline", begcell, endcell)
|
||||
if nl == -1:
|
||||
nl = find_token(document.body, "\\begin_inset Newline linebreak", begcell, endcell)
|
||||
if nl == -1:
|
||||
break
|
||||
linebreak = True
|
||||
nle = find_end_of_inset(document.body, nl)
|
||||
del(document.body[nle:nle+1])
|
||||
if linebreak:
|
||||
document.body[nl:nl+1] = put_cmd_in_ert("\\linebreak{}")
|
||||
else:
|
||||
document.body[nl:nl+1] = put_cmd_in_ert("\\\\")
|
||||
m += 1
|
||||
|
||||
i = j + 1
|
||||
|
||||
finally:
|
||||
if needarray == True:
|
||||
add_to_preamble(document, ["\\usepackage{array}"])
|
||||
if needvarwidth == True:
|
||||
add_to_preamble(document, ["\\usepackage{varwidth}"])
|
||||
|
||||
|
||||
##
|
||||
# Conversion hub
|
||||
#
|
||||
@ -360,10 +454,12 @@ convert = [
|
||||
[551, []],
|
||||
[552, []],
|
||||
[553, []],
|
||||
[554, []]
|
||||
[554, []],
|
||||
[555, []]
|
||||
]
|
||||
|
||||
revert = [
|
||||
[554, [revert_vcolumns]],
|
||||
[553, [revert_stretchcolumn]],
|
||||
[552, [revert_tuftecite]],
|
||||
[551, [revert_floatpclass, revert_floatalignment]],
|
||||
|
@ -160,7 +160,8 @@ ParagraphMetrics & TextMetrics::parMetrics(pit_type pit, bool redo)
|
||||
}
|
||||
|
||||
|
||||
bool TextMetrics::metrics(MetricsInfo & mi, Dimension & dim, int min_width)
|
||||
bool TextMetrics::metrics(MetricsInfo & mi, Dimension & dim, int min_width,
|
||||
bool const expand_on_multipars)
|
||||
{
|
||||
LBUFERR(mi.base.textwidth > 0);
|
||||
max_width_ = mi.base.textwidth;
|
||||
@ -170,7 +171,7 @@ bool TextMetrics::metrics(MetricsInfo & mi, Dimension & dim, int min_width)
|
||||
dim_ = Dimension();
|
||||
dim_.wid = min_width;
|
||||
pit_type const npar = text_->paragraphs().size();
|
||||
if (npar > 1)
|
||||
if (npar > 1 && expand_on_multipars)
|
||||
// If there is more than one row, expand the text to
|
||||
// the full allowable width.
|
||||
dim_.wid = max_width_;
|
||||
|
@ -55,7 +55,8 @@ public:
|
||||
|
||||
|
||||
/// compute text metrics.
|
||||
bool metrics(MetricsInfo & mi, Dimension & dim, int min_width = 0);
|
||||
bool metrics(MetricsInfo & mi, Dimension & dim, int min_width = 0,
|
||||
bool const expand_on_multipars = true);
|
||||
|
||||
///
|
||||
void newParMetricsDown();
|
||||
|
@ -917,8 +917,11 @@ void Tabular::updateIndexes()
|
||||
// reset column and row of cells and update their width and alignment
|
||||
for (row_type row = 0; row < nrows(); ++row)
|
||||
for (col_type column = 0; column < ncols(); ++column) {
|
||||
if (isPartOfMultiColumn(row, column))
|
||||
if (isPartOfMultiColumn(row, column)) {
|
||||
cell_info[row][column].inset->toggleMultiCol(true);
|
||||
continue;
|
||||
}
|
||||
cell_info[row][column].inset->toggleMultiCol(false);
|
||||
// columnofcell needs to be called before setting width and aligment
|
||||
// multirow cells inherit the width from the column width
|
||||
if (!isPartOfMultiRow(row, column)) {
|
||||
@ -926,8 +929,11 @@ void Tabular::updateIndexes()
|
||||
rowofcell[i] = row;
|
||||
}
|
||||
setFixedWidth(row, column);
|
||||
if (isPartOfMultiRow(row, column))
|
||||
if (isPartOfMultiRow(row, column)) {
|
||||
cell_info[row][column].inset->toggleMultiRow(true);
|
||||
continue;
|
||||
}
|
||||
cell_info[row][column].inset->toggleMultiRow(false);
|
||||
cell_info[row][column].inset->setContentAlignment(
|
||||
getAlignment(cellIndex(row, column)));
|
||||
++i;
|
||||
@ -1130,14 +1136,16 @@ void Tabular::setVAlignment(idx_type cell, VAlignment align,
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Allow line and paragraph breaks for fixed width cells or disallow them,
|
||||
* merge cell paragraphs and reset layout to standard for variable width
|
||||
* cells.
|
||||
* Allow line and paragraph breaks for fixed width multicol/multirow cells
|
||||
* or disallow them, merge cell paragraphs and reset layout to standard
|
||||
* for variable width multicol cells.
|
||||
*/
|
||||
void toggleFixedWidth(Cursor & cur, InsetTableCell * inset, bool fixedWidth)
|
||||
void toggleFixedWidth(Cursor & cur, InsetTableCell * inset,
|
||||
bool const fixedWidth, bool const multicol,
|
||||
bool const multirow)
|
||||
{
|
||||
inset->toggleFixedWidth(fixedWidth);
|
||||
if (fixedWidth)
|
||||
if (!multirow && (fixedWidth || !multicol))
|
||||
return;
|
||||
|
||||
// merge all paragraphs to one
|
||||
@ -1145,6 +1153,19 @@ void toggleFixedWidth(Cursor & cur, InsetTableCell * inset, bool fixedWidth)
|
||||
while (inset->paragraphs().size() > 1)
|
||||
mergeParagraph(bp, inset->paragraphs(), 0);
|
||||
|
||||
// This is relevant for multirows
|
||||
if (fixedWidth)
|
||||
return;
|
||||
|
||||
// remove newlines
|
||||
ParagraphList::iterator pit = inset->paragraphs().begin();
|
||||
for (; pit != inset->paragraphs().end(); ++pit) {
|
||||
for (pos_type j = 0; j != pit->size(); ++j) {
|
||||
if (pit->isNewline(j))
|
||||
pit->eraseChar(j, bp.track_changes);
|
||||
}
|
||||
}
|
||||
|
||||
// reset layout
|
||||
cur.push(*inset);
|
||||
// undo information has already been recorded
|
||||
@ -1171,16 +1192,13 @@ void Tabular::setColumnPWidth(Cursor & cur, idx_type cell,
|
||||
idx_type const cidx = cellIndex(r, c);
|
||||
// because of multicolumns
|
||||
toggleFixedWidth(cur, cellInset(cidx).get(),
|
||||
!getPWidth(cidx).zero());
|
||||
!getPWidth(cidx).zero(), isMultiColumn(cidx),
|
||||
isMultiRow(cidx));
|
||||
if (isMultiRow(cidx))
|
||||
setAlignment(cidx, LYX_ALIGN_LEFT, false);
|
||||
}
|
||||
// cur paragraph can become invalid after paragraphs were merged
|
||||
if (cur.pit() > cur.lastpit())
|
||||
cur.pit() = cur.lastpit();
|
||||
// cur position can become invalid after newlines were removed
|
||||
if (cur.pos() > cur.lastpos())
|
||||
cur.pos() = cur.lastpos();
|
||||
// cur can become invalid after paragraphs were merged
|
||||
cur.fixIfBroken();
|
||||
}
|
||||
|
||||
|
||||
@ -1201,13 +1219,10 @@ bool Tabular::setMColumnPWidth(Cursor & cur, idx_type cell,
|
||||
return false;
|
||||
|
||||
cellInfo(cell).p_width = width;
|
||||
toggleFixedWidth(cur, cellInset(cell).get(), !width.zero());
|
||||
// cur paragraph can become invalid after paragraphs were merged
|
||||
if (cur.pit() > cur.lastpit())
|
||||
cur.pit() = cur.lastpit();
|
||||
// cur position can become invalid after newlines were removed
|
||||
if (cur.pos() > cur.lastpos())
|
||||
cur.pos() = cur.lastpos();
|
||||
toggleFixedWidth(cur, cellInset(cell).get(), !width.zero(),
|
||||
isMultiColumn(cell), isMultiRow(cell));
|
||||
// cur can become invalid after paragraphs were merged
|
||||
cur.fixIfBroken();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1717,6 +1732,16 @@ bool Tabular::hasVarwidthColumn() const
|
||||
}
|
||||
|
||||
|
||||
bool Tabular::isVTypeColumn(col_type c) const
|
||||
{
|
||||
for (row_type r = 0; r < nrows(); ++r) {
|
||||
idx_type idx = cellIndex(r, c);
|
||||
if (getRotateCell(idx) == 0 && useBox(idx) == BOX_VARWIDTH)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Tabular::CellData const & Tabular::cellInfo(idx_type cell) const
|
||||
{
|
||||
@ -1730,7 +1755,7 @@ Tabular::CellData & Tabular::cellInfo(idx_type cell)
|
||||
}
|
||||
|
||||
|
||||
Tabular::idx_type Tabular::setMultiColumn(idx_type cell, idx_type number,
|
||||
Tabular::idx_type Tabular::setMultiColumn(Cursor & cur, idx_type cell, idx_type number,
|
||||
bool const right_border)
|
||||
{
|
||||
idx_type const col = cellColumn(cell);
|
||||
@ -1745,6 +1770,14 @@ Tabular::idx_type Tabular::setMultiColumn(idx_type cell, idx_type number,
|
||||
if (column_info[col].alignment != LYX_ALIGN_DECIMAL)
|
||||
cs.alignment = column_info[col].alignment;
|
||||
setRightLine(cell, right_border);
|
||||
// non-fixed width multicolumns cannot have multiple paragraphs
|
||||
if (getPWidth(cell).zero()) {
|
||||
toggleFixedWidth(cur, cellInset(cell).get(),
|
||||
!getPWidth(cell).zero(), isMultiColumn(cell),
|
||||
isMultiRow(cell));
|
||||
// cur can become invalid after paragraphs were merged
|
||||
cur.fixIfBroken();
|
||||
}
|
||||
|
||||
idx_type lastcell = cellIndex(row, col + number - 1);
|
||||
for (idx_type i = 1; i < lastcell - cell + 1; ++i) {
|
||||
@ -1773,7 +1806,7 @@ bool Tabular::hasMultiRow(row_type r) const
|
||||
return false;
|
||||
}
|
||||
|
||||
Tabular::idx_type Tabular::setMultiRow(idx_type cell, idx_type number,
|
||||
Tabular::idx_type Tabular::setMultiRow(Cursor & cur, idx_type cell, idx_type number,
|
||||
bool const bottom_border,
|
||||
LyXAlignment const halign)
|
||||
{
|
||||
@ -1796,6 +1829,15 @@ Tabular::idx_type Tabular::setMultiRow(idx_type cell, idx_type number,
|
||||
else
|
||||
cs.alignment = LYX_ALIGN_LEFT;
|
||||
|
||||
// Multirows cannot have multiple paragraphs
|
||||
if (getPWidth(cell).zero()) {
|
||||
toggleFixedWidth(cur, cellInset(cell).get(),
|
||||
!getPWidth(cell).zero(),
|
||||
isMultiColumn(cell), isMultiRow(cell));
|
||||
// cur can become invalid after paragraphs were merged
|
||||
cur.fixIfBroken();
|
||||
}
|
||||
|
||||
// set the bottom line of the last selected cell
|
||||
setBottomLine(cell, bottom_border);
|
||||
|
||||
@ -1949,7 +1991,7 @@ Tabular::BoxType Tabular::getUsebox(idx_type cell) const
|
||||
return BOX_NONE;
|
||||
if (cellInfo(cell).usebox > 1)
|
||||
return cellInfo(cell).usebox;
|
||||
return useParbox(cell);
|
||||
return useBox(cell);
|
||||
}
|
||||
|
||||
|
||||
@ -2078,11 +2120,11 @@ bool Tabular::haveLTLastFoot(bool withcaptions) const
|
||||
}
|
||||
|
||||
|
||||
Tabular::idx_type Tabular::setLTCaption(row_type row, bool what)
|
||||
Tabular::idx_type Tabular::setLTCaption(Cursor & cur, row_type row, bool what)
|
||||
{
|
||||
idx_type i = getFirstCellInRow(row);
|
||||
if (what) {
|
||||
setMultiColumn(i, numberOfCellsInRow(row), false);
|
||||
setMultiColumn(cur, i, numberOfCellsInRow(row), false);
|
||||
setTopLine(i, false);
|
||||
setBottomLine(i, false);
|
||||
setLeftLine(i, false);
|
||||
@ -2490,7 +2532,7 @@ void Tabular::TeXCellPreamble(otexstream & os, idx_type cell,
|
||||
}
|
||||
os << "]{" << from_ascii(getPWidth(cell).asLatexString())
|
||||
<< "}\n";
|
||||
} else if (getUsebox(cell) == BOX_VARWIDTH) {
|
||||
} else if (getRotateCell(cell) != 0 && getUsebox(cell) == BOX_VARWIDTH) {
|
||||
os << "\\begin{varwidth}[";
|
||||
switch (valign) {
|
||||
case LYX_VALIGN_TOP:
|
||||
@ -2520,7 +2562,7 @@ void Tabular::TeXCellPostamble(otexstream & os, idx_type cell,
|
||||
os << '}';
|
||||
else if (getUsebox(cell) == BOX_MINIPAGE)
|
||||
os << breakln << "\\end{minipage}";
|
||||
else if (getUsebox(cell) == BOX_VARWIDTH)
|
||||
else if (getRotateCell(cell) != 0 && getUsebox(cell) == BOX_VARWIDTH)
|
||||
os << breakln << "\\end{varwidth}";
|
||||
if (getRotateCell(cell) != 0)
|
||||
os << breakln << "\\end{turn}";
|
||||
@ -2964,6 +3006,25 @@ void Tabular::latex(otexstream & os, OutputParams const & runparams) const
|
||||
break;
|
||||
}
|
||||
os << 'X';
|
||||
} else if (isVTypeColumn(c)) {
|
||||
switch (column_info[c].alignment) {
|
||||
case LYX_ALIGN_LEFT:
|
||||
os << ">{\\raggedright}";
|
||||
break;
|
||||
case LYX_ALIGN_RIGHT:
|
||||
os << ">{\\raggedleft}";
|
||||
break;
|
||||
case LYX_ALIGN_CENTER:
|
||||
os << ">{\\centering}";
|
||||
break;
|
||||
case LYX_ALIGN_NONE:
|
||||
case LYX_ALIGN_BLOCK:
|
||||
case LYX_ALIGN_LAYOUT:
|
||||
case LYX_ALIGN_SPECIAL:
|
||||
case LYX_ALIGN_DECIMAL:
|
||||
break;
|
||||
}
|
||||
os << "V{\\linewidth}";
|
||||
} else {
|
||||
switch (column_info[c].alignment) {
|
||||
case LYX_ALIGN_LEFT:
|
||||
@ -3588,7 +3649,8 @@ void Tabular::validate(LaTeXFeatures & features) const
|
||||
if (getUsebox(cell) == BOX_VARWIDTH)
|
||||
features.require("varwidth");
|
||||
if (getVAlignment(cell) != LYX_VALIGN_TOP
|
||||
|| !getPWidth(cell).zero())
|
||||
|| !getPWidth(cell).zero()
|
||||
|| isVTypeColumn(cellColumn(cell)))
|
||||
features.require("array");
|
||||
// Tell footnote that we need a savenote
|
||||
// environment in non-long tables or
|
||||
@ -3604,17 +3666,19 @@ void Tabular::validate(LaTeXFeatures & features) const
|
||||
}
|
||||
|
||||
|
||||
Tabular::BoxType Tabular::useParbox(idx_type cell) const
|
||||
Tabular::BoxType Tabular::useBox(idx_type cell) const
|
||||
{
|
||||
ParagraphList const & parlist = cellInset(cell)->paragraphs();
|
||||
if (parlist.size() > 1)
|
||||
return BOX_VARWIDTH;
|
||||
|
||||
ParagraphList::const_iterator cit = parlist.begin();
|
||||
ParagraphList::const_iterator end = parlist.end();
|
||||
bool const turned = getRotateCell(cell) != 0;
|
||||
|
||||
for (; cit != end; ++cit)
|
||||
for (int i = 0; i < cit->size(); ++i)
|
||||
if (cit->isNewline(i))
|
||||
return turned ? BOX_VARWIDTH : BOX_PARBOX;
|
||||
if (cit->isNewline(i) || cit->layout().isEnvironment())
|
||||
return BOX_VARWIDTH;
|
||||
|
||||
return BOX_NONE;
|
||||
}
|
||||
@ -3628,13 +3692,13 @@ Tabular::BoxType Tabular::useParbox(idx_type cell) const
|
||||
|
||||
InsetTableCell::InsetTableCell(Buffer * buf)
|
||||
: InsetText(buf, InsetText::PlainLayout), isFixedWidth(false),
|
||||
contentAlign(LYX_ALIGN_CENTER)
|
||||
isMultiColumn(false), isMultiRow(false), contentAlign(LYX_ALIGN_CENTER)
|
||||
{}
|
||||
|
||||
|
||||
bool InsetTableCell::forcePlainLayout(idx_type) const
|
||||
{
|
||||
return !isFixedWidth;
|
||||
return isMultiRow || (isMultiColumn && !isFixedWidth);
|
||||
}
|
||||
|
||||
|
||||
@ -3701,6 +3765,34 @@ docstring InsetTableCell::xhtml(XHTMLStream & xs, OutputParams const & rp) const
|
||||
}
|
||||
|
||||
|
||||
void InsetTableCell::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
{
|
||||
TextMetrics & tm = mi.base.bv->textMetrics(&text());
|
||||
|
||||
// Hand font through to contained lyxtext:
|
||||
tm.font_.fontInfo() = mi.base.font;
|
||||
mi.base.textwidth -= 2 * TEXT_TO_INSET_OFFSET;
|
||||
|
||||
// This can happen when a layout has a left and right margin,
|
||||
// and the view is made very narrow. We can't do better than
|
||||
// to draw it partly out of view (bug 5890).
|
||||
if (mi.base.textwidth < 1)
|
||||
mi.base.textwidth = 1;
|
||||
|
||||
// We tell metrics here not to expand on multiple pars
|
||||
// This is the difference to InsetText::Metrics
|
||||
// FIXME: pars with newlines are still too wide!
|
||||
if (hasFixedWidth())
|
||||
tm.metrics(mi, dim, mi.base.textwidth, false);
|
||||
else
|
||||
tm.metrics(mi, dim, 0, false);
|
||||
mi.base.textwidth += 2 * TEXT_TO_INSET_OFFSET;
|
||||
dim.asc += TEXT_TO_INSET_OFFSET;
|
||||
dim.des += TEXT_TO_INSET_OFFSET;
|
||||
dim.wid += 2 * TEXT_TO_INSET_OFFSET;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -3921,8 +4013,7 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
|
||||
}
|
||||
|
||||
|
||||
bool InsetTabular::isCellSelected(Cursor & cur, row_type row, col_type col)
|
||||
const
|
||||
bool InsetTabular::isCellSelected(Cursor & cur, row_type row, col_type col) const
|
||||
{
|
||||
if (&cur.inset() == this && cur.selection()) {
|
||||
if (cur.selIsMultiCell()) {
|
||||
@ -5190,13 +5281,13 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
|
||||
return true;
|
||||
}
|
||||
// fall through
|
||||
case LFUN_NEWLINE_INSERT: {
|
||||
if (tabular.getPWidth(cur.idx()).zero()) {
|
||||
case LFUN_NEWLINE_INSERT:
|
||||
if ((tabular.isMultiColumn(cur.idx()) || tabular.isMultiRow(cur.idx()))
|
||||
&& tabular.getPWidth(cur.idx()).zero()) {
|
||||
status.setEnabled(false);
|
||||
return true;
|
||||
} else
|
||||
return cell(cur.idx())->getStatus(cur, cmd, status);
|
||||
}
|
||||
}
|
||||
return cell(cur.idx())->getStatus(cur, cmd, status);
|
||||
|
||||
case LFUN_NEWPAGE_INSERT:
|
||||
status.setEnabled(false);
|
||||
@ -5863,7 +5954,7 @@ void InsetTabular::tabularFeatures(Cursor & cur,
|
||||
// just multicol for one single cell
|
||||
// check whether we are completely in a multicol
|
||||
if (!tabular.isMultiColumn(cur.idx()))
|
||||
tabular.setMultiColumn(cur.idx(), 1,
|
||||
tabular.setMultiColumn(cur, cur.idx(), 1,
|
||||
tabular.rightLine(cur.idx()));
|
||||
break;
|
||||
}
|
||||
@ -5872,7 +5963,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());
|
||||
cur.idx() = tabular.setMultiColumn(s_start, col_end - col_start + 1,
|
||||
cur.idx() = tabular.setMultiColumn(cur, s_start, col_end - col_start + 1,
|
||||
tabular.rightLine(cur.selEnd().idx()));
|
||||
cur.pit() = 0;
|
||||
cur.pos() = 0;
|
||||
@ -5918,7 +6009,7 @@ void InsetTabular::tabularFeatures(Cursor & cur,
|
||||
// just multirow for one single cell
|
||||
// check whether we are completely in a multirow
|
||||
if (!tabular.isMultiRow(cur.idx()))
|
||||
tabular.setMultiRow(cur.idx(), 1,
|
||||
tabular.setMultiRow(cur, cur.idx(), 1,
|
||||
tabular.bottomLine(cur.idx()),
|
||||
tabular.getAlignment(cur.idx()));
|
||||
break;
|
||||
@ -5928,7 +6019,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());
|
||||
cur.idx() = tabular.setMultiRow(s_start, row_end - row_start + 1,
|
||||
cur.idx() = tabular.setMultiRow(cur, s_start, row_end - row_start + 1,
|
||||
tabular.bottomLine(cur.selEnd().idx()),
|
||||
tabular.getAlignment(cur.selEnd().idx()));
|
||||
cur.pit() = 0;
|
||||
@ -6141,7 +6232,7 @@ void InsetTabular::tabularFeatures(Cursor & cur,
|
||||
case Tabular::SET_LTCAPTION: {
|
||||
if (tabular.ltCaption(row))
|
||||
break;
|
||||
cur.idx() = tabular.setLTCaption(row, true);
|
||||
cur.idx() = tabular.setLTCaption(cur, row, true);
|
||||
cur.pit() = 0;
|
||||
cur.pos() = 0;
|
||||
cur.selection(false);
|
||||
@ -6157,7 +6248,7 @@ void InsetTabular::tabularFeatures(Cursor & cur,
|
||||
case Tabular::UNSET_LTCAPTION: {
|
||||
if (!tabular.ltCaption(row))
|
||||
break;
|
||||
cur.idx() = tabular.setLTCaption(row, false);
|
||||
cur.idx() = tabular.setLTCaption(cur, row, false);
|
||||
cur.pit() = 0;
|
||||
cur.pos() = 0;
|
||||
cur.selection(false);
|
||||
@ -6457,7 +6548,7 @@ bool InsetTabular::allowParagraphCustomization(idx_type cell) const
|
||||
|
||||
bool InsetTabular::forcePlainLayout(idx_type cell) const
|
||||
{
|
||||
return !tabular.getPWidth(cell).zero();
|
||||
return tabular.isMultiColumn(cell) && !tabular.getPWidth(cell).zero();
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,6 +63,10 @@ public:
|
||||
///
|
||||
void toggleFixedWidth(bool fw) { isFixedWidth = fw; }
|
||||
///
|
||||
void toggleMultiCol(bool m) { isMultiColumn = m; }
|
||||
///
|
||||
void toggleMultiRow(bool m) { isMultiRow = m; }
|
||||
///
|
||||
void setContentAlignment(LyXAlignment al) {contentAlign = al; }
|
||||
/// writes the contents of the cell as a string, optionally
|
||||
/// descending into insets
|
||||
@ -72,14 +76,17 @@ public:
|
||||
///
|
||||
void addToToc(DocIterator const & di, bool output_active,
|
||||
UpdateType utype, TocBackend & backend) const;
|
||||
///
|
||||
void metrics(MetricsInfo &, Dimension &) const;
|
||||
private:
|
||||
/// unimplemented
|
||||
InsetTableCell();
|
||||
/// unimplemented
|
||||
void operator=(InsetTableCell const &);
|
||||
// FIXME
|
||||
// This boolean is supposed to track whether the cell has had its
|
||||
// width explicitly set. We need to know this to determine whether
|
||||
// These booleans are supposed to track whether the cell has had its
|
||||
// width explicitly set and whether it is part of a multicolumn, respectively.
|
||||
// We need to know this to determine whether
|
||||
// layout changes and paragraph customization are allowed---that is,
|
||||
// we need it in forcePlainLayout() and allowParagraphCustomization().
|
||||
// Unfortunately, that information is not readily available in
|
||||
@ -102,6 +109,10 @@ private:
|
||||
// --rgh
|
||||
///
|
||||
bool isFixedWidth;
|
||||
///
|
||||
bool isMultiColumn;
|
||||
///
|
||||
bool isMultiRow;
|
||||
// FIXME: Here the thoughts from the comment above also apply.
|
||||
///
|
||||
LyXAlignment contentAlign;
|
||||
@ -120,11 +131,7 @@ private:
|
||||
/// Is the width forced to some value?
|
||||
bool hasFixedWidth() const { return isFixedWidth; }
|
||||
/// Can the cell contain several paragraphs?
|
||||
/** FIXME this is wrong for multirows, that are limited to one
|
||||
* paragraph. However, we cannot test for this (see the big
|
||||
* comment above).
|
||||
*/
|
||||
bool allowMultiPar() const { return isFixedWidth; }
|
||||
bool allowMultiPar() const { return !isMultiRow && (!isMultiColumn || isFixedWidth); }
|
||||
};
|
||||
|
||||
|
||||
@ -534,7 +541,9 @@ public:
|
||||
///
|
||||
bool hasVarwidthColumn() const;
|
||||
///
|
||||
idx_type setMultiColumn(idx_type cell, idx_type number,
|
||||
bool isVTypeColumn(col_type cell) const;
|
||||
///
|
||||
idx_type setMultiColumn(Cursor & cur, idx_type cell, idx_type number,
|
||||
bool const right_border);
|
||||
///
|
||||
void unsetMultiColumn(idx_type cell);
|
||||
@ -547,7 +556,7 @@ public:
|
||||
///
|
||||
bool hasMultiRow(row_type r) const;
|
||||
///
|
||||
idx_type setMultiRow(idx_type cell, idx_type number,
|
||||
idx_type setMultiRow(Cursor & cur, idx_type cell, idx_type number,
|
||||
bool const bottom_border,
|
||||
LyXAlignment const halign);
|
||||
///
|
||||
@ -595,7 +604,7 @@ public:
|
||||
///
|
||||
bool getLTNewPage(row_type row) const;
|
||||
///
|
||||
idx_type setLTCaption(row_type row, bool what);
|
||||
idx_type setLTCaption(Cursor & cur, row_type row, bool what);
|
||||
///
|
||||
bool ltCaption(row_type row) const;
|
||||
///
|
||||
@ -804,7 +813,7 @@ public:
|
||||
///
|
||||
idx_type rowSpan(idx_type cell) const;
|
||||
///
|
||||
BoxType useParbox(idx_type cell) const;
|
||||
BoxType useBox(idx_type cell) const;
|
||||
///
|
||||
// helper function for Latex
|
||||
///
|
||||
|
@ -59,6 +59,7 @@ Format LaTeX feature LyX feature
|
||||
546 Landscape support
|
||||
\begin{landscape}...\end{landscape} \begin_inset Flex Landscape
|
||||
with longtable content: <features rotate ="90"...>
|
||||
555 V column type (varwidth package) Automatically detected with newlines, paragraph breaks and environment content in cells of rows
|
||||
|
||||
|
||||
|
||||
|
@ -32,8 +32,8 @@ extern char const * const lyx_version_info;
|
||||
|
||||
// Do not remove the comment below, so we get merge conflict in
|
||||
// independent branches. Instead add your own.
|
||||
#define LYX_FORMAT_LYX 554 // spitz: tabularx/xltabular
|
||||
#define LYX_FORMAT_TEX2LYX 554
|
||||
#define LYX_FORMAT_LYX 555 // spitz: varwidth V columns
|
||||
#define LYX_FORMAT_TEX2LYX 555
|
||||
|
||||
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
|
||||
#ifndef _MSC_VER
|
||||
|
Loading…
Reference in New Issue
Block a user