X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsettabular.C;h=202ac6fa44bb8495781e2a56dd4919f2a87029ff;hb=e28331ed63062dea10d0a21b9ec12034b4b17b9a;hp=868e9d1004c2afe57841488c8b6aeb7e8215f194;hpb=4beb140b99a471bd935853805a907c5ae254198a;p=lyx.git diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index 868e9d1004..202ac6fa44 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -16,6 +16,7 @@ #include "bufferparams.h" #include "BufferView.h" #include "cursor.h" +#include "CutAndPaste.h" #include "coordcache.h" #include "debug.h" #include "dispatchresult.h" @@ -36,18 +37,26 @@ #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 #include #include -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; @@ -61,11 +70,14 @@ using std::ostringstream; 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 paste_tabular; @@ -83,6 +95,8 @@ TabularFeature tabularFeature[] = { 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" }, @@ -127,6 +141,11 @@ TabularFeature tabularFeature[] = { 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, "" } }; @@ -155,22 +174,16 @@ string const featureAsString(LyXTabular::Feature feature) } -bool InsetTabular::hasPasteBuffer() const -{ - return (paste_tabular.get() != 0); -} - - 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), 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) {} @@ -227,7 +240,7 @@ void InsetTabular::read(Buffer const & buf, LyXLex & lex) } -void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const +bool InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const { //lyxerr << "InsetTabular::metrics: " << mi.base.bv << " width: " << // mi.base.textwidth << "\n"; @@ -242,28 +255,48 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const 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); dim.des = tabular.getHeightOfTabular() - dim.asc; dim.wid = tabular.getWidthOfTabular() + 2 * ADD_TO_TABULAR_WIDTH; + bool const changed = dim_ != dim; dim_ = dim; + return changed; } @@ -274,12 +307,9 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const //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 += scroll(); + x += scx_; x += ADD_TO_TABULAR_WIDTH; idx_type idx = 0; @@ -300,11 +330,13 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const || 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; @@ -322,6 +354,15 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const 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)) @@ -329,8 +370,6 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const //resetPos(cur); - x += scroll(); - x += ADD_TO_TABULAR_WIDTH; if (tablemode(cur)) { row_type rs, re; @@ -364,28 +403,35 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const 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); @@ -393,12 +439,12 @@ void InsetTabular::drawCellLines(Painter & pain, int x, int y, 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"); } @@ -406,7 +452,7 @@ string const InsetTabular::editMessage() const void InsetTabular::edit(LCursor & cur, bool left) { - lyxerr << "InsetTabular::edit: " << this << endl; + //lyxerr << "InsetTabular::edit: " << this << endl; finishUndo(); cur.selection() = false; cur.push(*this); @@ -425,7 +471,7 @@ void InsetTabular::edit(LCursor & cur, bool left) 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(); } @@ -433,8 +479,8 @@ void InsetTabular::edit(LCursor & cur, bool left) 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(); @@ -443,25 +489,31 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) 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 + && (&bvcur.selBegin().inset() != this || !tablemode(bvcur)))) { + if (!bvcur.selection() && !cur.bv().mouseSetCursor(cur)) + cur.noUpdate(); cur.selection() = false; setCursorFromCoordinates(cur, cmd.x, cmd.y); - cur.resetAnchor(); - bvcur = cur; + cur.bv().mouseSetCursor(cur); break; } 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; + if (bvcur.selection()) { + // See comment in LyXText::dispatch why we + // do this + // FIXME This does not use paste_tabular, + // another reason why paste_tabular should go. + cap::copySelectionToStack(bvcur); + cmd = FuncRequest(LFUN_PASTE, "0"); + } else { + 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: @@ -469,6 +521,10 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) if (cmd.button() == mouse_button::button1) { // only accept motions to places not deeper nested than the real anchor if (bvcur.anchor_.hasPart(cur)) { + // only update if selection changes + if (bvcur.idx() == cur.idx() && + !(bvcur.anchor_.idx() == cur.idx() && bvcur.pos() != cur.pos())) + cur.noUpdate(); setCursorFromCoordinates(cur, cmd.x, cmd.y); bvcur.setCursor(cur); bvcur.selection() = true; @@ -479,7 +535,10 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) case LFUN_MOUSE_RELEASE: //lyxerr << "# InsetTabular::MouseRelease\n" << bvcur << endl; - if (cmd.button() == mouse_button::button3) + if (cmd.button() == mouse_button::button1) { + if (bvcur.selection()) + theSelection().haveSelection(true); + } else if (cmd.button() == mouse_button::button3) InsetTabularMailer(*this).showDialog(&cur.bv()); break; @@ -493,73 +552,89 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) 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(); - resetPos(cur); + if (cmd.action == LFUN_CHAR_FORWARD_SELECT) + theSelection().haveSelection(cur.selection()); + 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(); - resetPos(cur); + if (cmd.action == LFUN_CHAR_BACKWARD_SELECT) + theSelection().haveSelection(cur.selection()); + 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 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); + TextMetrics const & tm = + cur.bv().textMetrics(cell(cur.idx())->getText(0)); + cur.pos() = tm.x2pos(cur.pit(), 0, cur.targetX()); + if (cmd.action == LFUN_DOWN_SELECT) + theSelection().haveSelection(cur.selection()); } 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; - case LFUN_UPSEL: + case LFUN_UP_SELECT: case LFUN_UP: 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); + TextMetrics const & tm = cur.bv().textMetrics(text); + ParagraphMetrics const & pm = + tm.parMetrics(cur.lastpit()); + cur.pos() = tm.x2pos(cur.pit(), pm.rows().size()-1, cur.targetX()); + if (cmd.action == LFUN_UP_SELECT) + theSelection().haveSelection(cur.selection()); } if (sl == cur.top()) { cmd = FuncRequest(LFUN_FINISHED_UP); cur.undispatched(); - resetPos(cur); } 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; @@ -568,15 +643,14 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) // } // cur.par() = 0; // cur.pos() = 0; -// resetPos(cur); // 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) @@ -588,7 +662,6 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) // } // cur.par() = cur.lastpar(); // cur.pos() = cur.lastpos(); -// resetPos(cur); // break; // } @@ -601,15 +674,17 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) 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)) + case LFUN_FILE_INSERT_PLAINTEXT_PARA: + case LFUN_FILE_INSERT_PLAINTEXT: { + // FIXME UNICODE + string const tmpstr = getContentsOfPlaintextFile(&cur.bv(), to_utf8(cmd.argument()), false); + // FIXME: We don't know the encoding of the file + if (!tmpstr.empty() && !insertPlaintextString(cur.bv(), from_utf8(tmpstr), false)) cur.undispatched(); break; } @@ -617,7 +692,7 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) case LFUN_CUT: if (tablemode(cur)) { if (copySelection(cur)) { - recordUndo(cur, Undo::DELETE); + recordUndoInset(cur, Undo::DELETE); cutSelection(cur); } } @@ -625,11 +700,12 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) 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; @@ -644,126 +720,75 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) 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().getAsText() : + 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 InsertPlaintextString, but + // only if we have multi-cell content + if (clip.find_first_of(from_ascii("\t\n")) != docstring::npos) { + if (insertPlaintextString(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)) { - // so that the clipboard is used and it goes on - // to default - // and executes LFUN_PASTESELECTION in insettext! - paste_tabular.reset(); } - // fall through + // Let the cell handle normal text + cell(cur.idx())->dispatch(cur, cmd); + break; } case LFUN_PASTE: - if (hasPasteBuffer()) { - recordUndo(cur, Undo::INSERT); + if (tabularStackDirty() && theClipboard().isInternal()) { + 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); - for (row_type i = rs; i <= re; ++i) + 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); @@ -775,6 +800,8 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd) break; } + // FIXME: this accesses the position cache before it is initialized + //resetPos(cur); InsetTabularMailer(*this).updateDialog(&cur.bv()); } @@ -790,7 +817,7 @@ bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd, 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; } @@ -802,7 +829,7 @@ bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd, } 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; @@ -821,8 +848,13 @@ bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd, 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; @@ -962,6 +994,14 @@ bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd, 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); @@ -974,32 +1014,52 @@ bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd, 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: 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() && theClipboard().isInternal()) { + status.enabled(true); + return true; + } else + return cell(cur.idx())->getStatus(cur, cmd, status); + case LFUN_INSET_MODIFY: if (translate(cmd.getArg(0)) == TABULAR_CODE) { status.enabled(true); @@ -1014,14 +1074,14 @@ bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd, } -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; @@ -1029,14 +1089,7 @@ int InsetTabular::plaintext(Buffer const & buf, ostream & os, } -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; @@ -1084,10 +1137,10 @@ shared_ptr InsetTabular::cell(idx_type idx) } -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()); @@ -1111,33 +1164,31 @@ void InsetTabular::cursorPos } x += tabular.getBeginningOfTextInCell(idx); x += ADD_TO_TABULAR_WIDTH; - x += scroll(); + x += scx_; } -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 @@ -1153,7 +1204,7 @@ InsetBase * InsetTabular::editXY(LCursor & cur, int x, int y) //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); } @@ -1161,19 +1212,18 @@ InsetBase * InsetTabular::editXY(LCursor & cur, int x, int 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::max(); - for (idx_type i = 0; i < nargs(); ++i) { - if (theCoords.getInsets().has(tabular.getCellInset(i).get())) { - int const d = dist(i, x, y); + for (idx_type i = 0, n = nargs(); i != n; ++i) { + 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; @@ -1204,25 +1254,23 @@ void InsetTabular::resetPos(LCursor & cur) const int const maxwidth = bv.workWidth(); if (&cur.inset() != this) { - //scx = 0; + scx_ = 0; } else { 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 = 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(); - - InsetTabularMailer(*this).updateDialog(&bv); + cur.updateFlags(Update::Force | Update::FitCursor); } @@ -1271,7 +1319,9 @@ void InsetTabular::movePrevCell(LCursor & cur) } cur.pit() = cur.lastpit(); cur.pos() = cur.lastpos(); - resetPos(cur); + + // FIXME: this accesses the position cache before it is initialized + //resetPos(cur); } @@ -1375,7 +1425,7 @@ void InsetTabular::tabularFeatures(LCursor & 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()); @@ -1387,23 +1437,20 @@ void InsetTabular::tabularFeatures(LCursor & cur, 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: case LyXTabular::SET_SPECIAL_MULTI: - tabular.setAlignSpecial(cur.idx(),value,feature); + tabular.setAlignSpecial(cur.idx(), from_utf8(value), feature); break; case LyXTabular::APPEND_ROW: @@ -1439,6 +1486,15 @@ void InsetTabular::tabularFeatures(LCursor & cur, 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: { @@ -1525,8 +1581,9 @@ void InsetTabular::tabularFeatures(LCursor & cur, #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()) { @@ -1635,12 +1692,72 @@ void InsetTabular::tabularFeatures(LCursor & cur, 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; } - - InsetTabularMailer(*this).updateDialog(&bv); } @@ -1657,13 +1774,6 @@ void InsetTabular::openLayoutDialog(BufferView * bv) const } -void InsetTabular::getLabelList(Buffer const & buffer, - vector & list) const -{ - tabular.getLabelList(buffer, list); -} - - bool InsetTabular::copySelection(LCursor & cur) { if (!cur.selection()) @@ -1697,10 +1807,18 @@ bool InsetTabular::copySelection(LCursor & cur) 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()); + // Needed for the "Edit->Paste recent" menu and the system clipboard. + cap::copySelection(cur, 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. + // This must be called after cap::copySelection. + dirtyTabularStack(true); + return true; } @@ -1731,7 +1849,9 @@ bool InsetTabular::pasteSelection(LCursor & cur) shared_ptr 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; } } @@ -1744,17 +1864,28 @@ void InsetTabular::cutSelection(LCursor & cur) 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 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(); + theSelection().haveSelection(false); } @@ -1762,9 +1893,9 @@ bool InsetTabular::isRightToLeft(LCursor & cur) const { 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(); } @@ -1789,62 +1920,55 @@ void InsetTabular::getSelection(LCursor & cur, } -size_t InsetTabular::nargs() const +LyXText * InsetTabular::getText(int idx) const { - return tabular.getNumberOfCells(); + return size_t(idx) < nargs() ? cell(idx)->getText(0) : 0; } -LyXText * InsetTabular::getText(int idx) const +void InsetTabular::setChange(Change const & change) { - return size_t(idx) < nargs() ? cell(idx)->getText(0) : 0; + for (idx_type idx = 0; idx < nargs(); ++idx) + cell(idx)->setChange(change); } -void InsetTabular::markErased() +void InsetTabular::acceptChanges() { for (idx_type idx = 0; idx < nargs(); ++idx) - cell(idx)->markErased(); + cell(idx)->acceptChanges(); } -bool InsetTabular::forceDefaultParagraphs(InsetBase const *) const +void InsetTabular::rejectChanges() { -#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(); + for (idx_type idx = 0; idx < nargs(); ++idx) + cell(idx)->rejectChanges(); +} - // 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; +bool InsetTabular::forceDefaultParagraphs(idx_type cell) const +{ + return tabular.getPWidth(cell).zero(); } -bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf, +bool InsetTabular::insertPlaintextString(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; @@ -1865,9 +1989,10 @@ bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf, 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(); @@ -1875,7 +2000,7 @@ bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf, 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; @@ -1883,7 +2008,7 @@ bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf, 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; @@ -1893,8 +2018,9 @@ bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf, if (cols < columns) { shared_ptr 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; } @@ -1904,8 +2030,9 @@ bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf, if (cols < columns) { shared_ptr 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; @@ -1920,8 +2047,9 @@ bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf, if (cell < cells && op < len) { shared_ptr 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; } @@ -1973,14 +2101,14 @@ void InsetTabularMailer::string2params(string const & in, InsetTabular & inset) 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); @@ -1995,3 +2123,6 @@ string const InsetTabularMailer::params2string(InsetTabular const & inset) data << "\\end_inset\n"; return data.str(); } + + +} // namespace lyx