#include "bufferparams.h"
#include "BufferView.h"
#include "cursor.h"
+#include "CutAndPaste.h"
#include "coordcache.h"
#include "debug.h"
#include "dispatchresult.h"
#include "support/convert.h"
#include "frontends/Alert.h"
-#include "frontends/font_metrics.h"
-#include "frontends/LyXView.h"
+#include "frontends/Clipboard.h"
#include "frontends/Painter.h"
-#include "frontends/nullpainter.h"
+#include "frontends/Selection.h"
#include <sstream>
#include <iostream>
#include <limits>
-using lyx::graphics::PreviewLoader;
-using lyx::support::ltrim;
+namespace lyx {
+
+using cap::dirtyTabularStack;
+using cap::tabularStackDirty;
+
+using graphics::PreviewLoader;
+
+using support::ltrim;
+
+using frontend::Painter;
+using frontend::Clipboard;
using boost::shared_ptr;
using std::swap;
using std::vector;
+namespace Alert = frontend::Alert;
+
namespace {
int const ADD_TO_HEIGHT = 2;
int const ADD_TO_TABULAR_WIDTH = 2;
+int const default_line_space = 10;
///
boost::scoped_ptr<LyXTabular> paste_tabular;
{ LyXTabular::APPEND_COLUMN, "append-column" },
{ LyXTabular::DELETE_ROW, "delete-row" },
{ LyXTabular::DELETE_COLUMN, "delete-column" },
+ { LyXTabular::COPY_ROW, "copy-row" },
+ { LyXTabular::COPY_COLUMN, "copy-column" },
{ LyXTabular::TOGGLE_LINE_TOP, "toggle-line-top" },
{ LyXTabular::TOGGLE_LINE_BOTTOM, "toggle-line-bottom" },
{ LyXTabular::TOGGLE_LINE_LEFT, "toggle-line-left" },
{ LyXTabular::SET_LTNEWPAGE, "set-ltnewpage" },
{ LyXTabular::SET_SPECIAL_COLUMN, "set-special-column" },
{ LyXTabular::SET_SPECIAL_MULTI, "set-special-multi" },
+ { LyXTabular::SET_BOOKTABS, "set-booktabs" },
+ { LyXTabular::UNSET_BOOKTABS, "unset-booktabs" },
+ { LyXTabular::SET_TOP_SPACE, "set-top-space" },
+ { LyXTabular::SET_BOTTOM_SPACE, "set-bottom-space" },
+ { LyXTabular::SET_INTERLINE_SPACE, "set-interline-space" },
{ LyXTabular::LAST_ACTION, "" }
};
InsetTabular::InsetTabular(Buffer const & buf, row_type rows,
- col_type columns)
+ col_type columns)
: tabular(buf.params(), max(rows, row_type(1)),
max(columns, col_type(1))), buffer_(&buf), 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);
if (!p_width.zero())
dim.wid = m.base.textwidth;
+ tabular.setWidthOfCell(cell, dim.wid);
+ if (p_width.zero()) {
+ m.base.textwidth = dim.wid + 2 * ADD_TO_TABULAR_WIDTH;
+ // FIXME there must be a way to get rid of
+ // the second metrics call
+ tabular.getCellInset(cell)->metrics(m, dim);
+ }
maxAsc = max(maxAsc, dim.asc);
maxDesc = max(maxDesc, dim.des);
- tabular.setWidthOfCell(cell, dim.wid);
++cell;
}
- tabular.setAscentOfRow(i, maxAsc + ADD_TO_HEIGHT);
- tabular.setDescentOfRow(i, maxDesc + ADD_TO_HEIGHT);
+ int const top_space = tabular.row_info[i].top_space_default ?
+ default_line_space :
+ tabular.row_info[i].top_space.inPixels(mi.base.textwidth);
+ tabular.setAscentOfRow(i, maxAsc + ADD_TO_HEIGHT + top_space);
+ int const bottom_space = tabular.row_info[i].bottom_space_default ?
+ default_line_space :
+ tabular.row_info[i].bottom_space.inPixels(mi.base.textwidth);
+ tabular.setDescentOfRow(i, maxDesc + ADD_TO_HEIGHT + bottom_space);
}
dim.asc = tabular.getAscentOfRow(0);
//lyxerr << "InsetTabular::draw: " << x << " " << y << endl;
BufferView * bv = pi.base.bv;
- static NullPainter nop;
- static PainterInfo nullpi(bv, nop);
-
- //resetPos(bv->cursor());
+ resetPos(bv->cursor());
x += scx_;
x += ADD_TO_TABULAR_WIDTH;
|| nx > bv->workWidth()
|| y + d < 0
|| y - a > bv->workHeight()) {
- cell(idx)->draw(nullpi, cx, y);
- drawCellLines(nop, nx, y, i, idx);
+ pi.pain.setDrawingEnabled(false);
+ cell(idx)->draw(pi, cx, y);
+ drawCellLines(pi.pain, nx, y, i, idx, pi.erased_);
+ pi.pain.setDrawingEnabled(true);
} 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;
setPosCache(pi, x, y);
LCursor & cur = pi.base.bv->cursor();
+
+ x += scx_ + ADD_TO_TABULAR_WIDTH;
+
+ // Paint background of current tabular
+ int const w = tabular.getWidthOfTabular();
+ int const h = tabular.getHeightOfTabular();
+ int yy = y - tabular.getAscentOfRow(0);
+ pi.pain.fillRectangle(x, yy, w, h, backgroundColor());
+
if (!cur.selection())
return;
if (!ptr_cmp(&cur.inset(), this))
//resetPos(cur);
- 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);
}
-string const InsetTabular::editMessage() const
+docstring const InsetTabular::editMessage() const
{
return _("Opened table");
}
void InsetTabular::edit(LCursor & cur, bool left)
{
- lyxerr << "InsetTabular::edit: " << this << endl;
+ //lyxerr << "InsetTabular::edit: " << this << endl;
finishUndo();
cur.selection() = false;
cur.push(*this);
cur.pit() = 0;
cur.pos() = cur.lastpos(); // FIXME crude guess
}
- // this accesses the position cache before it is initialized
+ // FIXME: this accesses the position cache before it is initialized
//resetPos(cur);
//cur.bv().fitCursor();
}
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_MOUSE_PRESS:
//lyxerr << "# InsetTabular::MousePress\n" << cur.bv().cursor() << endl;
- if (cmd.button() == mouse_button::button1) {
+ if (cmd.button() == mouse_button::button1
+ || cmd.button() == mouse_button::button3) {
cur.selection() = false;
setCursorFromCoordinates(cur, cmd.x, cmd.y);
cur.resetAnchor();
}
if (cmd.button() == mouse_button::button2) {
- // FIXME: pasting multiple cells (with insettabular's own
- // LFUN_PASTESELECTION still does not work! (jspitzm)
- cmd = FuncRequest(LFUN_PASTESELECTION, "paragraph");
- cell(cur.idx())->dispatch(cur, cmd);
- break;
+ cmd = FuncRequest(LFUN_PRIMARY_SELECTION_PASTE, "paragraph");
+ doDispatch(cur, cmd);
}
-
- // we'll pop up the table dialog on release
- if (cmd.button() == mouse_button::button3)
- break;
break;
case LFUN_MOUSE_MOTION:
cur.selection() = false;
break;
- case LFUN_RIGHTSEL:
- case LFUN_RIGHT:
+ case LFUN_CHAR_FORWARD_SELECT:
+ case LFUN_CHAR_FORWARD:
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();
+ if (sl == cur.top())
+ cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+ else
+ cur.dispatched();
}
break;
- case LFUN_LEFTSEL:
- case LFUN_LEFT:
+ case LFUN_CHAR_BACKWARD_SELECT:
+ case LFUN_CHAR_BACKWARD:
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();
+ if (sl == cur.top())
+ cmd = FuncRequest(LFUN_FINISHED_LEFT);
+ else
+ cur.dispatched();
}
break;
- case LFUN_DOWNSEL:
+ case LFUN_DOWN_SELECT:
case LFUN_DOWN:
cell(cur.idx())->dispatch(cur, cmd);
cur.dispatched(); // override the cell's decision
cur.idx() = tabular.getCellBelow(cur.idx());
cur.pit() = 0;
cur.pos() = cell(cur.idx())->getText(0)->x2pos(
- cur.pit(), 0, cur.targetX());
+ cur.bv(), cur.pit(), 0, cur.targetX());
}
if (sl == cur.top()) {
// we trick it to go to the RIGHT after leaving the
}
break;
- case LFUN_UPSEL:
+ case LFUN_UP_SELECT:
case LFUN_UP:
cell(cur.idx())->dispatch(cur, cmd);
cur.dispatched(); // override the cell's decision
cur.pit() = cur.lastpit();
LyXText const * text = cell(cur.idx())->getText(0);
cur.pos() = text->x2pos(
+ cur.bv(),
cur.pit(),
text->paragraphs().back().rows().size()-1,
cur.targetX());
}
break;
-// case LFUN_NEXT: {
+// case LFUN_SCREEN_DOWN: {
// //if (hasSelection())
// // cur.selection() = false;
// col_type const col = tabular.column_of_cell(cur.idx());
-// int const t = cur.bv().top_y() + cur.bv().painter().paperHeight();
+// int const t = cur.bv().top_y() + cur.bv().height();
// if (t < yo() + tabular.getHeightOfTabular()) {
// cur.bv().scrollDocView(t);
// cur.idx() = tabular.getCellBelow(first_visible_cell) + col;
// break;
// }
//
-// case LFUN_PRIOR: {
+// case LFUN_SCREEN_UP: {
// //if (hasSelection())
// // cur.selection() = false;
// col_type const col = tabular.column_of_cell(cur.idx());
-// int const t = cur.bv().top_y() + cur.bv().painter().paperHeight();
+// int const t = cur.bv().top_y() + cur.bv().height();
// if (yo() < 0) {
// cur.bv().scrollDocView(t);
// if (yo() > 0)
break;
case LFUN_TABULAR_FEATURE:
- if (!tabularFeatures(cur, cmd.argument))
+ if (!tabularFeatures(cur, to_utf8(cmd.argument())))
cur.undispatched();
break;
// insert file functions
case LFUN_FILE_INSERT_ASCII_PARA:
case LFUN_FILE_INSERT_ASCII: {
- string const tmpstr = getContentsOfAsciiFile(&cur.bv(), cmd.argument, false);
- if (!tmpstr.empty() && !insertAsciiString(cur.bv(), tmpstr, false))
+ // FIXME: We don't know the encoding of filenames
+ string const tmpstr = getContentsOfAsciiFile(&cur.bv(), to_utf8(cmd.argument()), false);
+ // FIXME: We don't know the encoding of the file
+ if (!tmpstr.empty() && !insertAsciiString(cur.bv(), from_utf8(tmpstr), false))
cur.undispatched();
break;
}
case LFUN_CUT:
if (tablemode(cur)) {
if (copySelection(cur)) {
- recordUndo(cur, Undo::DELETE);
+ recordUndoInset(cur, Undo::DELETE);
cutSelection(cur);
}
}
cell(cur.idx())->dispatch(cur, cmd);
break;
- case LFUN_BACKSPACE:
- case LFUN_DELETE:
- recordUndo(cur, Undo::DELETE);
- if (tablemode(cur))
+ case LFUN_CHAR_DELETE_BACKWARD:
+ case LFUN_CHAR_DELETE_FORWARD:
+ if (tablemode(cur)) {
+ recordUndoInset(cur, Undo::DELETE);
cutSelection(cur);
+ }
else
cell(cur.idx())->dispatch(cur, cmd);
break;
cell(cur.idx())->dispatch(cur, cmd);
break;
- case LFUN_PASTESELECTION: {
- string const clip = cur.bv().getClipboard();
+ case LFUN_CLIPBOARD_PASTE:
+ case LFUN_PRIMARY_SELECTION_PASTE: {
+ docstring const clip = (cmd.action == LFUN_CLIPBOARD_PASTE) ?
+ theClipboard().get() :
+ theSelection().get();
if (clip.empty())
break;
- if (clip.find('\t') != string::npos) {
- col_type cols = 1;
- row_type rows = 1;
- col_type maxCols = 1;
- size_t len = clip.length();
- for (size_t p = 0; p < len; ++p) {
- p = clip.find_first_of("\t\n", p);
- if (p == string::npos)
- break;
- switch (clip[p]) {
- case '\t':
- ++cols;
- break;
- case '\n':
- if (p + 1 < len)
- ++rows;
- maxCols = max(cols, maxCols);
- cols = 1;
- break;
- }
- }
- maxCols = max(cols, maxCols);
-
- paste_tabular.reset(
- new LyXTabular(cur.buffer().params(), rows, maxCols));
-
- string::size_type op = 0;
- idx_type cell = 0;
- idx_type const cells =
- paste_tabular->getNumberOfCells();
- cols = 0;
- LyXFont font;
- for (size_t p = 0; cell < cells && p < len; ++p) {
- p = clip.find_first_of("\t\n", p);
- if (p == string::npos || p >= len)
- break;
- switch (clip[p]) {
- case '\t':
- paste_tabular->getCellInset(cell)->
- setText(clip.substr(op, p - op), font);
- ++cols;
- ++cell;
- break;
- case '\n':
- paste_tabular->getCellInset(cell)->
- setText(clip.substr(op, p - op), font);
- while (cols++ < maxCols)
- ++cell;
- cols = 0;
- break;
- }
- op = p + 1;
+ // pass to InsertAsciiString, but
+ // only if we have multi-cell content
+ if (clip.find_first_of(from_ascii("\t\n")) != docstring::npos) {
+ if (insertAsciiString(cur.bv(), clip, false)) {
+ // content has been replaced,
+ // so cursor might be invalid
+ cur.pos() = cur.lastpos();
+ bvcur.setCursor(cur);
+ break;
}
- // check for the last cell if there is no trailing '\n'
- if (cell < cells && op < len)
- paste_tabular->getCellInset(cell)->
- setText(clip.substr(op, len - op), font);
- } else if (!insertAsciiString(cur.bv(), clip, true)) {
+ } else {
// so that the clipboard is used and it goes on
// to default
- // and executes LFUN_PASTESELECTION in insettext!
+ // and executes LFUN_PRIMARY_SELECTION_PASTE in insettext!
paste_tabular.reset();
+ dirtyTabularStack(false);
}
// fall through
}
case LFUN_PASTE:
- if (hasPasteBuffer()) {
- recordUndo(cur, Undo::INSERT);
+ if (hasPasteBuffer() && tabularStackDirty()) {
+ recordUndoInset(cur, Undo::INSERT);
pasteSelection(cur);
break;
}
cell(cur.idx())->dispatch(cur, cmd);
break;
- case LFUN_EMPH:
- case LFUN_BOLD:
- case LFUN_ROMAN:
- case LFUN_NOUN:
- case LFUN_ITAL:
- case LFUN_FRAK:
- case LFUN_CODE:
- case LFUN_SANS:
- case LFUN_FREEFONT_APPLY:
- case LFUN_FREEFONT_UPDATE:
+ case LFUN_FONT_EMPH:
+ case LFUN_FONT_BOLD:
+ case LFUN_FONT_ROMAN:
+ case LFUN_FONT_NOUN:
+ case LFUN_FONT_ITAL:
+ case LFUN_FONT_FRAK:
+ case LFUN_FONT_CODE:
+ case LFUN_FONT_SANS:
+ case LFUN_FONT_FREE_APPLY:
+ case LFUN_FONT_FREE_UPDATE:
case LFUN_FONT_SIZE:
- case LFUN_UNDERLINE:
+ case LFUN_FONT_UNDERLINE:
case LFUN_LANGUAGE:
- case LFUN_CAPITALIZE_WORD:
- case LFUN_UPCASE_WORD:
- case LFUN_LOWCASE_WORD:
- case LFUN_TRANSPOSE_CHARS:
+ case LFUN_WORD_CAPITALIZE:
+ case LFUN_WORD_UPCASE:
+ case LFUN_WORD_LOWCASE:
+ case LFUN_CHARS_TRANSPOSE:
if (tablemode(cur)) {
row_type rs, re;
col_type cs, ce;
getSelection(cur, rs, re, cs, ce);
+ LCursor tmpcur = cur;
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);
+ tmpcur.idx() = tabular.getCellNumber(i, j);
// select this cell only:
- cur.pos() = 0;
- cur.resetAnchor();
- cur.pos() = cur.top().lastpos();
- cur.setCursor(cur);
- cur.setSelection();
- cell(cur.idx())->dispatch(cur, cmd);
+ tmpcur.pit() = 0;
+ tmpcur.pos() = 0;
+ tmpcur.resetAnchor();
+ tmpcur.pit() = tmpcur.lastpit();
+ tmpcur.pos() = tmpcur.top().lastpos();
+ tmpcur.setCursor(tmpcur);
+ tmpcur.setSelection();
+ cell(tmpcur.idx())->dispatch(tmpcur, cmd);
}
}
- // Restore original selection
- cur.idx() = tabular.getCellNumber(rs, cs);
- cur.pos() = 0;
- cur.resetAnchor();
- cur.idx() = tabular.getCellNumber(re, ce);
- cur.pos() = cur.top().lastpos();
- cur.setCursor(cur);
- cur.setSelection();
break;
} else {
cell(cur.idx())->dispatch(cur, cmd);
break;
}
- resetPos(cur);
+ // FIXME: this accesses the position cache before it is initialized
+ //resetPos(cur);
InsetTabularMailer(*this).updateDialog(&cur.bv());
}
int i = 0;
for (; tabularFeature[i].action != LyXTabular::LAST_ACTION; ++i) {
string const tmp = tabularFeature[i].feature;
- if (tmp == cmd.argument.substr(0, tmp.length())) {
+ if (tmp == to_utf8(cmd.argument()).substr(0, tmp.length())) {
action = tabularFeature[i].action;
break;
}
}
string const argument
- = ltrim(cmd.argument.substr(tabularFeature[i].feature.length()));
+ = ltrim(to_utf8(cmd.argument()).substr(tabularFeature[i].feature.length()));
row_type sel_row_start = 0;
row_type sel_row_end = 0;
case LyXTabular::APPEND_COLUMN:
case LyXTabular::DELETE_ROW:
case LyXTabular::DELETE_COLUMN:
+ case LyXTabular::COPY_ROW:
+ case LyXTabular::COPY_COLUMN:
case LyXTabular::SET_ALL_LINES:
case LyXTabular::UNSET_ALL_LINES:
+ case LyXTabular::SET_TOP_SPACE:
+ case LyXTabular::SET_BOTTOM_SPACE:
+ case LyXTabular::SET_INTERLINE_SPACE:
status.clear();
return true;
status.setOnOff(tabular.getLTNewPage(sel_row_start));
break;
+ case LyXTabular::SET_BOOKTABS:
+ status.setOnOff(tabular.useBookTabs());
+ break;
+
+ case LyXTabular::UNSET_BOOKTABS:
+ status.setOnOff(!tabular.useBookTabs());
+ break;
+
default:
status.clear();
status.enabled(false);
// disable these with multiple cells selected
case LFUN_INSET_INSERT:
case LFUN_TABULAR_INSERT:
- case LFUN_INSERT_CHARSTYLE:
- case LFUN_INSET_FLOAT:
- case LFUN_INSET_WIDE_FLOAT:
- case LFUN_INSET_FOOTNOTE:
- case LFUN_INSET_MARGINAL:
- case LFUN_INSERT_MATH:
+ case LFUN_CHARSTYLE_INSERT:
+ case LFUN_FLOAT_INSERT:
+ case LFUN_FLOAT_WIDE_INSERT:
+ case LFUN_FOOTNOTE_INSERT:
+ case LFUN_MARGINALNOTE_INSERT:
+ case LFUN_MATH_INSERT:
case LFUN_MATH_MODE:
case LFUN_MATH_MUTATE:
case LFUN_MATH_DISPLAY:
- case LFUN_INSERT_NOTE:
- case LFUN_INSET_OPTARG:
- case LFUN_INSERT_BOX:
- case LFUN_INSERT_BRANCH:
- case LFUN_INSET_WRAP:
- case LFUN_INSET_ERT: {
+ case LFUN_NOTE_INSERT:
+ case LFUN_OPTIONAL_INSERT:
+ case LFUN_BOX_INSERT:
+ case LFUN_BRANCH_INSERT:
+ case LFUN_WRAP_INSERT:
+ case LFUN_ERT_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_BREAK_LINE:
+ case LFUN_BREAK_PARAGRAPH:
+ case LFUN_BREAK_PARAGRAPH_KEEP_LAYOUT:
+ case LFUN_BREAK_PARAGRAPH_SKIP: {
+ if (tabular.getPWidth(cur.idx()).zero()) {
+ status.enabled(false);
+ return true;
+ } else
+ return cell(cur.idx())->getStatus(cur, cmd, status);
+ }
+
+ case LFUN_PASTE:
+ if (tabularStackDirty()) {
+ status.enabled(true);
+ return true;
+ }
+
case LFUN_INSET_MODIFY:
if (translate(cmd.getArg(0)) == TABULAR_CODE) {
status.enabled(true);
}
-int InsetTabular::latex(Buffer const & buf, ostream & os,
+int InsetTabular::latex(Buffer const & buf, odocstream & os,
OutputParams const & runparams) const
{
return tabular.latex(buf, os, runparams);
}
-int InsetTabular::plaintext(Buffer const & buf, ostream & os,
+int InsetTabular::plaintext(Buffer const & buf, odocstream & os,
OutputParams const & runparams) const
{
int const dp = runparams.linelen ? runparams.depth : 0;
}
-int InsetTabular::linuxdoc(Buffer const & buf, ostream & os,
- OutputParams const & runparams) const
-{
- return tabular.linuxdoc(buf,os, runparams);
-}
-
-
-int InsetTabular::docbook(Buffer const & buf, ostream & os,
+int InsetTabular::docbook(Buffer const & buf, odocstream & os,
OutputParams const & runparams) const
{
int ret = 0;
}
-void InsetTabular::cursorPos
- (CursorSlice const & sl, bool boundary, int & x, int & y) const
+void InsetTabular::cursorPos(BufferView const & bv,
+ CursorSlice const & sl, bool boundary, int & x, int & y) const
{
- cell(sl.idx())->cursorPos(sl, boundary, x, y);
+ cell(sl.idx())->cursorPos(bv, sl, boundary, x, y);
// y offset correction
int const row = tabular.row_of_cell(sl.idx());
}
-int InsetTabular::dist(idx_type const cell, int x, int y) const
+int InsetTabular::dist(BufferView & bv, idx_type const cell, int x, int y) const
{
int xx = 0;
int yy = 0;
InsetBase const & inset = *tabular.getCellInset(cell);
- Point o = theCoords.getInsets().xy(&inset);
+ Point o = bv.coordCache().getInsets().xy(&inset);
int const xbeg = o.x_ - tabular.getBeginningOfTextInCell(cell);
int const xend = xbeg + tabular.getWidthOfColumn(cell);
- int const ybeg = o.y_ - inset.ascent();
row_type const row = tabular.row_of_cell(cell);
- int const rowheight = tabular.getAscentOfRow(row)
- + tabular.getDescentOfRow(row)
- + tabular.getAdditionalHeight(row);
- int const yend = ybeg + rowheight;
+ int const ybeg = o.y_ - tabular.getAscentOfRow(row) -
+ tabular.getAdditionalHeight(row);
+ int const yend = o.y_ + tabular.getDescentOfRow(row);
if (x < xbeg)
xx = xbeg - x;
else if (x > xend)
xx = x - xend;
- if (y < ybeg)
+ if (y < ybeg)
yy = ybeg - y;
- else if (y > yend)
+ else if (y > yend)
yy = y - yend;
//lyxerr << " xbeg=" << xbeg << " xend=" << xend
//lyxerr << "InsetTabular::editXY: " << this << endl;
cur.selection() = false;
cur.push(*this);
- cur.idx() = getNearestCell(x, y);
+ cur.idx() = getNearestCell(cur.bv(), x, y);
resetPos(cur);
return cell(cur.idx())->text_.editXY(cur, x, y);
}
void InsetTabular::setCursorFromCoordinates(LCursor & cur, int x, int y) const
{
- cur.idx() = getNearestCell(x, y);
+ cur.idx() = getNearestCell(cur.bv(), x, y);
cell(cur.idx())->text_.setCursorFromCoordinates(cur, x, y);
- resetPos(cur);
}
-InsetTabular::idx_type InsetTabular::getNearestCell(int x, int y) const
+InsetTabular::idx_type InsetTabular::getNearestCell(BufferView & bv, int x, int y) const
{
idx_type idx_min = 0;
int dist_min = std::numeric_limits<int>::max();
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 (bv.coordCache().getInsets().has(tabular.getCellInset(i).get())) {
+ int const d = dist(bv, i, x, y);
if (d < dist_min) {
dist_min = d;
idx_min = i;
int const X1 = 0;
int const X2 = maxwidth;
int const offset = ADD_TO_TABULAR_WIDTH + 2;
- int const x1 = xo() + getCellXPos(cur.idx()) + offset;
+ int const x1 = xo(cur.bv()) + getCellXPos(cur.idx()) + offset;
int const x2 = x1 + tabular.getWidthOfColumn(cur.idx());
if (x1 < X1)
scx_ = 0;
}
- cur.needsUpdate();
+ cur.updateFlags(Update::Force | Update::FitCursor);
InsetTabularMailer(*this).updateDialog(&bv);
}
}
cur.pit() = cur.lastpit();
cur.pos() = cur.lastpos();
- resetPos(cur);
+
+ // FIXME: this accesses the position cache before it is initialized
+ //resetPos(cur);
}
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:
cur.selection() = false;
break;
+ case LyXTabular::COPY_ROW:
+ tabular.copyRow(bv.buffer()->params(), row);
+ break;
+
+ case LyXTabular::COPY_COLUMN:
+ tabular.copyColumn(bv.buffer()->params(), column);
+ cur.idx() = tabular.getCellNumber(row, column);
+ break;
+
case LyXTabular::M_TOGGLE_LINE_TOP:
flag = false;
case LyXTabular::TOGGLE_LINE_TOP: {
#ifdef WITH_WARNINGS
#warning Need I say it ? This is horrible.
#endif
+ // FIXME UNICODE
Alert::error(_("Error setting multicolumn"),
- _("You cannot set multicolumn vertically."));
+ _("You cannot set multicolumn vertically."));
return;
}
if (!cur.selection()) {
tabular.setLTNewPage(row, !tabular.getLTNewPage(row));
break;
+ case LyXTabular::SET_BOOKTABS:
+ tabular.setBookTabs(true);
+ break;
+
+ case LyXTabular::UNSET_BOOKTABS:
+ tabular.setBookTabs(false);
+ break;
+
+ case LyXTabular::SET_TOP_SPACE: {
+ LyXLength len;
+ if (value == "default")
+ for (row_type i = sel_row_start; i <= sel_row_end; ++i)
+ tabular.row_info[i].top_space_default = true;
+ else if (isValidLength(value, &len))
+ for (row_type i = sel_row_start; i <= sel_row_end; ++i) {
+ tabular.row_info[i].top_space_default = false;
+ tabular.row_info[i].top_space = len;
+ }
+ else
+ for (row_type i = sel_row_start; i <= sel_row_end; ++i) {
+ tabular.row_info[i].top_space_default = false;
+ tabular.row_info[i].top_space = len;
+ }
+ break;
+ }
+
+ case LyXTabular::SET_BOTTOM_SPACE: {
+ LyXLength len;
+ if (value == "default")
+ for (row_type i = sel_row_start; i <= sel_row_end; ++i)
+ tabular.row_info[i].bottom_space_default = true;
+ else if (isValidLength(value, &len))
+ for (row_type i = sel_row_start; i <= sel_row_end; ++i) {
+ tabular.row_info[i].bottom_space_default = false;
+ tabular.row_info[i].bottom_space = len;
+ }
+ else
+ for (row_type i = sel_row_start; i <= sel_row_end; ++i) {
+ tabular.row_info[i].bottom_space_default = false;
+ tabular.row_info[i].bottom_space = len;
+ }
+ break;
+ }
+
+ case LyXTabular::SET_INTERLINE_SPACE: {
+ LyXLength len;
+ if (value == "default")
+ for (row_type i = sel_row_start; i <= sel_row_end; ++i)
+ tabular.row_info[i].interline_space_default = true;
+ else if (isValidLength(value, &len))
+ for (row_type i = sel_row_start; i <= sel_row_end; ++i) {
+ tabular.row_info[i].interline_space_default = false;
+ tabular.row_info[i].interline_space = len;
+ }
+ else
+ for (row_type i = sel_row_start; i <= sel_row_end; ++i) {
+ tabular.row_info[i].interline_space_default = false;
+ tabular.row_info[i].interline_space = len;
+ }
+ break;
+ }
+
// dummy stuff just to avoid warnings
case LyXTabular::LAST_ACTION:
break;
}
-void InsetTabular::getLabelList(Buffer const & buffer,
- vector<string> & list) const
-{
- tabular.getLabelList(buffer, list);
-}
-
-
bool InsetTabular::copySelection(LCursor & cur)
{
if (!cur.selection())
paste_tabular->setRightLine(paste_tabular->getLastCellInRow(0),
true, true);
- ostringstream os;
+ odocstringstream os;
OutputParams const runparams;
paste_tabular->plaintext(cur.buffer(), os, runparams, 0, true, '\t');
- cur.bv().stuffClipboard(os.str());
+ theClipboard().put(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.
+ cap::dirtyTabularStack(true);
+
return true;
}
shared_ptr<InsetText> inset(
new InsetText(*paste_tabular->getCellInset(r1, c1)));
tabular.setCellInset(r2, c2, inset);
- inset->markNew();
+ // FIXME: change tracking (MG)
+ inset->setChange(Change(cur.buffer().params().trackChanges ?
+ Change::INSERTED : Change::UNCHANGED));
cur.pos() = 0;
}
}
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().trackChanges)
+ // FIXME: Change tracking (MG)
+ t->setChange(Change(Change::DELETED));
+ else
+ t->clear();
+ }
+ }
// cursor position might be invalid now
- cur.pos() = cur.lastpos();
+ if (cur.pit() > cur.lastpit())
+ cur.pit() = cur.lastpit();
+ if (cur.pos() > cur.lastpos())
+ cur.pos() = cur.lastpos();
cur.clearSelection();
}
{
BOOST_ASSERT(cur.depth() > 1);
Paragraph const & parentpar = cur[cur.depth() - 2].paragraph();
- LCursor::pos_type const parentpos = cur[cur.depth() - 2].pos();
+ pos_type const parentpos = cur[cur.depth() - 2].pos();
return parentpar.getFontSettings(cur.bv().buffer()->params(),
- parentpos).language()->RightToLeft();
+ parentpos).language()->rightToLeft();
}
}
-void InsetTabular::markErased()
+void InsetTabular::setChange(Change const & change)
{
for (idx_type idx = 0; idx < nargs(); ++idx)
- cell(idx)->markErased();
+ cell(idx)->setChange(change);
}
-bool InsetTabular::forceDefaultParagraphs(InsetBase const *) const
+void InsetTabular::acceptChanges()
{
-#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();
+ for (idx_type idx = 0; idx < nargs(); ++idx)
+ cell(idx)->acceptChanges();
+}
- if (cell != npos)
- return tabular.getPWidth(cell).zero();
- // this is a workaround for a crash (New, Insert->Tabular,
- // Insert->FootNote)
- if (!owner())
- return false;
+void InsetTabular::rejectChanges()
+{
+ for (idx_type idx = 0; idx < nargs(); ++idx)
+ cell(idx)->rejectChanges();
+}
- // well we didn't obviously find it so maybe our owner knows more
- BOOST_ASSERT(owner());
- return owner()->forceDefaultParagraphs(in);
-#endif
- return false;
+
+bool InsetTabular::forceDefaultParagraphs(idx_type cell) const
+{
+ return tabular.getPWidth(cell).zero();
}
-bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf,
+bool InsetTabular::insertAsciiString(BufferView & bv, docstring const & buf,
bool usePaste)
{
if (buf.length() <= 0)
return true;
+ Buffer const & buffer = *bv.buffer();
+
col_type cols = 1;
row_type rows = 1;
col_type maxCols = 1;
- string::size_type const len = buf.length();
- string::size_type p = 0;
+ docstring::size_type const len = buf.length();
+ docstring::size_type p = 0;
- while (p < len && (p = buf.find_first_of("\t\n", p)) != string::npos) {
+ while (p < len &&
+ (p = buf.find_first_of(from_ascii("\t\n"), p)) != docstring::npos) {
switch (buf[p]) {
case '\t':
++cols;
row_type row = 0;
if (usePaste) {
paste_tabular.reset(
- new LyXTabular(bv.buffer()->params(), rows, maxCols));
+ new LyXTabular(buffer.params(), rows, maxCols));
loctab = paste_tabular.get();
cols = 0;
+ dirtyTabularStack(true);
} else {
loctab = &tabular;
cell = bv.cursor().idx();
row = tabular.row_of_cell(cell);
}
- string::size_type op = 0;
+ docstring::size_type op = 0;
idx_type const cells = loctab->getNumberOfCells();
p = 0;
cols = ocol;
col_type const columns = loctab->columns();
while (cell < cells && p < len && row < rows &&
- (p = buf.find_first_of("\t\n", p)) != string::npos)
+ (p = buf.find_first_of(from_ascii("\t\n"), p)) != docstring::npos)
{
if (p >= len)
break;
if (cols < columns) {
shared_ptr<InsetText> inset = loctab->getCellInset(cell);
Paragraph & par = inset->text_.getPar(0);
- LyXFont const font = inset->text_.getFont(par, 0);
- inset->setText(buf.substr(op, p - op), font);
+ LyXFont const font = inset->text_.getFont(buffer, par, 0);
+ inset->setText(buf.substr(op, p - op), font,
+ buffer.params().trackChanges);
++cols;
++cell;
}
if (cols < columns) {
shared_ptr<InsetText> inset = tabular.getCellInset(cell);
Paragraph & par = inset->text_.getPar(0);
- LyXFont const font = inset->text_.getFont(par, 0);
- inset->setText(buf.substr(op, p - op), font);
+ LyXFont const font = inset->text_.getFont(buffer, par, 0);
+ inset->setText(buf.substr(op, p - op), font,
+ buffer.params().trackChanges);
}
cols = ocol;
++row;
if (cell < cells && op < len) {
shared_ptr<InsetText> inset = loctab->getCellInset(cell);
Paragraph & par = inset->text_.getPar(0);
- LyXFont const font = inset->text_.getFont(par, 0);
- inset->setText(buf.substr(op, len - op), font);
+ LyXFont const font = inset->text_.getFont(buffer, par, 0);
+ inset->setText(buf.substr(op, len - op), font,
+ buffer.params().trackChanges);
}
return true;
}
lex >> token;
if (!lex || token != name_)
return print_mailer_error("InsetTabularMailer", in, 1,
- name_);
+ name_);
// This is part of the inset proper that is usually swallowed
// by Buffer::readInset
lex >> token;
if (!lex || token != "Tabular")
return print_mailer_error("InsetTabularMailer", in, 2,
- "Tabular");
+ "Tabular");
Buffer const & buffer = inset.buffer();
inset.read(buffer, lex);
data << "\\end_inset\n";
return data.str();
}
+
+
+} // namespace lyx