Add toggle feature for all, outer and inner borders

Fix for bug #12503.

Also some bug fixes for the set inner lines algorithm. See discussion of #12503.
This commit is contained in:
Daniel Ramoeller 2022-03-13 08:57:49 +01:00 committed by Scott Kostyshak
parent a88f67ac60
commit f21899661a
16 changed files with 284 additions and 47 deletions

View File

@ -695,11 +695,11 @@ dist_images_DATA1X = \
images/tabular-feature_multicolumn.svgz \
images/tabular-feature_multirow.svgz \
images/tabular-feature_reset-formal-default.svgz \
images/tabular-feature_set-all-lines.svgz \
images/tabular-feature_toggle-all-lines.svgz \
images/tabular-feature_set-longtabular.svgz \
images/tabular-feature_set-rotate-cell.svgz \
images/tabular-feature_set-border-lines.svgz \
images/tabular-feature_set-inner-lines.svgz \
images/tabular-feature_toggle-border-lines.svgz \
images/tabular-feature_toggle-inner-lines.svgz \
images/tabular-feature_set-rotate-tabular.svgz \
images/tabular-feature_toggle-line-bottom.svgz \
images/tabular-feature_toggle-line-left.svgz \
@ -2155,9 +2155,9 @@ dist_imagesoxygen_DATA1X = \
images/oxygen/tabular-feature_multicolumn.svgz \
images/oxygen/tabular-feature_multirow.svgz \
images/oxygen/tabular-feature_reset-formal-default.svgz \
images/oxygen/tabular-feature_set-all-lines.svgz \
images/oxygen/tabular-feature_set-border-lines.svgz \
images/oxygen/tabular-feature_set-inner-lines.svgz \
images/oxygen/tabular-feature_toggle-all-lines.svgz \
images/oxygen/tabular-feature_toggle-border-lines.svgz \
images/oxygen/tabular-feature_toggle-inner-lines.svgz \
images/oxygen/tabular-feature_set-longtabular.svgz \
images/oxygen/tabular-feature_toggle-line-bottom.svgz \
images/oxygen/tabular-feature_toggle-line-left.svgz \
@ -2353,9 +2353,9 @@ dist_imagesclassic_DATA = \
images/classic/tabular-feature_multicolumn.png \
images/classic/tabular-feature_multirow.png \
images/classic/tabular-feature_reset-formal-default.png \
images/classic/tabular-feature_set-all-lines.png \
images/classic/tabular-feature_set-border-lines.png \
images/classic/tabular-feature_set-inner-lines.png \
images/classic/tabular-feature_toggle-all-lines.png \
images/classic/tabular-feature_toggle-border-lines.png \
images/classic/tabular-feature_toggle-inner-lines.png \
images/classic/tabular-feature_set-longtabular.png \
images/classic/tabular-feature_set-rotate-cell.png \
images/classic/tabular-feature_set-rotate-tabular.png \

View File

@ -143,6 +143,9 @@
ignore the inserted file's main language (and rather adapt it to the insertion
context's language).
* tabular-feature: added toggle parameters "toggle-all-lines", "toggle-border-lines"
and "toggle-inner-lines"
!!!The following LyX functions have been removed in 2.4:

View File

@ -1,5 +1,5 @@
#LyX 2.4 created this file. For more info see https://www.lyx.org/
\lyxformat 608
\lyxformat 609
\begin_document
\begin_header
\save_transient_properties true
@ -250,6 +250,7 @@ varwidth
\html_be_strict false
\docbook_table_output 0
\docbook_mathml_prefix 1
\author -1382599118 "Daniel"
\author -712698321 "Jürgen Spitzmüller"
\author 630872221 "Jean-Pierre Chrétien" jeanpierre.chretien@free.fr
\end_header
@ -2646,7 +2647,29 @@ type "icon"
arg "tabular-feature toggle-line-top"
\end_inset
adds a line at the top of the current cell / row or of a selection
\change_deleted -1382599118 1647157945
adds
\change_inserted -1382599118 1647157946
toggles
\change_unchanged
a line at the top of
\change_inserted -1382599118 1647158116
every cell for
\change_unchanged
the current
\change_inserted -1382599118 1647157889
ly
\change_deleted -1382599118 1647157917
cell / row or of a
\change_unchanged
select
\change_deleted -1382599118 1647157923
ion
\change_inserted -1382599118 1647157925
ed cells
\change_unchanged
\end_layout
\begin_layout Labeling
@ -2656,7 +2679,29 @@ type "icon"
arg "tabular-feature toggle-line-bottom"
\end_inset
adds a line at the bottom of the current cell / row or of a selection
\change_deleted -1382599118 1647157963
adds
\change_inserted -1382599118 1647157964
toggles
\change_unchanged
a line at the bottom of
\change_inserted -1382599118 1647158114
every cell for
\change_unchanged
the current
\change_inserted -1382599118 1647157991
ly
\change_deleted -1382599118 1647158003
cell / row or of a
\change_unchanged
select
\change_deleted -1382599118 1647158007
ion
\change_inserted -1382599118 1647158009
ed cells
\change_unchanged
\end_layout
\begin_layout Labeling
@ -2666,7 +2711,29 @@ type "icon"
arg "tabular-feature toggle-line-left"
\end_inset
adds a line at the left side of the current cell / row or of a selection
\change_deleted -1382599118 1647157971
adds
\change_inserted -1382599118 1647157972
toggles
\change_unchanged
a line at the left side of
\change_inserted -1382599118 1647158111
every cell for
\change_unchanged
the current
\change_inserted -1382599118 1647158027
ly
\change_deleted -1382599118 1647158069
cell / row or of a
\change_unchanged
select
\change_deleted -1382599118 1647158043
ion
\change_inserted -1382599118 1647158044
ed cells
\change_unchanged
\end_layout
\begin_layout Labeling
@ -2676,7 +2743,27 @@ type "icon"
arg "tabular-feature toggle-line-right"
\end_inset
adds a line at the right side of the current cell / row or of a selection
\change_deleted -1382599118 1647157974
adds
\change_inserted -1382599118 1647157975
toggles
\change_unchanged
a line at the right side of
\change_inserted -1382599118 1647158109
every cell for
\change_unchanged
the current
\change_inserted -1382599118 1647158061
ly
\change_deleted -1382599118 1647158072
cell / row or of a
\change_unchanged
select
\change_deleted -1382599118 1647158078
ion
\change_inserted -1382599118 1647158082
ed cells
\change_inserted -712698321 1554289731
\end_layout
@ -2687,10 +2774,30 @@ arg "tabular-feature toggle-line-right"
\change_inserted -712698321 1554289910
\begin_inset Info
type "icon"
arg "tabular-feature set-border-lines"
arg "tabular-feature toggle-border-lines"
\end_inset
adds a border around the currently selected cells
\change_deleted -1382599118 1647157966
adds
\change_inserted -1382599118 1647157967
toggles
\change_inserted -712698321 1554289910
a border around the currently selected cells
\change_inserted -1382599118 1647040213
\end_layout
\begin_layout Labeling
\labelwidthstring 00.00.0000
\change_inserted -1382599118 1647158092
\begin_inset Info
type "icon"
arg "tabular-feature toggle-inner-lines"
\end_inset
toggles inner lines for the currently selected cells
\change_unchanged
\end_layout
@ -2699,7 +2806,7 @@ arg "tabular-feature set-border-lines"
\labelwidthstring 00.00.0000
\begin_inset Info
type "icon"
arg "tabular-feature set-all-lines"
arg "tabular-feature toggle-all-lines"
\end_inset
adds lines around the current or selected cells - if the current cell is

View File

Before

Width:  |  Height:  |  Size: 201 B

After

Width:  |  Height:  |  Size: 201 B

View File

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 220 B

View File

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -164,9 +164,9 @@ ToolbarSet
Item "Toggle bottom line" "tabular-feature toggle-line-bottom"
Item "Toggle left line" "tabular-feature toggle-line-left"
Item "Toggle right line" "tabular-feature toggle-line-right"
Item "Set border lines" "tabular-feature set-border-lines"
Item "Set all lines" "tabular-feature set-all-lines"
Item "Set inner lines" "tabular-feature set-inner-lines"
Item "Toggle border lines" "tabular-feature toggle-border-lines"
Item "Toggle inner lines" "tabular-feature toggle-inner-lines"
Item "Toggle all lines" "tabular-feature toggle-all-lines"
Item "Unset all lines" "tabular-feature unset-all-lines"
Item "Reset formal default lines" "tabular-feature reset-formal-default"
Separator

View File

@ -3900,17 +3900,17 @@ void LyXAction::init()
valign-top|valign-bottom|valign-middle|longtabular-align-left|\n
longtabular-align-center|longtabular-align-right|m-align-left|m-align-right|\n
m-align-center|m-valign-top|m-valign-bottom|m-valign-middle|multicolumn|\n
reset-formal-default|set-all-lines|unset-all-lines|toggle-longtabular|\n
set-longtabular|unset-longtabular|set-pwidth|\n
reset-formal-default|set-all-lines|toggle-all-lines|unset-all-lines|\n
toggle-longtabular|set-longtabular|unset-longtabular|set-pwidth|\n
set-mpwidth|set-rotate-tabular|unset-rotate-tabular|toggle-rotate-tabular|\n
set-rotate-cell|unset-rotate-cell|toggle-rotate-cell|set-usebox|set-lthead|\n
unset-lthead|set-ltfirsthead|unset-ltfirsthead|set-ltfoot|unset-ltfoot|\n
set-ltlastfoot|unset-ltlastfoot|set-ltnewpage|toggle-ltcaption|\n
set-special-column|set-special-multicolumn|set-special-multirow|\n
toggle-booktabs|set-booktabs|unset-booktabs|set-top-space|set-bottom-space|\n
set-interline-space|set-border-lines|tabular-valign-top|\n
tabular-valign-middle|tabular-valign-bottom|set-tabular-width|\n
toggle-varwidth-column
set-interline-space|tabular-valign-top|tabular-valign-middle|\n
tabular-valign-bottom|set-tabular-width|toggle-varwidth-column|\n
set-border-lines|toggle-border-lines|set-inner-lines|toggle-inner-lines
Various math-environment features are handled as well, e.g. add-vline-left/right for\n
the Grid/Array environment.\n
<ARG>: additional argument for some commands, use debug mode to explore its values.

View File

@ -164,6 +164,7 @@ TabularFeature tabularFeature[] =
{ Tabular::UNSET_MULTIROW, "unset-multirow", false },
{ Tabular::SET_MROFFSET, "set-mroffset", true },
{ Tabular::SET_ALL_LINES, "set-all-lines", false },
{ Tabular::TOGGLE_ALL_LINES, "toggle-all-lines", false },
{ Tabular::RESET_FORMAL_DEFAULT, "reset-formal-default", false },
{ Tabular::UNSET_ALL_LINES, "unset-all-lines", false },
{ Tabular::TOGGLE_LONGTABULAR, "toggle-longtabular", false },
@ -201,6 +202,7 @@ TabularFeature tabularFeature[] =
{ Tabular::SET_BOTTOM_SPACE, "set-bottom-space", true },
{ Tabular::SET_INTERLINE_SPACE, "set-interline-space", true },
{ Tabular::SET_BORDER_LINES, "set-border-lines", false },
{ Tabular::TOGGLE_BORDER_LINES, "toggle-border-lines", false },
{ Tabular::TABULAR_VALIGN_TOP, "tabular-valign-top", false},
{ Tabular::TABULAR_VALIGN_MIDDLE, "tabular-valign-middle", false},
{ Tabular::TABULAR_VALIGN_BOTTOM, "tabular-valign-bottom", false},
@ -210,6 +212,7 @@ TabularFeature tabularFeature[] =
{ Tabular::SET_DECIMAL_POINT, "set-decimal-point", true },
{ Tabular::SET_TABULAR_WIDTH, "set-tabular-width", true },
{ Tabular::SET_INNER_LINES, "set-inner-lines", false },
{ Tabular::TOGGLE_INNER_LINES, "toggle-inner-lines", false },
{ Tabular::LAST_ACTION, "", false }
};
@ -1121,6 +1124,76 @@ bool Tabular::rightLine(idx_type cell, bool const ignore_bt) const
}
bool Tabular::outsideBorders(
row_type const sel_row_start, row_type const sel_row_end,
col_type const sel_col_start, col_type const sel_col_end) const
{
if (!use_booktabs)
for (row_type r = sel_row_start; r <= sel_row_end; ++r) {
if (!leftLine(cellIndex(r, sel_col_start))
|| !rightLine(cellIndex(r, sel_col_end)))
return false;
}
for (col_type c = sel_col_start; c <= sel_col_end; ++c) {
if (!topLine(cellIndex(sel_row_start, c))
|| !bottomLine(cellIndex(sel_row_end, c)))
return false;
}
return true;
}
bool Tabular::innerBorders(
row_type const sel_row_start, row_type const sel_row_end,
col_type const sel_col_start, col_type const sel_col_end) const
{
// Single cell has no inner borders
if (sel_row_start == sel_row_end && sel_col_start == sel_col_end)
return 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) {
idx_type const cell = cellIndex(r, c);
if ((r != sel_row_start && !topLine(cell)
&& cell_info[r][c].multirow != CELL_PART_OF_MULTIROW)
|| (!use_booktabs
&& c != sel_col_start && !leftLine(cell)
&& cell_info[r][c].multicolumn != CELL_PART_OF_MULTICOLUMN))
return false;
}
return true;
}
void Tabular::setLines(
row_type const sel_row_start, row_type const sel_row_end,
col_type const sel_col_start, col_type const sel_col_end,
bool setLinesInnerOnly, bool 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 = cellIndex(r, c);
if (!(setLinesInnerOnly && r == sel_row_start)
// for multirows, cell is taken care of at beginning
&& cell_info[r][c].multirow != CELL_PART_OF_MULTIROW)
setTopLine(cell, setLines);
if (!(setLinesInnerOnly && r == sel_row_end)
&& (r == sel_row_end || (!setLines
// for multirows, cell is taken care of at the last part
&& cell_info[r + 1][c].multirow != CELL_PART_OF_MULTIROW)))
setBottomLine(cell, setLines);
if (!(setLinesInnerOnly && c == sel_col_start)
// for multicolumns, cell is taken care of at beginning
&& cell_info[r][c].multicolumn != CELL_PART_OF_MULTICOLUMN)
setLeftLine(cell, setLines);
if (!(setLinesInnerOnly && c == sel_col_end)
&& (c == sel_col_end || (!setLines
// for multicolumns, cell is taken care of at the last part
&& cell_info[r][c + 1].multicolumn != CELL_PART_OF_MULTICOLUMN)))
setRightLine(cell, setLines);
}
}
pair<bool, bool> Tabular::topLineTrim(idx_type const cell) const
{
if (!use_booktabs)
@ -5657,9 +5730,28 @@ bool InsetTabular::getFeatureStatus(Cursor & cur, string const & s,
status.setOnOff(tabular.isMultiRow(cur.idx()));
break;
case Tabular::TOGGLE_INNER_LINES:
status.setOnOff(tabular.innerBorders(sel_row_start, sel_row_end,
sel_col_start, sel_col_end));
status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
break;
case Tabular::TOGGLE_ALL_LINES:
status.setOnOff(tabular.innerBorders(sel_row_start, sel_row_end,
sel_col_start, sel_col_end)
&& tabular.outsideBorders(sel_row_start, sel_row_end,
sel_col_start, sel_col_end));
status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
break;
case Tabular::SET_ALL_LINES:
case Tabular::UNSET_ALL_LINES:
case Tabular::SET_INNER_LINES:
status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
break;
case Tabular::TOGGLE_BORDER_LINES:
status.setOnOff(tabular.outsideBorders(sel_row_start, sel_row_end,
sel_col_start, sel_col_end));
// fall through
case Tabular::SET_BORDER_LINES:
status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
break;
@ -6511,7 +6603,7 @@ void InsetTabular::tabularFeatures(Cursor & cur,
row_type sel_row_start;
row_type sel_row_end;
bool setLines = false;
bool setLinesInnerOnly = false;
bool toggle = false;
LyXAlignment setAlign = LYX_ALIGN_LEFT;
Tabular::VAlignment setVAlign = Tabular::LYX_VALIGN_TOP;
@ -6935,27 +7027,36 @@ void InsetTabular::tabularFeatures(Cursor & cur,
break;
}
case Tabular::TOGGLE_INNER_LINES:
toggle = true;
// fall through
case Tabular::SET_INNER_LINES:
setLinesInnerOnly = true;
if (toggle)
setLines = !tabular.innerBorders(sel_row_start, sel_row_end,
sel_col_start, sel_col_end);
else
setLines = true;
tabular.setLines(sel_row_start, sel_row_end,
sel_col_start, sel_col_end,
true, setLines);
break;
case Tabular::TOGGLE_ALL_LINES:
toggle = true;
// fall through
case Tabular::SET_ALL_LINES:
setLines = true;
if (toggle)
setLines = !tabular.innerBorders(sel_row_start, sel_row_end,
sel_col_start, sel_col_end)
|| !tabular.outsideBorders(sel_row_start, sel_row_end,
sel_col_start, sel_col_end);
else
setLines = true;
// fall through
case Tabular::UNSET_ALL_LINES:
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);
if (!setLinesInnerOnly || r != sel_row_start)
tabular.setTopLine(cell, setLines);
if ((!setLinesInnerOnly || r != sel_row_end)
&& (!setLines || r == sel_row_end))
tabular.setBottomLine(cell, setLines);
if ((!setLinesInnerOnly || c != sel_col_end)
&& (!setLines || c == sel_col_end))
tabular.setRightLine(cell, setLines);
if ((!setLinesInnerOnly || c != sel_col_start))
tabular.setLeftLine(cell, setLines);
}
tabular.setLines(sel_row_start, sel_row_end,
sel_col_start, sel_col_end,
false, setLines);
break;
case Tabular::RESET_FORMAL_DEFAULT:
@ -6969,16 +7070,24 @@ void InsetTabular::tabularFeatures(Cursor & cur,
}
break;
case Tabular::SET_BORDER_LINES:
case Tabular::TOGGLE_BORDER_LINES:
toggle = true;
// fall through
case Tabular::SET_BORDER_LINES: {
bool const border = toggle &&
tabular.outsideBorders(sel_row_start, sel_row_end,
sel_col_start, sel_col_end)
? false : 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);
tabular.setLeftLine(tabular.cellIndex(r, sel_col_start), border);
tabular.setRightLine(tabular.cellIndex(r, sel_col_end), border);
}
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);
tabular.setTopLine(tabular.cellIndex(sel_row_start, c), border);
tabular.setBottomLine(tabular.cellIndex(sel_row_end, c), border);
}
break;
}
case Tabular::TOGGLE_LONGTABULAR:
if (tabular.is_long_tabular)

View File

@ -341,6 +341,12 @@ public:
///
SET_INNER_LINES,
///
TOGGLE_INNER_LINES,
///
TOGGLE_BORDER_LINES,
///
TOGGLE_ALL_LINES,
///
LAST_ACTION
};
///
@ -445,6 +451,18 @@ public:
/// If \p ignore_bt is true, we return the state as if booktabs was
/// not used
bool rightLine(idx_type cell, bool const ignore_bt = false) const;
/// Returns true if there is an outside border around the selection
bool outsideBorders(row_type sel_row_start, row_type sel_row_end,
col_type sel_col_start, col_type sel_col_end) const;
/// Returns true if there are inside lines in the selection
bool innerBorders(row_type sel_row_start, row_type sel_row_end,
col_type sel_col_start, col_type sel_col_end) const;
/// Sets the grid lines in the selection
/// if \p setLinesInnerOnly is true, outside borders are excluded
/// if \p setLines is true the lines are set otherwise they are unset
void setLines(row_type const sel_row_start, row_type const sel_row_end,
col_type const sel_col_start, col_type const sel_col_end,
bool setLinesInnerOnly, bool setLines);
/// Returns whether the top line is trimmed left and/or right
std::pair<bool, bool> topLineTrim(idx_type const cell) const;
/// Returns whether the bottom line is trimmed left and/or right