This has probably still some rough edges, so please test thoroughly.
Fixes: #3072
-----------------------
+2019-04-03 Jürgen Spitzmüller <spitz@lyx.org>
+ * format incremented to 571: Add \cmidrule trimming support
+ \cmidrule(lr){n-n}
+ <cell ... toplineltrim|toplinettrim|bottomlineltrim|bottomlinertrim true ...>
+
2019-03-29 Jürgen Spitzmüller <spitz@lyx.org>
* format incremented to 570: Add individual bib encodings for biblatex
\begin_inset CommandInset bibtex
i = j + 1
+def revert_cmidruletrimming(document):
+ " Remove \\cmidrule trimming "
+
+ # FIXME: Revert to TeX code?
+ i = 0
+ while True:
+ # first, let's find out if we need to do anything
+ i = find_token(document.body, '<cell ', i)
+ if i == -1:
+ return
+ j = document.body[i].find('trim="')
+ if j == -1:
+ i += 1
+ continue
+ rgx = re.compile(r' (bottom|top)line[lr]trim="true"')
+ # remove trim option
+ document.body[i] = rgx.sub('', document.body[i])
+
+ i += 1
+
##
# Conversion hub
[567, []],
[568, []],
[569, []],
- [570, []]
+ [570, []],
+ [571, []]
]
revert = [
+ [570, [revert_cmidruletrimming]],
[569, [revert_bibfileencodings]],
[568, [revert_tablestyle]],
[567, [revert_soul]],
* \li Params: Generally see #LFUN_INSET_INSERT for further details.\n
* <FEATURE>: append-row|append-column|delete-row|delete-column|copy-row|\n
copy-column|move-column-right|move-column-left|move-row-down|move-row-up|\n
+ set-line-top|set-line-bottom|set-line-left|set-line-right|\n
toggle-line-top|toggle-line-bottom|toggle-line-left|toggle-line-right|\n
+ set-ltrim-top|set-rtrim-top|set-ltrim-bottom|set-rtrim-bottom\n
+ toggle-ltrim-top|toggle-rtrim-top|toggle-ltrim-bottom|toggle-rtrim-bottom\n
align-left|align-right|align-center|align-block|align-decimal|set-decimal-point|\n
valign-top|valign-bottom|valign-middle|longtabular-align-left|\n
longtabular-align-center|longtabular-align-right|m-align-left|m-align-right|\n
*
* \author Edwin Leuven
* \author John Levon
+ * \author Jürgen Spitzmüller
*
* Full author contact details are available in file CREDITS.
*/
#include "GuiSetBorder.h"
+#include "support/debug.h"
+
#include <QPainter>
#include <QMouseEvent>
#include <QPaintEvent>
GuiSetBorder::GuiSetBorder(QWidget * parent, Qt::WindowFlags fl)
- : QWidget(parent, fl), buffer(75, 75)
+ : QWidget(parent, fl), buffer(75, 75), bottom_drawn_wide_(false),
+ top_drawn_wide_(false)
{
/* length of corner line */
- l = buffer.width() / 10;
+ corner_length = buffer.width() / 10;
/* margin */
- m = buffer.height() / 10;
+ margin = buffer.height() / 10;
- w = buffer.width();
- h = buffer.height();
+ bwidth = buffer.width();
+ bheight = buffer.height();
init();
- setMinimumSize(w,h);
- setMaximumSize(w,h);
+ setMinimumSize(bwidth, bheight);
+ setMaximumSize(bwidth, bheight);
}
paint.setPen(Qt::black);
- // FIXME: wow, readable !! :)
-
- paint.drawLine(m + l , m, m + l, m + l);
- paint.drawLine(w - (m + l), m, w - (m + l), m + l);
-
- paint.drawLine(m, m + l , m + l, m + l);
- paint.drawLine(m, h - (m + l), m + l, h - (m + l));
-
- paint.drawLine(m + l ,h - m, m + l ,h - (m + l));
- paint.drawLine(w - (m + l), h - m, w - (m + l), h - (m + l));
-
- paint.drawLine(h - m, m+l, h - (m + l), m + l);
- paint.drawLine(h - m, h - (m + l), h - (m + l),h - (m + l));
+ // Draw the corner marks
+ paint.drawLine(margin + corner_length, margin,
+ margin + corner_length, margin + corner_length);
+ paint.drawLine(bwidth - (margin + corner_length), margin,
+ bwidth - (margin + corner_length), margin + corner_length);
+
+ paint.drawLine(margin, margin + corner_length,
+ margin + corner_length, margin + corner_length);
+ paint.drawLine(margin, bheight - (margin + corner_length),
+ margin + corner_length, bheight - (margin + corner_length));
+
+ paint.drawLine(margin + corner_length ,bheight - margin,
+ margin + corner_length ,bheight - (margin + corner_length));
+ paint.drawLine(bwidth - (margin + corner_length), bheight - margin,
+ bwidth - (margin + corner_length), bheight - (margin + corner_length));
+
+ paint.drawLine(bheight - margin, margin+corner_length,
+ bheight - (margin + corner_length), margin + corner_length);
+ paint.drawLine(bheight - margin, bheight - (margin + corner_length),
+ bheight - (margin + corner_length),bheight - (margin + corner_length));
}
leftSet();
}
} else {
- if (bottom_.enabled) {
+ if (bottom_trim_left_.enabled && e->x() < margin + 4 + 2 * corner_length) {
+ setBottomLeftTrim(bottom_trim_left_.set == LINE_SET ? LINE_UNSET : LINE_SET);
+ // emit signal
+ bottomLTSet();
+ } else if (bottom_trim_right_.enabled && e->x() > bwidth - margin - 2 * corner_length - 4) {
+ setBottomRightTrim(bottom_trim_right_.set == LINE_SET ? LINE_UNSET : LINE_SET);
+ // emit signal
+ bottomRTSet();
+ } else if (bottom_.enabled) {
setBottom(bottom_.set == LINE_SET ? LINE_UNSET : LINE_SET);
// emit signal
bottomSet();
}
} else {
if (e->y() < height() - e->x()) {
- if (top_.enabled) {
+ if (top_trim_left_.enabled && e->x() < margin + 4 + 2 * corner_length) {
+ setTopLeftTrim(top_trim_left_.set == LINE_SET ? LINE_UNSET : LINE_SET);
+ // emit signal
+ topLTSet();
+ } else if (top_trim_right_.enabled && e->x() > bwidth - margin - 2 * corner_length - 4) {
+ setTopRightTrim(top_trim_right_.set == LINE_SET ? LINE_UNSET : LINE_SET);
+ // emit signal
+ topRTSet();
+ } else if (top_.enabled) {
setTop(top_.set == LINE_SET ? LINE_UNSET : LINE_SET);
// emit signal
topSet();
}
if (!left_.enabled)
col = QColor(Qt::lightGray);
- drawLine(col, m + l, m + l + 2, m + l, h - m - l - 1);
+ drawLine(col, margin + corner_length, margin + corner_length + 2,
+ margin + corner_length, bheight - margin - corner_length - 1);
}
}
if (!right_.enabled)
col = QColor(Qt::lightGray);
- drawLine(col, h - m - l + 1, m + l + 2, h - m - l + 1, h - m - l - 1);
+ drawLine(col, bheight - margin - corner_length + 1, margin + corner_length + 2,
+ bheight - margin - corner_length + 1, bheight - margin - corner_length - 1);
}
switch (draw) {
case LINE_SET:
col = Qt::black;
+ top_drawn_wide_ = true;
break;
case LINE_UNSET:
col = Qt::white;
+ top_drawn_wide_ = false;
break;
case LINE_UNDECIDED:
case LINE_UNDEF:
col = Qt::lightGray;
+ top_drawn_wide_ = true;
break;
}
if (!top_.enabled)
col = QColor(Qt::lightGray);
- drawLine(col, m + l + 2, m + l, w - m - l - 1, m + l);
+ int const lt = (top_trim_left_.enabled) ? corner_length + 4 : 0;
+ int const rt = (top_trim_right_.enabled) ? corner_length + 4 : 0;
+ drawLine(col, margin + corner_length + 2 + lt, margin + corner_length,
+ bwidth - margin - corner_length - 1 - rt, margin + corner_length);
+}
+
+
+void GuiSetBorder::undrawWideTopLine()
+{
+ if (!top_drawn_wide_)
+ return;
+
+ // Overpaint previous lines white
+ drawLine(Qt::white, margin + corner_length + 2, margin + corner_length,
+ bwidth - margin - corner_length - 1, margin + corner_length);
+ top_drawn_wide_ = false;
+}
+
+
+void GuiSetBorder::drawTopLeftTrim(BorderState draw)
+{
+ QColor col;
+ switch (draw) {
+ case LINE_SET:
+ col = Qt::black;
+ break;
+ case LINE_UNSET:
+ col = Qt::white;
+ break;
+ case LINE_UNDECIDED:
+ case LINE_UNDEF:
+ col = Qt::lightGray;
+ break;
+ }
+ if (!top_trim_left_.enabled)
+ col = QColor(Qt::white);
+ int const lt = corner_length;
+ if (top_trim_left_.enabled)
+ drawLine(col, margin + corner_length + 2, margin + corner_length,
+ margin + corner_length + 2 + lt, margin + corner_length);
+}
+
+
+void GuiSetBorder::drawTopRightTrim(BorderState draw)
+{
+ QColor col;
+ switch (draw) {
+ case LINE_SET:
+ col = Qt::black;
+ break;
+ case LINE_UNSET:
+ col = Qt::white;
+ break;
+ case LINE_UNDECIDED:
+ case LINE_UNDEF:
+ col = Qt::lightGray;
+ break;
+ }
+ if (!top_trim_right_.enabled)
+ col = QColor(Qt::white);
+ int const rt = corner_length;
+ if (top_trim_right_.enabled)
+ drawLine(col, bwidth - margin - corner_length - 1 - rt, margin + corner_length,
+ bwidth - margin - corner_length - 1, margin + corner_length);
}
switch (draw) {
case LINE_SET:
col = Qt::black;
+ bottom_drawn_wide_ = true;
break;
case LINE_UNSET:
col = Qt::white;
+ bottom_drawn_wide_ = false;
break;
case LINE_UNDECIDED:
case LINE_UNDEF:
col = Qt::lightGray;
+ bottom_drawn_wide_ = true;
break;
}
if (!bottom_.enabled)
col = QColor(Qt::lightGray);
- drawLine(col, m + l + 2, w - m - l + 1, w - m - l - 1, w - m - l + 1);
+ int const lt = (bottom_trim_left_.enabled) ? corner_length + 4 : 0;
+ int const rt = (bottom_trim_right_.enabled) ? corner_length + 4 : 0;
+ drawLine(col, margin + corner_length + 2 + lt, bwidth - margin - corner_length + 1,
+ bwidth - margin - corner_length - 1 - rt, bwidth - margin - corner_length + 1);
+}
+
+
+void GuiSetBorder::undrawWideBottomLine()
+{
+ if (!bottom_drawn_wide_)
+ return;
+
+ //Overpaint previous lines white
+ drawLine(Qt::white, margin + corner_length + 2, bwidth - margin - corner_length + 1,
+ bwidth - margin - corner_length - 1, bwidth - margin - corner_length + 1);
+ bottom_drawn_wide_ = false;
+}
+
+
+void GuiSetBorder::drawBottomLeftTrim(BorderState draw)
+{
+ QColor col;
+ switch (draw) {
+ case LINE_SET:
+ col = Qt::black;
+ break;
+ case LINE_UNSET:
+ col = Qt::white;
+ break;
+ case LINE_UNDECIDED:
+ case LINE_UNDEF:
+ col = Qt::lightGray;
+ break;
+ }
+ if (!bottom_trim_left_.enabled)
+ col = QColor(Qt::white);
+ int const lt = corner_length;
+ if (bottom_trim_left_.enabled)
+ drawLine(col, margin + corner_length + 2, bwidth - margin - corner_length + 1,
+ margin + corner_length + 2 + lt, bwidth - margin - corner_length + 1);
+}
+
+
+void GuiSetBorder::drawBottomRightTrim(BorderState draw)
+{
+ QColor col;
+ switch (draw) {
+ case LINE_SET:
+ col = Qt::black;
+ break;
+ case LINE_UNSET:
+ col = Qt::white;
+ break;
+ case LINE_UNDECIDED:
+ case LINE_UNDEF:
+ col = Qt::lightGray;
+ break;
+ }
+ if (!bottom_trim_right_.enabled)
+ col = QColor(Qt::white);
+ int const rt = corner_length;
+ if (bottom_trim_right_.enabled)
+ drawLine(col, bwidth - margin - corner_length - 1 - rt, bwidth - margin - corner_length + 1,
+ bwidth - margin - corner_length - 1, bwidth - margin - corner_length + 1);
}
}
+void GuiSetBorder::setTopLeftTrimEnabled(bool enabled)
+{
+ top_trim_left_.enabled = enabled;
+ undrawWideTopLine();
+ drawTopLeftTrim(top_trim_left_.set);
+ drawTop(top_.set);
+ top_drawn_wide_ = !enabled;
+}
+
+
+void GuiSetBorder::setTopRightTrimEnabled(bool enabled)
+{
+ top_trim_right_.enabled = enabled;
+ undrawWideTopLine();
+ drawTopRightTrim(top_trim_right_.set);
+ drawTop(top_.set);
+ top_drawn_wide_ = !enabled;;
+}
+
+
+void GuiSetBorder::setBottomLeftTrimEnabled(bool enabled)
+{
+ bottom_trim_left_.enabled = enabled;
+ undrawWideBottomLine();
+ drawBottomLeftTrim(bottom_trim_left_.set);
+ drawBottom(bottom_.set);
+ bottom_drawn_wide_ = !enabled;;
+}
+
+
+void GuiSetBorder::setBottomRightTrimEnabled(bool enabled)
+{
+ bottom_trim_right_.enabled = enabled;
+ undrawWideBottomLine();
+ drawBottomRightTrim(bottom_trim_right_.set);
+ drawBottom(bottom_.set);
+ bottom_drawn_wide_ = !enabled;;
+}
+
+
void GuiSetBorder::setLeft(BorderState border)
{
left_.set = border;
}
+void GuiSetBorder::setTopLeftTrim(BorderState border)
+{
+ top_trim_left_.set = border;
+ drawTopLeftTrim(border);
+}
+
+
+void GuiSetBorder::setTopRightTrim(BorderState border)
+{
+ top_trim_right_.set = border;
+ drawTopRightTrim(border);
+}
+
+
+void GuiSetBorder::setBottomLeftTrim(BorderState border)
+{
+ bottom_trim_left_.set = border;
+ drawBottomLeftTrim(border);
+}
+
+void GuiSetBorder::setBottomRightTrim(BorderState border)
+{
+ bottom_trim_right_.set = border;
+ drawBottomRightTrim(border);
+}
+
+
void GuiSetBorder::setAll(BorderState border)
{
setLeft(border);
setRight(border);
setTop(border);
setBottom(border);
+ setTopLeftTrim(border);
+ setTopRightTrim(border);
+ setBottomLeftTrim(border);
+ setBottomRightTrim(border);
}
return bottom_.set;
}
+
+GuiSetBorder::BorderState GuiSetBorder::getTopLeftTrim()
+{
+ return top_trim_left_.set;
+}
+
+
+GuiSetBorder::BorderState GuiSetBorder::getTopRightTrim()
+{
+ return top_trim_right_.set;
+}
+
+
+GuiSetBorder::BorderState GuiSetBorder::getBottomLeftTrim()
+{
+ return bottom_trim_left_.set;
+}
+
+
+GuiSetBorder::BorderState GuiSetBorder::getBottomRightTrim()
+{
+ return bottom_trim_right_.set;
+}
+
#include "moc_GuiSetBorder.cpp"
*
* \author Edwin Leuven
* \author John Levon
+ * \author Jürgen Spitzmüller
*
* Full author contact details are available in file CREDITS.
*/
{
Q_OBJECT
public:
- GuiSetBorder(QWidget * parent = 0, Qt::WindowFlags fl = 0);
+ GuiSetBorder(QWidget * parent = nullptr, Qt::WindowFlags fl = nullptr);
// We need tristate for multi-cell selection
enum BorderState {
BorderState getRight();
BorderState getTop();
BorderState getBottom();
+ BorderState getTopLeftTrim();
+ BorderState getTopRightTrim();
+ BorderState getBottomLeftTrim();
+ BorderState getBottomRightTrim();
bool leftLineSet() { return getLeft() == LINE_SET; }
bool rightLineSet() { return getRight() == LINE_SET; }
bool topLineUnset() { return getTop() == LINE_UNSET; }
bool bottomLineUnset() { return getBottom() == LINE_UNSET; }
+ bool topLineLTSet() { return getTopLeftTrim() == LINE_SET; }
+ bool bottomLineLTSet() { return getBottomLeftTrim() == LINE_SET; }
+ bool topLineRTSet() { return getTopRightTrim() == LINE_SET; }
+ bool bottomLineRTSet() { return getBottomRightTrim() == LINE_SET; }
+
+ bool topLineLTUnset() { return getTopLeftTrim() == LINE_UNSET; }
+ bool bottomLineLTUnset() { return getBottomLeftTrim() == LINE_UNSET; }
+ bool topLineRTUnset() { return getTopRightTrim() == LINE_UNSET; }
+ bool bottomLineRTUnset() { return getBottomRightTrim() == LINE_UNSET; }
+
Q_SIGNALS:
void rightSet();
void leftSet();
void topSet();
void bottomSet();
+ void topLTSet();
+ void bottomLTSet();
+ void topRTSet();
+ void bottomRTSet();
void clicked();
public Q_SLOTS:
void setRightEnabled(bool);
void setTopEnabled(bool);
void setBottomEnabled(bool);
+ void setTopLeftTrimEnabled(bool);
+ void setTopRightTrimEnabled(bool);
+ void setBottomLeftTrimEnabled(bool);
+ void setBottomRightTrimEnabled(bool);
void setLeft(BorderState);
void setRight(BorderState);
void setTop(BorderState);
void setBottom(BorderState);
+ void setTopLeftTrim(BorderState);
+ void setTopRightTrim(BorderState);
+ void setBottomLeftTrim(BorderState);
+ void setBottomRightTrim(BorderState);
void setAll(BorderState);
protected:
void drawLeft(BorderState);
void drawRight(BorderState);
void drawTop(BorderState);
+ void undrawWideTopLine();
void drawBottom(BorderState);
+ void undrawWideBottomLine();
+ void drawTopLeftTrim(BorderState);
+ void drawTopRightTrim(BorderState);
+ void drawBottomLeftTrim(BorderState);
+ void drawBottomRightTrim(BorderState);
class Border {
public:
Border right_;
Border top_;
Border bottom_;
+ /// trim areas
+ Border top_trim_left_;
+ Border top_trim_right_;
+ Border bottom_trim_left_;
+ Border bottom_trim_right_;
- int m;
- int l;
- int w;
- int h;
+ int margin;
+ int corner_length;
+ int bwidth;
+ int bheight;
QPixmap buffer;
+
+ bool bottom_drawn_wide_;
+ bool top_drawn_wide_;
};
GuiTabular::GuiTabular(QWidget * parent)
: InsetParamsWidget(parent), firstheader_suppressable_(false),
lastfooter_suppressable_(false), orig_leftborder_(GuiSetBorder::LINE_UNDEF),
- orig_rightborder_(GuiSetBorder::LINE_UNDEF)
+ orig_rightborder_(GuiSetBorder::LINE_UNDEF), lastrow_(0)
{
setupUi(this);
this, SLOT(checkEnabled()));
connect(borders, SIGNAL(leftSet()),
this, SLOT(checkEnabled()));
+ connect(borders, SIGNAL(topLTSet()),
+ this, SLOT(checkEnabled()));
+ connect(borders, SIGNAL(topRTSet()),
+ this, SLOT(checkEnabled()));
+ connect(borders, SIGNAL(bottomLTSet()),
+ this, SLOT(checkEnabled()));
+ connect(borders, SIGNAL(bottomRTSet()),
+ this, SLOT(checkEnabled()));
connect(rotateTabularCB, SIGNAL(clicked()),
this, SLOT(checkEnabled()));
connect(rotateTabularAngleSB, SIGNAL(valueChanged(int)),
// Vertical lines cannot be set in formal tables
borders->setLeftEnabled(!booktabsRB->isChecked());
borders->setRightEnabled(!booktabsRB->isChecked());
+ // Trimming is only allowed in booktabs and if the line is set
+ int const row = tabularRowED->text().toInt();
+ borders->setTopLeftTrimEnabled(booktabsRB->isChecked()
+ && borders->topLineSet()
+ && row > 1);
+ borders->setTopRightTrimEnabled(booktabsRB->isChecked()
+ && borders->topLineSet()
+ && row > 1);
+ borders->setBottomLeftTrimEnabled(booktabsRB->isChecked()
+ && borders->bottomLineSet()
+ && row < lastrow_);
+ borders->setBottomRightTrimEnabled(booktabsRB->isChecked()
+ && borders->bottomLineSet()
+ && row < lastrow_);
}
borders->setBottom(GuiSetBorder::LINE_SET);
borders->setLeft(GuiSetBorder::LINE_SET);
borders->setRight(GuiSetBorder::LINE_SET);
+ borders->setTopLeftTrim(GuiSetBorder::LINE_SET);
+ borders->setBottomLeftTrim(GuiSetBorder::LINE_SET);
+ borders->setTopRightTrim(GuiSetBorder::LINE_SET);
+ borders->setBottomRightTrim(GuiSetBorder::LINE_SET);
// repaint the setborder widget
borders->update();
checkEnabled();
borders->setBottom(GuiSetBorder::LINE_UNSET);
borders->setLeft(GuiSetBorder::LINE_UNSET);
borders->setRight(GuiSetBorder::LINE_UNSET);
+ borders->setTopLeftTrim(GuiSetBorder::LINE_UNSET);
+ borders->setBottomLeftTrim(GuiSetBorder::LINE_UNSET);
+ borders->setTopRightTrim(GuiSetBorder::LINE_UNSET);
+ borders->setBottomRightTrim(GuiSetBorder::LINE_UNSET);
// repaint the setborder widget
borders->update();
checkEnabled();
setParam(param_str, Tabular::SET_LINE_BOTTOM,
borders->bottomLineSet() ? "true" : "false");
}
+ if (borders->topLineLTSet())
+ setParam(param_str, Tabular::SET_LTRIM_TOP, "false");
+ else if (borders->topLineLTUnset())
+ setParam(param_str, Tabular::SET_LTRIM_TOP, "true");
+ if (borders->topLineRTSet())
+ setParam(param_str, Tabular::SET_RTRIM_TOP, "false");
+ else if (borders->topLineRTUnset())
+ setParam(param_str, Tabular::SET_RTRIM_TOP, "true");
+ if (borders->bottomLineLTSet())
+ setParam(param_str, Tabular::SET_LTRIM_BOTTOM, "false");
+ else if (borders->bottomLineRTUnset())
+ setParam(param_str, Tabular::SET_LTRIM_BOTTOM, "true");
+ if (borders->bottomLineRTSet())
+ setParam(param_str, Tabular::SET_RTRIM_BOTTOM, "false");
+ else if (borders->bottomLineRTUnset())
+ setParam(param_str, Tabular::SET_RTRIM_BOTTOM, "true");
// apply the special alignment
string special = fromqstr(specialAlignmentED->text());
tabularRowED->setText(QString::number(row + 1));
tabularColumnED->setText(QString::number(col + 1));
+ lastrow_ = int(tabular.nrows());
bool const multicol = tabular.isMultiColumn(cell);
multicolumnCB->setChecked(multicol);
}
// In what follows, we check the borders of all selected cells,
- // and if there are diverging settings, we use the LINE_UNDEF
+ // and if there are diverging settings, we use the LINE_UNDECIDED
// border status.
- GuiSetBorder::BorderState lt = GuiSetBorder::LINE_UNDEF;
- GuiSetBorder::BorderState lb = GuiSetBorder::LINE_UNDEF;
- GuiSetBorder::BorderState ll = GuiSetBorder::LINE_UNDEF;
- GuiSetBorder::BorderState lr = GuiSetBorder::LINE_UNDEF;
+ GuiSetBorder::BorderState ltop = GuiSetBorder::LINE_UNDEF;
+ GuiSetBorder::BorderState lbottom = GuiSetBorder::LINE_UNDEF;
+ GuiSetBorder::BorderState lleft = GuiSetBorder::LINE_UNDEF;
+ GuiSetBorder::BorderState lright = GuiSetBorder::LINE_UNDEF;
+ GuiSetBorder::BorderState ltop_ltrim = GuiSetBorder::LINE_UNDEF;
+ GuiSetBorder::BorderState ltop_rtrim = GuiSetBorder::LINE_UNDEF;
+ GuiSetBorder::BorderState lbottom_ltrim = GuiSetBorder::LINE_UNDEF;
+ GuiSetBorder::BorderState lbottom_rtrim = GuiSetBorder::LINE_UNDEF;
CursorSlice const & beg = bv->cursor().selBegin();
CursorSlice const & end = bv->cursor().selEnd();
if (beg != end) {
for (Tabular::row_type r = rs; r <= re; ++r)
for (Tabular::col_type c = cs; c <= ce; ++c) {
idx_type const cc = tabular.cellIndex(r, c);
- lt = borderState(lt, tabular.topLine(cc));
- lb = borderState(lb, tabular.bottomLine(cc));
- ll = borderState(ll, tabular.leftLine(cc));
- lr = borderState(lr, tabular.rightLine(cc));
+ ltop = borderState(ltop, tabular.topLine(cc));
+ lbottom = borderState(lbottom, tabular.bottomLine(cc));
+ lleft = borderState(lleft, tabular.leftLine(cc));
+ lright = borderState(lright, tabular.rightLine(cc));
+ ltop_ltrim = borderState(ltop_ltrim, !tabular.topLineTrim(cc).first);
+ ltop_rtrim = borderState(ltop_rtrim, !tabular.topLineTrim(cc).second);
+ lbottom_ltrim = borderState(lbottom_ltrim, !tabular.bottomLineTrim(cc).first);
+ lbottom_rtrim = borderState(lbottom_rtrim, !tabular.bottomLineTrim(cc).second);
// store left/right borders for the case of formal/nonformal switch
- orig_leftborder_ = borderState(ll, tabular.leftLine(cc, true));
- orig_rightborder_ = borderState(lr, tabular.rightLine(cc, true));
+ orig_leftborder_ = borderState(lleft, tabular.leftLine(cc, true));
+ orig_rightborder_ = borderState(lright, tabular.rightLine(cc, true));
}
} else {
- lt = tabular.topLine(cell) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
- lb = tabular.bottomLine(cell) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
- ll = tabular.leftLine(cell) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
- lr = tabular.rightLine(cell) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
+ ltop = tabular.topLine(cell) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
+ lbottom = tabular.bottomLine(cell) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
+ lleft = tabular.leftLine(cell) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
+ lright = tabular.rightLine(cell) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
+ ltop_ltrim = tabular.topLineTrim(cell).first ? GuiSetBorder::LINE_UNSET : GuiSetBorder::LINE_SET;
+ ltop_rtrim = tabular.topLineTrim(cell).second ? GuiSetBorder::LINE_UNSET : GuiSetBorder::LINE_SET;
+ lbottom_ltrim = tabular.bottomLineTrim(cell).first ? GuiSetBorder::LINE_UNSET : GuiSetBorder::LINE_SET;
+ lbottom_rtrim = tabular.bottomLineTrim(cell).second ? GuiSetBorder::LINE_UNSET : GuiSetBorder::LINE_SET;
// store left/right borders for the case of formal/nonformal switch
orig_leftborder_ = tabular.leftLine(cell, true) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
orig_rightborder_ = tabular.rightLine(cell, true) ? GuiSetBorder::LINE_SET : GuiSetBorder::LINE_UNSET;
}
- borders->setTop(lt);
- borders->setBottom(lb);
- borders->setLeft(ll);
- borders->setRight(lr);
+ borders->setTop(ltop);
+ borders->setBottom(lbottom);
+ borders->setLeft(lleft);
+ borders->setRight(lright);
+ borders->setTopLeftTrim(ltop_ltrim);
+ borders->setTopRightTrim(ltop_rtrim);
+ borders->setBottomLeftTrim(lbottom_ltrim);
+ borders->setBottomRightTrim(lbottom_rtrim);
// repaint the setborder widget
borders->update();
GuiSetBorder::BorderState orig_leftborder_;
///
GuiSetBorder::BorderState orig_rightborder_;
+ ///
+ int lastrow_;
};
} // namespace frontend
{ Tabular::MOVE_ROW_UP, "move-row-up", false },
{ Tabular::SET_LINE_TOP, "set-line-top", true },
{ Tabular::SET_LINE_BOTTOM, "set-line-bottom", true },
+ { Tabular::SET_LTRIM_TOP, "set-ltrim-top", true },
+ { Tabular::SET_LTRIM_BOTTOM, "set-ltrim-bottom", true },
+ { Tabular::SET_RTRIM_TOP, "set-rtrim-top", true },
+ { Tabular::SET_RTRIM_BOTTOM, "set-rtrim-bottom", true },
{ Tabular::SET_LINE_LEFT, "set-line-left", true },
{ Tabular::SET_LINE_RIGHT, "set-line-right", true },
{ Tabular::TOGGLE_LINE_TOP, "toggle-line-top", false },
{ Tabular::TOGGLE_LINE_BOTTOM, "toggle-line-bottom", false },
{ Tabular::TOGGLE_LINE_LEFT, "toggle-line-left", false },
{ Tabular::TOGGLE_LINE_RIGHT, "toggle-line-right", false },
+ { Tabular::TOGGLE_LTRIM_TOP, "toggle-ltrim-top", true },
+ { Tabular::TOGGLE_LTRIM_BOTTOM, "toggle-ltrim-bottom", true },
+ { Tabular::TOGGLE_RTRIM_TOP, "toggle-rtrim-top", true },
+ { Tabular::TOGGLE_RTRIM_BOTTOM, "toggle-rtrim-bottom", true },
{ Tabular::ALIGN_LEFT, "align-left", false },
{ Tabular::ALIGN_RIGHT, "align-right", false },
{ Tabular::ALIGN_CENTER, "align-center", false },
bottom_line(false),
left_line(false),
right_line(false),
+ top_line_rtrimmed(false),
+ top_line_ltrimmed(false),
+ bottom_line_rtrimmed(false),
+ bottom_line_ltrimmed(false),
usebox(BOX_NONE),
rotate(0),
inset(new InsetTableCell(buf))
bottom_line(cs.bottom_line),
left_line(cs.left_line),
right_line(cs.right_line),
+ top_line_rtrimmed(cs.top_line_rtrimmed),
+ top_line_ltrimmed(cs.top_line_ltrimmed),
+ bottom_line_rtrimmed(cs.bottom_line_rtrimmed),
+ bottom_line_ltrimmed(cs.bottom_line_ltrimmed),
usebox(cs.usebox),
rotate(cs.rotate),
align_special(cs.align_special),
bottom_line = cs.bottom_line;
left_line = cs.left_line;
right_line = cs.right_line;
+ top_line_rtrimmed = cs.top_line_rtrimmed;
+ top_line_ltrimmed = cs.top_line_ltrimmed;
+ bottom_line_rtrimmed = cs.bottom_line_rtrimmed;
+ bottom_line_rtrimmed = cs.bottom_line_rtrimmed;
usebox = cs.usebox;
rotate = cs.rotate;
align_special = cs.align_special;
}
+pair<bool, bool> Tabular::topLineTrim(idx_type const cell) const
+{
+ if (!use_booktabs)
+ return make_pair(false, false);
+ return make_pair(cellInfo(cell).top_line_ltrimmed,
+ cellInfo(cell).top_line_rtrimmed);
+}
+
+
+pair<bool, bool> Tabular::bottomLineTrim(idx_type const cell) const
+{
+ if (!use_booktabs)
+ return make_pair(false, false);
+ return make_pair(cellInfo(cell).bottom_line_ltrimmed,
+ cellInfo(cell).bottom_line_rtrimmed);
+}
+
+
int Tabular::interRowSpace(row_type row) const
{
if (!row || row >= nrows())
}
+void Tabular::setTopLineLTrim(idx_type i, bool val)
+{
+ cellInfo(i).top_line_ltrimmed = val;
+}
+
+
+void Tabular::setTopLineRTrim(idx_type i, bool val)
+{
+ cellInfo(i).top_line_rtrimmed = val;
+}
+
+
+void Tabular::setBottomLineLTrim(idx_type i, bool val)
+{
+ cellInfo(i).bottom_line_ltrimmed = val;
+}
+
+
+void Tabular::setBottomLineRTrim(idx_type i, bool val)
+{
+ cellInfo(i).bottom_line_rtrimmed = val;
+}
+
+
+void Tabular::setTopLineTrim(idx_type i, pair<bool, bool> trim)
+{
+ setTopLineLTrim(i, trim.first);
+ setTopLineRTrim(i, trim.second);
+}
+
+void Tabular::setBottomLineTrim(idx_type i, pair<bool, bool> trim)
+{
+ setBottomLineLTrim(i, trim.first);
+ setBottomLineRTrim(i, trim.second);
+}
+
void Tabular::setLeftLine(idx_type cell, bool line)
{
cellInfo(cell).left_line = line;
<< write_attribute("alignment", cell_info[r][c].alignment)
<< write_attribute("valignment", cell_info[r][c].valignment)
<< write_attribute("topline", cell_info[r][c].top_line)
+ << write_attribute("toplineltrim", cell_info[r][c].top_line_ltrimmed)
+ << write_attribute("toplinertrim", cell_info[r][c].top_line_rtrimmed)
<< write_attribute("bottomline", cell_info[r][c].bottom_line)
+ << write_attribute("bottomlineltrim", cell_info[r][c].bottom_line_ltrimmed)
+ << write_attribute("bottomlinertrim", cell_info[r][c].bottom_line_rtrimmed)
<< write_attribute("leftline", cell_info[r][c].left_line)
<< write_attribute("rightline", cell_info[r][c].right_line)
<< write_attribute("rotate", cell_info[r][c].rotate)
getTokenValue(line, "alignment", cell_info[i][j].alignment);
getTokenValue(line, "valignment", cell_info[i][j].valignment);
getTokenValue(line, "topline", cell_info[i][j].top_line);
+ getTokenValue(line, "toplineltrim", cell_info[i][j].top_line_ltrimmed);
+ getTokenValue(line, "toplinertrim", cell_info[i][j].top_line_rtrimmed);
getTokenValue(line, "bottomline", cell_info[i][j].bottom_line);
+ getTokenValue(line, "bottomlineltrim", cell_info[i][j].bottom_line_ltrimmed);
+ getTokenValue(line, "bottomlinertrim", cell_info[i][j].bottom_line_rtrimmed);
getTokenValue(line, "leftline", cell_info[i][j].left_line);
getTokenValue(line, "rightline", cell_info[i][j].right_line);
getTokenValue(line, "rotate", cell_info[i][j].rotate);
// is done in Tabular::TeXBottomHLine(...)
// get for each column the topline (if any)
- map<col_type, bool> topline;
+ map<col_type, bool> topline, topltrims, toprtrims;
col_type nset = 0;
+ bool have_trims = false;
for (auto const & c : columns) {
topline[c] = topLine(cellIndex(row, c));
+ topltrims[c] = topLineTrim(cellIndex(row, c)).first;
+ toprtrims[c] = topLineTrim(cellIndex(row, c)).second;
// If cell is part of a multirow and not the first cell of the
// multirow, no line must be drawn.
if (row != 0)
if (isMultiRow(cellIndex(row, c))
- && cell_info[row][c].multirow != CELL_BEGIN_OF_MULTIROW)
+ && cell_info[row][c].multirow != CELL_BEGIN_OF_MULTIROW) {
topline[c] = false;
+ topltrims[c] = false;
+ toprtrims[c] = false;
+ }
if (topline.find(c) != topline.end() && topline.find(c)->second)
++nset;
+ if ((topltrims.find(c) != topltrims.end() && topltrims.find(c)->second)
+ || (toprtrims.find(c) != toprtrims.end() && toprtrims.find(c)->second))
+ have_trims = true;
}
// do nothing if empty first row, or incomplete row line after
return;
// only output complete row lines and the 1st row's clines
- if (nset == ncols()) {
+ if (nset == ncols() && !have_trims) {
if (use_booktabs) {
os << (row == 0 ? "\\toprule " : "\\midrule ");
} else {
os << "\\hline ";
}
- } else if (row == 0) {
+ } else if (row == 0 || have_trims) {
+ string const cline = use_booktabs ? "\\cmidrule" : "\\cline";
for (auto & c : columns) {
if (topline.find(c)->second) {
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 << '-';
-
+ string trim;
+ if (topltrims.find(c) != topltrims.end()
+ && topltrims.find(c)->second)
+ trim = "l";
+ string const firstcol = convert<string>(c + 1 + offset);
col_type cstart = c;
- for ( ; c < ncols() && topline.find(c)->second; ++c) {}
+ for ( ; c < ncols() - 1 && topline.find(c)->second ; ++c) {
+ if (c > cstart && topltrims.find(c) != topltrims.end()
+ && topltrims.find(c)->second) {
+ --c;
+ break;
+ } else if (toprtrims.find(c) != toprtrims.end()
+ && toprtrims.find(c)->second)
+ break;
+ }
for (col_type j = cstart ; j < c ; ++j)
if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
++offset;
+ col_type const lastcol = c + 1 + offset;
+ if (toprtrims.find(c) != toprtrims.end()
+ && toprtrims.find(c)->second)
+ trim += "r";
- os << c + 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" << cline;
+ if (!trim.empty())
+ os << "(" << trim << ")";
+ os << "\\expandafter{\\expandafter" << firstcol << "\\string-";
+ } else {
+ os << cline;
+ if (!trim.empty())
+ os << "(" << trim << ")";
+ os << "{" << firstcol << '-';
+ }
+ os << lastcol << "}";
+ if (c == ncols() - 1)
+ break;
}
}
}
// get the bottomlines of row r, and toplines in next row
bool lastrow = row == nrows() - 1;
- map<col_type, bool> bottomline, topline;
+ map<col_type, bool> bottomline, topline, topltrims, toprtrims, bottomltrims, bottomrtrims;
bool nextrowset = true;
for (auto const & c : columns) {
+ idx_type const idx = cellIndex(row, c);
bottomline[c] = bottomLine(cellIndex(row, c));
+ bottomltrims[c] = bottomLineTrim(idx).first;
+ bottomrtrims[c] = bottomLineTrim(idx).second;
topline[c] = !lastrow && topLine(cellIndex(row + 1, c));
+ topltrims[c] = !lastrow && topLineTrim(cellIndex(row + 1, c)).first;
+ toprtrims[c] = !lastrow && topLineTrim(cellIndex(row + 1, c)).second;
// If cell is part of a multirow and not the last cell of the
// multirow, no line must be drawn.
if (!lastrow)
&& cell_info[row + 1][c].multirow != CELL_BEGIN_OF_MULTIROW) {
bottomline[c] = false;
topline[c] = false;
- }
+ bottomltrims[c] = false;
+ bottomrtrims[c] = false;
+ topltrims[c] = false;
+ toprtrims[c] = false;
+ }
nextrowset &= topline.find(c) != topline.end() && topline.find(c)->second;
}
// combine this row's bottom lines and next row's toplines if necessary
col_type nset = 0;
+ bool have_trims = false;
for (auto const & c : columns) {
if (!nextrowset)
bottomline[c] = bottomline.find(c)->second || topline.find(c)->second;
+ bottomltrims[c] = (bottomltrims.find(c) != bottomltrims.end() && bottomltrims.find(c)->second)
+ || (topltrims.find(c) != topltrims.end() && topltrims.find(c)->second);
+ bottomrtrims[c] =(bottomrtrims.find(c) != bottomrtrims.end() && bottomrtrims.find(c)->second)
+ || (toprtrims.find(c) != toprtrims.end() && toprtrims.find(c)->second);
if (bottomline.find(c)->second)
++nset;
+ if ((bottomltrims.find(c) != bottomltrims.end() && bottomltrims.find(c)->second)
+ || (bottomrtrims.find(c) != bottomrtrims.end() && bottomrtrims.find(c)->second))
+ have_trims = true;
}
// do nothing if empty, OR incomplete row line with a topline in next row
if (nset == 0 || (nextrowset && nset != ncols()))
return;
- if (nset == ncols()) {
+ if (nset == ncols() && !have_trims) {
if (use_booktabs)
os << (lastrow ? "\\bottomrule" : "\\midrule");
else
os << "\\hline ";
} else {
+ string const cline = use_booktabs ? "\\cmidrule" : "\\cline";
for (auto & c : columns) {
if (bottomline.find(c)->second) {
col_type offset = 0;
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 << '-';
-
+ string trim;
+ if (bottomltrims.find(c) != bottomltrims.end()
+ && bottomltrims.find(c)->second)
+ trim = "l";
+ string const firstcol = convert<string>(c + 1 + offset);
col_type cstart = c;
- for ( ; c < ncols() && bottomline.find(c)->second; ++c) {}
+ for ( ; c < ncols() - 1 && bottomline.find(c)->second ; ++c) {
+ if (c > cstart && bottomltrims.find(c) != bottomltrims.end()
+ && bottomltrims.find(c)->second) {
+ --c;
+ break;
+ } else if (bottomrtrims.find(c) != bottomrtrims.end()
+ && bottomrtrims.find(c)->second)
+ break;
+ }
for (col_type j = cstart ; j < c ; ++j)
if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
++offset;
+ col_type const lastcol = c + 1 + offset;
+ if (bottomrtrims.find(c) != bottomrtrims.end()
+ && bottomrtrims.find(c)->second)
+ trim += "r";
- os << c + 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" << cline;
+ if (!trim.empty())
+ os << "(" << trim << ")";
+ os << "\\expandafter{\\expandafter" << firstcol << "\\string-";
+ } else {
+ os << cline;
+ if (!trim.empty())
+ os << "(" << trim << ")";
+ os << "{" << firstcol << '-';
+ }
+ os << lastcol << "}";
+ if (c == ncols() - 1)
+ break;
}
}
}
namespace {
-void tabline(PainterInfo const & pi, int x1, int y1, int x2, int y2,
+void tabline(PainterInfo const & pi, int x1, int y1, int x2, int y2, int lt, int rt,
bool drawline, bool heavy = false)
{
ColorCode const col = drawline ? Color_tabularline : Color_tabularonoffline;
- pi.pain.line(x1, y1, x2, y2, pi.textColor(col),
+ if (drawline && lt > 0)
+ pi.pain.line(x1, y1, x1 + lt, y2, pi.textColor(Color_tabularonoffline),
+ Painter::line_onoffdash,
+ Painter::thin_line);
+ pi.pain.line(x1 + lt, y1, x2 - rt, y2, pi.textColor(col),
drawline ? Painter::line_solid : Painter::line_onoffdash,
(heavy ? 2 : 1) * Painter::thin_line);
+ if (drawline && rt > 0)
+ pi.pain.line(x2 - rt, y1, x2, y2, pi.textColor(Color_tabularonoffline),
+ Painter::line_onoffdash,
+ Painter::thin_line);
}
}
y -= tabular.rowAscent(row);
int const w = tabular.cellWidth(cell);
int const h = tabular.cellHeight(cell);
+ int lt = 0;
+ int rt = 0;
col_type const col = tabular.cellColumn(cell);
bool drawline = tabular.topLine(cell)
|| (row > 0 && tabular.bottomLine(tabular.cellAbove(cell)));
bool heavy = tabular.use_booktabs && row == 0 && tabular.rowTopLine(row);
- tabline(pi, x, y, x + w, y, drawline, heavy);
+ if (tabular.topLineTrim(cell).first
+ || (row > 0 && tabular.bottomLineTrim(tabular.cellIndex(row - 1, col)).first))
+ lt = 10;
+ if (tabular.topLineTrim(cell).second
+ || (row > 0 && tabular.bottomLineTrim(tabular.cellIndex(row - 1, col)).second))
+ rt = 10;
+ tabline(pi, x, y, x + w, y, lt, rt, drawline, heavy);
// Bottom
+ lt = rt = 0;
drawline = tabular.bottomLine(cell);
row_type const lastrow = tabular.nrows() - 1;
// Consider multi-rows
heavy = tabular.use_booktabs
&& ((row == lastrow && tabular.rowBottomLine(row))
|| (r == lastrow && tabular.rowBottomLine(r)));
- tabline(pi, x, y + h, x + w, y + h, drawline, heavy);
+ if (tabular.bottomLineTrim(cell).first)
+ lt = 10;
+ if (tabular.bottomLineTrim(cell).second)
+ rt = 10;
+ tabline(pi, x, y + h, x + w, y + h, lt, rt, drawline, heavy);
// Left
drawline = tabular.leftLine(cell)
|| (col > 0 && tabular.rightLine(tabular.cellIndex(row, col - 1)));
- tabline(pi, x, y, x, y + h, drawline);
+ tabline(pi, x, y, x, y + h, 0, 0, drawline);
// Right
x -= tabular.interColumnSpace(cell);
drawline = tabular.rightLine(cell)
|| (next_cell_col < tabular.ncols()
&& tabular.leftLine(tabular.cellIndex(row, next_cell_col)));
- tabline(pi, x + w, y, x + w, y + h, drawline);
+ tabline(pi, x + w, y, x + w, y + h, 0, 0, drawline);
}
&& !tabular.ltCaption(tabular.cellRow(cur.idx())));
break;
+ case Tabular::SET_LTRIM_TOP:
+ case Tabular::SET_RTRIM_TOP:
+ status.setEnabled(tabular.use_booktabs
+ && tabular.cellRow(cur.idx()) != 0
+ && !tabular.ltCaption(tabular.cellRow(cur.idx())));
+ break;
+
+ case Tabular::SET_LTRIM_BOTTOM:
+ case Tabular::SET_RTRIM_BOTTOM:
+ status.setEnabled(tabular.use_booktabs
+ && tabular.cellRow(cur.idx()) != tabular.nrows() - 1
+ && !tabular.ltCaption(tabular.cellRow(cur.idx())));
+ break;
+
case Tabular::TOGGLE_LINE_TOP:
status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
status.setOnOff(tabular.topLine(cur.idx()));
status.setOnOff(tabular.rightLine(cur.idx()));
break;
+ case Tabular::TOGGLE_LTRIM_TOP:
+ status.setEnabled(tabular.use_booktabs
+ && !tabular.ltCaption(tabular.cellRow(cur.idx())));
+ status.setOnOff(tabular.topLineTrim(cur.idx()).first);
+ break;
+
+ case Tabular::TOGGLE_RTRIM_TOP:
+ status.setEnabled(tabular.use_booktabs
+ && !tabular.ltCaption(tabular.cellRow(cur.idx())));
+ status.setOnOff(tabular.topLineTrim(cur.idx()).second);
+ break;
+
+ case Tabular::TOGGLE_LTRIM_BOTTOM:
+ status.setEnabled(tabular.use_booktabs
+ && !tabular.ltCaption(tabular.cellRow(cur.idx())));
+ status.setOnOff(tabular.bottomLineTrim(cur.idx()).first);
+ break;
+
+ case Tabular::TOGGLE_RTRIM_BOTTOM:
+ status.setEnabled(tabular.use_booktabs
+ && !tabular.ltCaption(tabular.cellRow(cur.idx())));
+ status.setOnOff(tabular.bottomLineTrim(cur.idx()).second);
+ break;
+
// multirow cells only inherit the alignment of the column if the column has
// no width, otherwise they are left-aligned
// therefore allow always left but right and center only if there is no width
case Tabular::DELETE_ROW:
if (sel_row_end == tabular.nrows() - 1 && sel_row_start != 0) {
- for (col_type c = 0; c < tabular.ncols(); c++)
+ for (col_type c = 0; c < tabular.ncols(); c++) {
tabular.setBottomLine(tabular.cellIndex(sel_row_start - 1, c),
tabular.bottomLine(tabular.cellIndex(sel_row_end, c)));
+ tabular.setBottomLineTrim(tabular.cellIndex(sel_row_start - 1, c),
+ tabular.bottomLineTrim(tabular.cellIndex(sel_row_end, c)));
+ }
}
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
break;
}
+ case Tabular::SET_LTRIM_TOP:
+ case Tabular::TOGGLE_LTRIM_TOP: {
+ bool l = (feature == Tabular::SET_LTRIM_TOP)
+ ? (value == "true") : !tabular.topLineTrim(cur.idx()).first;
+ 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.setTopLineLTrim(tabular.cellIndex(r, c), l);
+ break;
+ }
+
+ case Tabular::SET_RTRIM_TOP:
+ case Tabular::TOGGLE_RTRIM_TOP: {
+ bool l = (feature == Tabular::SET_RTRIM_TOP)
+ ? (value == "true") : !tabular.topLineTrim(cur.idx()).second;
+ 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.setTopLineRTrim(tabular.cellIndex(r, c), l);
+ break;
+ }
+
+ case Tabular::SET_LTRIM_BOTTOM:
+ case Tabular::TOGGLE_LTRIM_BOTTOM: {
+ bool l = (feature == Tabular::SET_LTRIM_BOTTOM)
+ ? (value == "true") : !tabular.bottomLineTrim(cur.idx()).first;
+ 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.setBottomLineLTrim(tabular.cellIndex(r, c), l);
+ break;
+ }
+
+ case Tabular::SET_RTRIM_BOTTOM:
+ case Tabular::TOGGLE_RTRIM_BOTTOM: {
+ bool l = (feature == Tabular::SET_RTRIM_BOTTOM)
+ ? (value == "true") : !tabular.bottomLineTrim(cur.idx()).second;
+ 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.setBottomLineRTrim(tabular.cellIndex(r, c), l);
+ break;
+ }
+
case Tabular::SET_LINE_LEFT:
case Tabular::TOGGLE_LINE_LEFT: {
bool lineSet = (feature == Tabular::SET_LINE_LEFT)
///FIXME: remove
TOGGLE_LINE_RIGHT,
///
+ SET_LTRIM_TOP,
+ ///
+ SET_RTRIM_TOP,
+ ///
+ SET_LTRIM_BOTTOM,
+ ///
+ SET_RTRIM_BOTTOM,
+ ///
+ TOGGLE_LTRIM_TOP,
+ ///
+ TOGGLE_RTRIM_TOP,
+ ///
+ TOGGLE_LTRIM_BOTTOM,
+ ///
+ TOGGLE_RTRIM_BOTTOM,
+ ///
ALIGN_LEFT,
///
ALIGN_RIGHT,
/// 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 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
+ std::pair<bool, bool> bottomLineTrim(idx_type const cell) const;
/// return space occupied by the second horizontal line and
/// interline space above row \p row in pixels
///
void setBottomLine(idx_type cell, bool line);
///
+ void setTopLineLTrim(idx_type cell, bool val);
+ ///
+ void setBottomLineLTrim(idx_type cell, bool val);
+ ///
+ void setTopLineRTrim(idx_type cell, bool val);
+ ///
+ void setBottomLineRTrim(idx_type cell, bool val);
+ ///
+ void setTopLineTrim(idx_type cell, std::pair<bool, bool>);
+ ///
+ void setBottomLineTrim(idx_type cell, std::pair<bool, bool>);
+ ///
void setLeftLine(idx_type cell, bool line);
///
void setRightLine(idx_type cell, bool line);
///
bool right_line;
///
+ bool top_line_rtrimmed;
+ ///
+ bool top_line_ltrimmed;
+ ///
+ bool bottom_line_rtrimmed;
+ ///
+ bool bottom_line_ltrimmed;
+ ///
BoxType usebox;
///
int rotate;
443 unicode-math.sty InsetMath*
453 automatic stmaryrd loading \use_package stmaryrd
457 automatic stackrel loading \use_package stackrel
+571 cmirule trimming (booktabs)
+ \cmidrule(lr){n-n} <cell ... toplineltrim|toplinettrim|bottomlineltrim|bottomlinertrim true ...>
// Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own.
-#define LYX_FORMAT_LYX 570 // spitz: biblatex bibencodings
-#define LYX_FORMAT_TEX2LYX 570
+#define LYX_FORMAT_LYX 571 // spitz: cmidrule trimming
+#define LYX_FORMAT_TEX2LYX 571
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
#ifndef _MSC_VER