#include "bufferparams.h"
#include "BufferView.h"
#include "cursor.h"
+#include "CutAndPaste.h"
#include "coordcache.h"
#include "debug.h"
#include "dispatchresult.h"
#include <iostream>
#include <limits>
+using lyx::cap::tabularStackDirty;
+
using lyx::graphics::PreviewLoader;
using lyx::support::ltrim;
InsetTabular::InsetTabular(Buffer const & buf, row_type rows,
col_type columns)
: tabular(buf.params(), max(rows, row_type(1)),
- max(columns, col_type(1))), buffer_(&buf), cursorx_(0)
+ max(columns, col_type(1))), buffer_(&buf), scx_(0)
{}
InsetTabular::InsetTabular(InsetTabular const & tab)
- : UpdatableInset(tab), tabular(tab.tabular),
- buffer_(tab.buffer_), cursorx_(0)
+ : InsetOld(tab), tabular(tab.tabular),
+ buffer_(tab.buffer_), scx_(0)
{}
int maxDesc = 0;
for (col_type j = 0; j < tabular.columns(); ++j) {
if (tabular.isPartOfMultiColumn(i, j))
+ // Multicolumn cell, but not first one
continue;
Dimension dim;
MetricsInfo m = mi;
- LyXLength p_width = tabular.column_info[j].p_width;
+ LyXLength p_width;
+ if (tabular.cell_info[i][j].multicolumn ==
+ LyXTabular::CELL_BEGIN_OF_MULTICOLUMN)
+ p_width = tabular.cellinfo_of_cell(cell).p_width;
+ else
+ p_width = tabular.column_info[j].p_width;
if (!p_width.zero())
m.base.textwidth = p_width.inPixels(mi.base.textwidth);
tabular.getCellInset(cell)->metrics(m, dim);
//resetPos(bv->cursor());
- x += scroll();
+ x += scx_;
x += ADD_TO_TABULAR_WIDTH;
idx_type idx = 0;
|| y + d < 0
|| y - a > bv->workHeight()) {
cell(idx)->draw(nullpi, cx, y);
- drawCellLines(nop, nx, y, i, idx);
+ drawCellLines(nop, nx, y, i, idx, pi.erased_);
} else {
cell(idx)->draw(pi, cx, y);
- drawCellLines(pi.pain, nx, y, i, idx);
+ drawCellLines(pi.pain, nx, y, i, idx, pi.erased_);
}
nx += tabular.getWidthOfColumn(idx);
++idx;
//resetPos(cur);
- x += scroll();
- x += ADD_TO_TABULAR_WIDTH;
+ x += scx_ + ADD_TO_TABULAR_WIDTH;
if (tablemode(cur)) {
row_type rs, re;
void InsetTabular::drawCellLines(Painter & pain, int x, int y,
- row_type row, idx_type cell) const
+ row_type row, idx_type cell, bool erased) const
{
int x2 = x + tabular.getWidthOfColumn(cell);
bool on_off = false;
+ LColor::color col = LColor::tabularline;
+ LColor::color onoffcol = LColor::tabularonoffline;
+
+ if (erased) {
+ col = LColor::strikeout;
+ onoffcol = LColor::strikeout;
+ }
if (!tabular.topAlreadyDrawn(cell)) {
on_off = !tabular.topLine(cell);
pain.line(x, y - tabular.getAscentOfRow(row),
x2, y - tabular.getAscentOfRow(row),
- on_off ? LColor::tabularonoffline : LColor::tabularline,
+ on_off ? onoffcol : col,
on_off ? Painter::line_onoffdash : Painter::line_solid);
}
on_off = !tabular.bottomLine(cell);
pain.line(x, y + tabular.getDescentOfRow(row),
x2, y + tabular.getDescentOfRow(row),
- on_off ? LColor::tabularonoffline : LColor::tabularline,
+ on_off ? onoffcol : col,
on_off ? Painter::line_onoffdash : Painter::line_solid);
if (!tabular.leftAlreadyDrawn(cell)) {
on_off = !tabular.leftLine(cell);
pain.line(x, y - tabular.getAscentOfRow(row),
x, y + tabular.getDescentOfRow(row),
- on_off ? LColor::tabularonoffline : LColor::tabularline,
+ on_off ? onoffcol : col,
on_off ? Painter::line_onoffdash : Painter::line_solid);
}
on_off = !tabular.rightLine(cell);
y - tabular.getAscentOfRow(row),
x2 - tabular.getAdditionalWidth(cell),
y + tabular.getDescentOfRow(row),
- on_off ? LColor::tabularonoffline : LColor::tabularline,
+ on_off ? onoffcol : col,
on_off ? Painter::line_onoffdash : Painter::line_solid);
}
void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
{
- //lyxerr << "# InsetTabular::dispatch: cmd: " << cmd << endl;
- //lyxerr << " cur:\n" << cur << endl;
+ lyxerr[Debug::DEBUG] << "# InsetTabular::doDispatch: cmd: " << cmd
+ << "\n cur:" << cur << endl;
CursorSlice sl = cur.top();
LCursor & bvcur = cur.bv().cursor();
case LFUN_RIGHTSEL:
case LFUN_RIGHT:
cell(cur.idx())->dispatch(cur, cmd);
- cur.dispatched(); // override the cell's decision
- if (sl == cur.top())
+ if (!cur.result().dispatched()) {
isRightToLeft(cur) ? movePrevCell(cur) : moveNextCell(cur);
- if (sl == cur.top()) {
- cmd = FuncRequest(LFUN_FINISHED_RIGHT);
- cur.undispatched();
- resetPos(cur);
+ if (sl == cur.top())
+ cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+ else
+ cur.dispatched();
}
break;
case LFUN_LEFTSEL:
case LFUN_LEFT:
cell(cur.idx())->dispatch(cur, cmd);
- cur.dispatched(); // override the cell's decision
- if (sl == cur.top())
+ if (!cur.result().dispatched()) {
isRightToLeft(cur) ? moveNextCell(cur) : movePrevCell(cur);
- if (sl == cur.top()) {
- cmd = FuncRequest(LFUN_FINISHED_LEFT);
- cur.undispatched();
- resetPos(cur);
+ if (sl == cur.top())
+ cmd = FuncRequest(LFUN_FINISHED_LEFT);
+ else
+ cur.dispatched();
}
break;
cell(cur.idx())->dispatch(cur, cmd);
cur.dispatched(); // override the cell's decision
if (sl == cur.top())
+ // if our LyXText didn't do anything to the cursor
+ // then we try to put the cursor into the cell below
+ // setting also the right targetX.
if (tabular.row_of_cell(cur.idx()) != tabular.rows() - 1) {
cur.idx() = tabular.getCellBelow(cur.idx());
cur.pit() = 0;
- cur.pos() = 0;
- resetPos(cur);
+ cur.pos() = cell(cur.idx())->getText(0)->x2pos(
+ cur.pit(), 0, cur.targetX());
}
if (sl == cur.top()) {
- cmd = FuncRequest(LFUN_FINISHED_DOWN);
+ // we trick it to go to the RIGHT after leaving the
+ // tabular.
+ cmd = FuncRequest(LFUN_FINISHED_RIGHT);
cur.undispatched();
- resetPos(cur);
}
break;
cell(cur.idx())->dispatch(cur, cmd);
cur.dispatched(); // override the cell's decision
if (sl == cur.top())
+ // if our LyXText didn't do anything to the cursor
+ // then we try to put the cursor into the cell above
+ // setting also the right targetX.
if (tabular.row_of_cell(cur.idx()) != 0) {
cur.idx() = tabular.getCellAbove(cur.idx());
cur.pit() = cur.lastpit();
- cur.pos() = cur.lastpos();
- resetPos(cur);
+ LyXText const * text = cell(cur.idx())->getText(0);
+ cur.pos() = text->x2pos(
+ cur.pit(),
+ text->paragraphs().back().rows().size()-1,
+ cur.targetX());
}
if (sl == cur.top()) {
cmd = FuncRequest(LFUN_FINISHED_UP);
cur.undispatched();
- resetPos(cur);
}
break;
// }
// cur.par() = 0;
// cur.pos() = 0;
-// resetPos(cur);
// break;
// }
//
// }
// cur.par() = cur.lastpar();
// cur.pos() = cur.lastpos();
-// resetPos(cur);
// break;
// }
case LFUN_CUT:
if (tablemode(cur)) {
if (copySelection(cur)) {
- recordUndo(cur, Undo::DELETE);
+ recordUndoInset(cur, Undo::DELETE);
cutSelection(cur);
}
}
case LFUN_BACKSPACE:
case LFUN_DELETE:
- recordUndo(cur, Undo::DELETE);
- if (tablemode(cur))
+ if (tablemode(cur)) {
+ recordUndoInset(cur, Undo::DELETE);
cutSelection(cur);
+ }
else
cell(cur.idx())->dispatch(cur, cmd);
break;
}
case LFUN_PASTE:
- if (hasPasteBuffer()) {
- recordUndo(cur, Undo::INSERT);
+ if (hasPasteBuffer() && tabularStackDirty()) {
+ recordUndoInset(cur, Undo::INSERT);
pasteSelection(cur);
break;
}
row_type rs, re;
col_type cs, ce;
getSelection(cur, rs, re, cs, ce);
- for (row_type i = rs; i <= re; ++i)
+ for (row_type i = rs; i <= re; ++i) {
for (col_type j = cs; j <= ce; ++j) {
// cursor follows cell:
cur.idx() = tabular.getCellNumber(i, j);
// select this cell only:
cur.pos() = 0;
- cur.resetAnchor();
+ cur.resetAnchor();
cur.pos() = cur.top().lastpos();
- cur.setCursor(cur);
- cur.setSelection();
+ cur.setCursor(cur);
+ cur.setSelection();
cell(cur.idx())->dispatch(cur, cmd);
}
+ }
// Restore original selection
cur.idx() = tabular.getCellNumber(rs, cs);
cur.pos() = 0;
break;
}
+ resetPos(cur);
InsetTabularMailer(*this).updateDialog(&cur.bv());
}
case LFUN_CELL_BACKWARD:
case LFUN_CELL_FORWARD:
status.enabled(true);
- return true;
+ return true;
// disable these with multiple cells selected
case LFUN_INSET_INSERT:
if (tablemode(cur)) {
status.enabled(false);
return true;
- }
+ } else
+ return cell(cur.idx())->getStatus(cur, cmd, status);
+ }
+
+ // disable in non-fixed-width cells
+ case LFUN_BREAKLINE:
+ case LFUN_BREAKPARAGRAPH:
+ case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
+ case LFUN_BREAKPARAGRAPH_SKIP: {
+ if (tabular.getPWidth(cur.idx()).zero()) {
+ status.enabled(false);
+ return true;
+ } else
+ return cell(cur.idx())->getStatus(cur, cmd, status);
}
case LFUN_INSET_MODIFY:
}
x += tabular.getBeginningOfTextInCell(idx);
x += ADD_TO_TABULAR_WIDTH;
- x += scroll();
+ x += scx_;
}
{
cur.idx() = getNearestCell(x, y);
cell(cur.idx())->text_.setCursorFromCoordinates(cur, x, y);
- resetPos(cur);
}
{
idx_type idx_min = 0;
int dist_min = std::numeric_limits<int>::max();
- for (idx_type i = 0; i < nargs(); ++i) {
+ for (idx_type i = 0, n = nargs(); i != n; ++i) {
if (theCoords.getInsets().has(tabular.getCellInset(i).get())) {
int const d = dist(i, x, y);
if (d < dist_min) {
int const maxwidth = bv.workWidth();
if (&cur.inset() != this) {
- //scx = 0;
+ scx_ = 0;
} else {
int const X1 = 0;
int const X2 = maxwidth;
int const x2 = x1 + tabular.getWidthOfColumn(cur.idx());
if (x1 < X1)
- scx = X1 + 20 - x1;
+ scx_ = X1 + 20 - x1;
else if (x2 > X2)
- scx = X2 - 20 - x2;
+ scx_ = X2 - 20 - x2;
else
- scx = 0;
+ scx_ = 0;
}
cur.needsUpdate();
break;
}
- recordUndo(cur, Undo::ATOMIC);
+ recordUndoInset(cur, Undo::ATOMIC);
getSelection(cur, sel_row_start, sel_row_end, sel_col_start, sel_col_end);
row_type const row = tabular.row_of_cell(cur.idx());
case LyXTabular::SET_PWIDTH: {
LyXLength const len(value);
- tabular.setColumnPWidth(cur.idx(), len);
+ tabular.setColumnPWidth(cur, cur.idx(), len);
if (len.zero()
&& tabular.getAlignment(cur.idx(), true) == LYX_ALIGN_BLOCK)
tabularFeatures(cur, LyXTabular::ALIGN_CENTER, string());
- else if (!len.zero()
- && tabular.getAlignment(cur.idx(), true) != LYX_ALIGN_BLOCK)
- tabularFeatures(cur, LyXTabular::ALIGN_BLOCK, string());
break;
}
case LyXTabular::SET_MPWIDTH:
- tabular.setMColumnPWidth(cur.idx(), LyXLength(value));
+ tabular.setMColumnPWidth(cur, cur.idx(), LyXLength(value));
break;
case LyXTabular::SET_SPECIAL_COLUMN:
OutputParams const runparams;
paste_tabular->plaintext(cur.buffer(), os, runparams, 0, true, '\t');
cur.bv().stuffClipboard(os.str());
+ // mark tabular stack dirty
+ // FIXME: this is a workaround for bug 1919. Should be removed for 1.5,
+ // when we (hopefully) have a one-for-all paste mechanism.
+ lyx::cap::dirtyTabularStack(true);
+
return true;
}
if (!cur.selection())
return;
- bool const track = cur.buffer().params().tracking_changes;
row_type rs, re;
col_type cs, ce;
getSelection(cur, rs, re, cs, ce);
- for (row_type i = rs; i <= re; ++i)
- for (col_type j = cs; j <= ce; ++j)
- cell(tabular.getCellNumber(i, j))->clear(track);
+ for (row_type i = rs; i <= re; ++i) {
+ for (col_type j = cs; j <= ce; ++j) {
+ shared_ptr<InsetText> t
+ = cell(tabular.getCellNumber(i, j));
+ if (cur.buffer().params().tracking_changes)
+ t->markErased(true);
+ else
+ t->clear();
+ }
+ }
// cursor position might be invalid now
cur.pos() = cur.lastpos();
}
-size_t InsetTabular::nargs() const
-{
- return tabular.getNumberOfCells();
-}
-
-
LyXText * InsetTabular::getText(int idx) const
{
return size_t(idx) < nargs() ? cell(idx)->getText(0) : 0;
}
-void InsetTabular::markErased()
+void InsetTabular::markErased(bool erased)
{
for (idx_type idx = 0; idx < nargs(); ++idx)
- cell(idx)->markErased();
+ cell(idx)->markErased(erased);
}
-bool InsetTabular::forceDefaultParagraphs(InsetBase const *) const
+bool InsetTabular::forceDefaultParagraphs(idx_type cell) const
{
-#if 0
- idx_type const cell = tabular.getCellFromInset(in);
- // FIXME: getCellFromInset() returns now always a valid cell, so
- // the stuff below can be deleted, and instead we have:
return tabular.getPWidth(cell).zero();
-
- if (cell != npos)
- return tabular.getPWidth(cell).zero();
-
- // this is a workaround for a crash (New, Insert->Tabular,
- // Insert->FootNote)
- if (!owner())
- return false;
-
- // well we didn't obviously find it so maybe our owner knows more
- BOOST_ASSERT(owner());
- return owner()->forceDefaultParagraphs(in);
-#endif
- return false;
}