* \author Jürgen Vigna
* \author Uwe Stöhr
* \author Edwin Leuven
+ * \author Scott Kostyshak
*
* Full author contact details are available in file CREDITS.
*/
#include "DispatchResult.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
+#include "InsetList.h"
#include "Language.h"
#include "LaTeXFeatures.h"
#include "Lexer.h"
{ Tabular::DELETE_COLUMN, "delete-column", false },
{ Tabular::COPY_ROW, "copy-row", false },
{ Tabular::COPY_COLUMN, "copy-column", false },
+ { Tabular::MOVE_COLUMN_RIGHT, "move-column-right", false },
+ { Tabular::MOVE_COLUMN_LEFT, "move-column-left", false },
+ { Tabular::MOVE_ROW_DOWN, "move-row-down", false },
+ { 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_LINE_LEFT, "set-line-left", true },
{ Tabular::UNSET_LONGTABULAR, "unset-longtabular", false },
{ Tabular::SET_PWIDTH, "set-pwidth", true },
{ Tabular::SET_MPWIDTH, "set-mpwidth", true },
- { Tabular::SET_ROTATE_TABULAR, "set-rotate-tabular", false },
- { Tabular::UNSET_ROTATE_TABULAR, "unset-rotate-tabular", false },
- { Tabular::TOGGLE_ROTATE_TABULAR, "toggle-rotate-tabular", false },
- { Tabular::SET_ROTATE_CELL, "set-rotate-cell", false },
- { Tabular::UNSET_ROTATE_CELL, "unset-rotate-cell", false },
- { Tabular::TOGGLE_ROTATE_CELL, "toggle-rotate-cell", false },
+ { Tabular::SET_ROTATE_TABULAR, "set-rotate-tabular", true },
+ { Tabular::UNSET_ROTATE_TABULAR, "unset-rotate-tabular", true },
+ { Tabular::TOGGLE_ROTATE_TABULAR, "toggle-rotate-tabular", true },
+ { Tabular::SET_ROTATE_CELL, "set-rotate-cell", true },
+ { Tabular::UNSET_ROTATE_CELL, "unset-rotate-cell", true },
+ { Tabular::TOGGLE_ROTATE_CELL, "toggle-rotate-cell", true },
{ Tabular::SET_USEBOX, "set-usebox", true },
{ Tabular::SET_LTHEAD, "set-lthead", true },
{ Tabular::UNSET_LTHEAD, "unset-lthead", true },
{ Tabular::SET_LTLASTFOOT, "set-ltlastfoot", true },
{ Tabular::UNSET_LTLASTFOOT, "unset-ltlastfoot", true },
{ Tabular::SET_LTNEWPAGE, "set-ltnewpage", false },
+ { Tabular::UNSET_LTNEWPAGE, "unset-ltnewpage", false },
{ Tabular::TOGGLE_LTCAPTION, "toggle-ltcaption", false },
{ Tabular::SET_LTCAPTION, "set-ltcaption", false },
{ Tabular::UNSET_LTCAPTION, "unset-ltcaption", false },
left_line(false),
right_line(false),
usebox(BOX_NONE),
- rotate(false),
+ rotate(0),
inset(new InsetTableCell(buf))
{
inset->setBuffer(*buf);
tabular_valignment = LYX_VALIGN_MIDDLE;
tabular_width = Length();
longtabular_alignment = LYX_LONGTABULAR_ALIGN_CENTER;
- rotate = false;
+ rotate = 0;
use_booktabs = false;
// set silly default lines
for (row_type r = 0; r < nrows(); ++r)
}
+void Tabular::moveColumn(col_type col, ColDirection direction)
+{
+ if (direction == Tabular::LEFT)
+ col = col - 1;
+
+ for (row_type r = 0; r < nrows(); ++r) {
+ std::swap(cell_info[r][col], cell_info[r][col + 1]);
+ std::swap(cell_info[r][col].left_line, cell_info[r][col + 1].left_line);
+ std::swap(cell_info[r][col].right_line, cell_info[r][col + 1].right_line);
+
+ // FIXME track changes is broken for tabular features (#8469)
+ idx_type const i = cellIndex(r, col);
+ idx_type const j = cellIndex(r, col + 1);
+ if (buffer().params().trackChanges) {
+ cellInfo(i).inset->setChange(Change(Change::INSERTED));
+ cellInfo(j).inset->setChange(Change(Change::INSERTED));
+ }
+ }
+ updateIndexes();
+}
+
+
+void Tabular::moveRow(row_type row, RowDirection direction)
+{
+ if (direction == Tabular::UP)
+ row = row - 1;
+
+ for (col_type c = 0; c < ncols(); ++c) {
+ std::swap(cell_info[row][c], cell_info[row + 1][c]);
+ std::swap(cell_info[row][c].top_line, cell_info[row + 1][c].top_line);
+ std::swap(cell_info[row][c].bottom_line, cell_info[row + 1][c].bottom_line);
+
+ // FIXME track changes is broken for tabular features (#8469)
+ idx_type const i = cellIndex(row, c);
+ idx_type const j = cellIndex(row + 1, c);
+ if (buffer().params().trackChanges) {
+ cellInfo(i).inset->setChange(Change(Change::INSERTED));
+ cellInfo(j).inset->setChange(Change(Change::INSERTED));
+ }
+ }
+ updateIndexes();
+}
+
+
void Tabular::deleteColumn(col_type const col)
{
// Not allowed to delete last column
<< ">\n";
// global longtable options
os << "<features"
- << write_attribute("rotate", rotate)
+ << write_attribute("rotate", convert<string>(rotate))
<< write_attribute("booktabs", use_booktabs)
<< write_attribute("islongtable", is_long_tabular)
<< write_attribute("firstHeadTopDL", endfirsthead.topDL)
}
+bool Tabular::hasMultiColumn(col_type c) const
+{
+ for (row_type r = 0; r < nrows(); ++r) {
+ if (isMultiColumn(cellIndex(r, c)))
+ return true;
+ }
+ return false;
+}
+
+
Tabular::CellData & Tabular::cellInfo(idx_type cell) const
{
return cell_info[cellRow(cell)][cellColumn(cell)];
|| cellInfo(cell).multirow == CELL_PART_OF_MULTIROW);
}
+bool Tabular::hasMultiRow(row_type r) const
+{
+ for (col_type c = 0; c < ncols(); ++c) {
+ if (isMultiRow(cellIndex(r, c)))
+ return true;
+ }
+ return false;
+}
Tabular::idx_type Tabular::setMultiRow(idx_type cell, idx_type number,
bool const bottom_border)
}
-void Tabular::setRotateCell(idx_type cell, bool flag)
+void Tabular::setRotateCell(idx_type cell, int value)
{
- cellInfo(cell).rotate = flag;
+ cellInfo(cell).rotate = value;
}
-bool Tabular::getRotateCell(idx_type cell) const
+int Tabular::getRotateCell(idx_type cell) const
{
return cellInfo(cell).rotate;
}
return true;
for (row_type r = 0; r < nrows(); ++r)
for (col_type c = 0; c < ncols(); ++c)
- if (cell_info[r][c].rotate)
+ if (cell_info[r][c].rotate != 0)
return true;
return false;
}
os << "{";
} // end if ismultirow
- if (getRotateCell(cell)) {
- os << "\\begin{sideways}\n";
- }
+ if (getRotateCell(cell) != 0)
+ os << "\\begin{turn}{" << convert<string>(getRotateCell(cell)) << "}\n";
+
if (getUsebox(cell) == BOX_PARBOX) {
os << "\\parbox[";
switch (valign) {
os << '}';
else if (getUsebox(cell) == BOX_MINIPAGE)
os << breakln << "\\end{minipage}";
- if (getRotateCell(cell))
- os << breakln << "\\end{sideways}";
+ if (getRotateCell(cell) != 0)
+ os << breakln << "\\end{turn}";
if (ismultirow)
os << '}';
if (ismulticol)
Paragraph const & par = inset->paragraphs().front();
bool rtl = par.isRTL(buffer().params())
&& !par.empty()
- && getPWidth(cell).zero();
+ && getPWidth(cell).zero()
+ && !runparams.use_polyglossia;
if (rtl) {
string const lang =
if (runparams.lastid != -1)
os.texrow().start(runparams.lastid, runparams.lastpos);
- if (rotate)
- os << "\\begin{sideways}\n";
+ if (rotate != 0)
+ os << "\\begin{turn}{" << convert<string>(rotate) << "}\n";
if (is_long_tabular) {
os << "\\begin{longtable}";
os << "\\end{tabular}";
}
- if (rotate)
- os << breakln << "\\end{sideways}";
+ if (rotate != 0)
+ os << breakln << "\\end{turn}";
}
if (select_whole && !empty_cell){
getText(cur.idx())->selectAll(cur);
cur.dispatched();
+ cur.screenUpdateFlags(Update::Force | Update::FitCursor);
break;
}
cur.pit() = cur.lastpit();
cur.pos() = cur.lastpos();
cur.setCurrentFont();
+ cur.screenUpdateFlags(Update::Force | Update::FitCursor);
return;
}
- cur.screenUpdateFlags(Update::FitCursor);
+ cur.screenUpdateFlags(Update::Force | Update::FitCursor);
break;
case LFUN_UP_SELECT:
cur.pit() = 0;
cur.pos() = cur.lastpos();
cur.setCurrentFont();
+ cur.screenUpdateFlags(Update::Force | Update::FitCursor);
return;
}
- cur.screenUpdateFlags(Update::FitCursor);
+ cur.screenUpdateFlags(Update::Force | Update::FitCursor);
break;
// case LFUN_SCREEN_DOWN: {
&& tabular.tabular_valignment == Tabular::LYX_VALIGN_MIDDLE);
break;
+ case Tabular::MOVE_COLUMN_RIGHT:
+ case Tabular::MOVE_COLUMN_LEFT:
+ case Tabular::MOVE_ROW_DOWN:
+ case Tabular::MOVE_ROW_UP: {
+ if (cur.selection()) {
+ status.message(_("Selections not supported."));
+ status.setEnabled(false);
+ break;
+ }
+
+ if ((action == Tabular::MOVE_COLUMN_RIGHT &&
+ tabular.ncols() == tabular.cellColumn(cur.idx()) + 1) ||
+ (action == Tabular::MOVE_COLUMN_LEFT &&
+ tabular.cellColumn(cur.idx()) == 0) ||
+ (action == Tabular::MOVE_ROW_DOWN &&
+ tabular.nrows() == tabular.cellRow(cur.idx()) + 1) ||
+ (action == Tabular::MOVE_ROW_UP &&
+ tabular.cellRow(cur.idx()) == 0)) {
+ status.setEnabled(false);
+ break;
+ }
+
+ if (action == Tabular::MOVE_COLUMN_RIGHT ||
+ action == Tabular::MOVE_COLUMN_LEFT) {
+ if (tabular.hasMultiColumn(tabular.cellColumn(cur.idx())) ||
+ tabular.hasMultiColumn(tabular.cellColumn(cur.idx()) +
+ (action == Tabular::MOVE_COLUMN_RIGHT ? 1 : -1))) {
+ status.message(_("Multi-column in current or"
+ " destination column."));
+ status.setEnabled(false);
+ break;
+ }
+ }
+
+ if (action == Tabular::MOVE_ROW_DOWN ||
+ action == Tabular::MOVE_ROW_UP) {
+ if (tabular.hasMultiRow(tabular.cellRow(cur.idx())) ||
+ tabular.hasMultiRow(tabular.cellRow(cur.idx()) +
+ (action == Tabular::MOVE_ROW_DOWN ? 1 : -1))) {
+ status.message(_("Multi-row in current or"
+ " destination row."));
+ status.setEnabled(false);
+ break;
+ }
+ }
+
+ status.setEnabled(true);
+ break;
+ }
+
case Tabular::SET_DECIMAL_POINT:
status.setEnabled(
tabular.getAlignment(cur.idx()) == LYX_ALIGN_DECIMAL);
case Tabular::TOGGLE_ROTATE_TABULAR:
case Tabular::SET_ROTATE_TABULAR:
- status.setEnabled(tabular.tabular_width.zero());
- status.setOnOff(tabular.rotate);
+ status.setOnOff(tabular.rotate != 0);
break;
case Tabular::TABULAR_VALIGN_TOP:
break;
case Tabular::UNSET_ROTATE_TABULAR:
- status.setOnOff(!tabular.rotate);
+ status.setOnOff(tabular.rotate == 0);
break;
case Tabular::TOGGLE_ROTATE_CELL:
case Tabular::SET_LTNEWPAGE:
status.setOnOff(tabular.getLTNewPage(sel_row_start));
break;
+ case Tabular::UNSET_LTNEWPAGE:
+ status.setOnOff(!tabular.getLTNewPage(sel_row_start));
+ break;
// only one row in head/firsthead/foot/lasthead can be the caption
// and a multirow cannot be set as caption
return true;
}
+ case LFUN_CAPTION_INSERT: {
+ // caption is only allowed in caption cell of longtable
+ if (!tabular.ltCaption(tabular.cellRow(cur.idx()))) {
+ status.setEnabled(false);
+ return true;
+ }
+ // only standard caption is allowed
+ string arg = cmd.getArg(0);
+ if (!arg.empty() && arg != "Standard") {
+ status.setEnabled(false);
+ return true;
+ }
+ // check if there is already a caption
+ bool have_caption = false;
+ InsetTableCell itc = InsetTableCell(*tabular.cellInset(cur.idx()).get());
+ ParagraphList::const_iterator pit = itc.paragraphs().begin();
+ ParagraphList::const_iterator pend = itc.paragraphs().end();
+ for (; pit != pend; ++pit) {
+ InsetList::const_iterator it = pit->insetList().begin();
+ InsetList::const_iterator end = pit->insetList().end();
+ for (; it != end; ++it) {
+ if (it->inset->lyxCode() == CAPTION_CODE) {
+ have_caption = true;
+ break;
+ }
+ }
+ }
+ status.setEnabled(!have_caption);
+ return true;
+ }
+
// These are only enabled inside tabular
case LFUN_CELL_BACKWARD:
case LFUN_CELL_FORWARD:
}
// disable in non-fixed-width cells
- case LFUN_BREAK_PARAGRAPH:
+ case LFUN_PARAGRAPH_BREAK:
// multirow does not allow paragraph breaks
if (tabular.isMultiRow(cur.idx())) {
status.setEnabled(false);
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);
+ - tabular.interRowSpace(row) - tabular.textVOffset(cell);
int const yend = ybeg + tabular.cellHeight(cell);
if (x < xbeg)
for (; tabularFeature[i].action != Tabular::LAST_ACTION; ++i) {
if (s != tabularFeature[i].feature)
continue;
-
action = tabularFeature[i].action;
break;
}
{
for (row_type r = row_start; r <= row_end; ++r)
for (col_type c = col_start; c <= col_end; ++c)
- if (tabular.getRotateCell(tabular.cellIndex(r, c)) == rotated)
- return true;
-
+ if (rotated) {
+ if (tabular.getRotateCell(tabular.cellIndex(r, c)) != 0)
+ return true;
+ } else {
+ if (tabular.getRotateCell(tabular.cellIndex(r, c)) == 0)
+ return true;
+ }
return false;
}
+
void InsetTabular::tabularFeatures(Cursor & cur,
Tabular::Feature feature, string const & value)
{
break;
case Tabular::ALIGN_DECIMAL:
- setAlign = LYX_ALIGN_DECIMAL;
+ if (tabular.column_info[tabular.cellColumn(cur.idx())].alignment == LYX_ALIGN_DECIMAL)
+ setAlign = LYX_ALIGN_CENTER;
+ else
+ setAlign = LYX_ALIGN_DECIMAL;
break;
case Tabular::M_VALIGN_TOP:
break;
case Tabular::DELETE_ROW:
+ if (sel_row_end == tabular.nrows() - 1 && sel_row_start != 0) {
+ 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)));
+ }
+
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
tabular.deleteRow(sel_row_start);
if (sel_row_start >= tabular.nrows())
break;
case Tabular::DELETE_COLUMN:
+ if (sel_col_end == tabular.ncols() - 1 && sel_col_start != 0) {
+ for (row_type r = 0; r < tabular.nrows(); r++)
+ tabular.setRightLine(tabular.cellIndex(r, sel_col_start - 1),
+ tabular.rightLine(tabular.cellIndex(r, sel_col_end)));
+ }
+
+ if (sel_col_start == 0 && sel_col_end != tabular.ncols() - 1) {
+ for (row_type r = 0; r < tabular.nrows(); r++)
+ tabular.setLeftLine(tabular.cellIndex(r, sel_col_end + 1),
+ tabular.leftLine(tabular.cellIndex(r, 0)));
+ }
+
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
tabular.deleteColumn(sel_col_start);
if (sel_col_start >= tabular.ncols())
cur.idx() = tabular.cellIndex(row, column);
break;
+ case Tabular::MOVE_COLUMN_RIGHT:
+ tabular.moveColumn(column, Tabular::RIGHT);
+ cur.idx() = tabular.cellIndex(row, column + 1);
+ break;
+
+ case Tabular::MOVE_COLUMN_LEFT:
+ tabular.moveColumn(column, Tabular::LEFT);
+ cur.idx() = tabular.cellIndex(row, column - 1);
+ break;
+
+ case Tabular::MOVE_ROW_DOWN:
+ tabular.moveRow(row, Tabular::DOWN);
+ cur.idx() = tabular.cellIndex(row + 1, column);
+ break;
+
+ case Tabular::MOVE_ROW_UP:
+ tabular.moveRow(row, Tabular::UP);
+ cur.idx() = tabular.cellIndex(row - 1, column);
+ break;
+
case Tabular::SET_LINE_TOP:
case Tabular::TOGGLE_LINE_TOP: {
bool lineSet = (feature == Tabular::SET_LINE_TOP)
tabular.rightLine(cur.idx()));
break;
}
- // we have a selection so this means we just add all this
+ // we have a selection so this means we just add all these
// cells to form a multicolumn cell
idx_type const s_start = cur.selBegin().idx();
row_type const col_start = tabular.cellColumn(s_start);
break;
case Tabular::SET_ROTATE_TABULAR:
- tabular.rotate = true;
+ tabular.rotate = convert<int>(value);
break;
case Tabular::UNSET_ROTATE_TABULAR:
- tabular.rotate = false;
+ tabular.rotate = 0;
break;
case Tabular::TOGGLE_ROTATE_TABULAR:
- tabular.rotate = !tabular.rotate;
+ // when pressing the rotate button we default to 90° rotation
+ tabular.rotate != 0 ? tabular.rotate = 0 : tabular.rotate = 90;
break;
case Tabular::TABULAR_VALIGN_TOP:
case Tabular::SET_ROTATE_CELL:
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
- tabular.setRotateCell(tabular.cellIndex(r, c), true);
+ tabular.setRotateCell(tabular.cellIndex(r, c), convert<int>(value));
break;
case Tabular::UNSET_ROTATE_CELL:
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
- tabular.setRotateCell(tabular.cellIndex(r, c), false);
+ tabular.setRotateCell(tabular.cellIndex(r, c), 0);
break;
case Tabular::TOGGLE_ROTATE_CELL:
sel_row_start, sel_row_end, sel_col_start, sel_col_end);
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
- for (col_type c = sel_col_start; c <= sel_col_end; ++c)
- tabular.setRotateCell(tabular.cellIndex(r, c),
- oneNotRotated);
+ for (col_type c = sel_col_start; c <= sel_col_end; ++c) {
+ // when pressing the rotate cell button we default to 90° rotation
+ if (oneNotRotated)
+ tabular.setRotateCell(tabular.cellIndex(r, c), 90);
+ else
+ tabular.setRotateCell(tabular.cellIndex(r, c), 0);
+ }
}
break;
tabular.setLTFoot(row, flag, ltt, true);
break;
+ case Tabular::UNSET_LTNEWPAGE:
+ flag = false;
case Tabular::SET_LTNEWPAGE:
- tabular.setLTNewPage(row, !tabular.getLTNewPage(row));
+ tabular.setLTNewPage(row, flag);
break;
case Tabular::SET_LTCAPTION: {