X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsettabular.C;h=fd5c283bf5ec97c75b41791d0ca0e9d53f7248d0;hb=4acce5c117e0d6101113f38e2e058d284b866de9;hp=e8351e5cae793449960d776a40c5f1d4aacbc8c7;hpb=79ae54d4c018e4d9600d6d09d3ff22fd4505baab;p=lyx.git diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index e8351e5cae..fd5c283bf5 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -37,7 +37,7 @@ #include "frontends/LyXView.h" #include "frontends/Painter.h" -#include "support/std_sstream.h" +#include #include using lyx::graphics::PreviewLoader; @@ -46,14 +46,15 @@ using lyx::support::ltrim; using lyx::support::strToInt; using lyx::support::strToDbl; +using std::auto_ptr; using std::endl; using std::max; -using std::swap; using std::string; -using std::auto_ptr; using std::istringstream; using std::ostream; using std::ostringstream; +using std::swap; +using std::vector; namespace { @@ -120,10 +121,12 @@ TabularFeature tabularFeature[] = { LyXTabular::LAST_ACTION, "" } }; -struct FindFeature { - FindFeature(LyXTabular::Feature feature) : feature_(feature) {} - bool operator()(TabularFeature & tf) - { + +class FeatureEqual : public std::unary_function { +public: + FeatureEqual(LyXTabular::Feature feature) + : feature_(feature) {} + bool operator()(TabularFeature const & tf) const { return tf.action == feature_; } private: @@ -135,10 +138,10 @@ private: string const featureAsString(LyXTabular::Feature feature) { - TabularFeature * it = tabularFeature; - TabularFeature * end = it + + TabularFeature * end = tabularFeature + sizeof(tabularFeature) / sizeof(TabularFeature); - it = std::find_if(it, end, FindFeature(feature)); + TabularFeature * it = std::find_if(tabularFeature, end, + FeatureEqual(feature)); return (it == end) ? string() : it->feature; } @@ -151,28 +154,14 @@ bool InsetTabular::hasPasteBuffer() const InsetTabular::InsetTabular(Buffer const & buf, int rows, int columns) : tabular(buf.params(), max(rows, 1), max(columns, 1)), - buffer_(&buf), cursorx_(0), cursory_(0) -{ - tabular.setOwner(this); - the_locking_inset = 0; - actrow = 0; - actcell = 0; - clearSelection(); - in_reset_pos = 0; -} + buffer_(&buf), cursorx_(0) +{} InsetTabular::InsetTabular(InsetTabular const & tab) : UpdatableInset(tab), tabular(tab.tabular), - buffer_(tab.buffer_), cursorx_(0), cursory_(0) -{ - tabular.setOwner(this); - the_locking_inset = 0; - actrow = 0; - actcell = 0; - clearSelection(); - in_reset_pos = 0; -} + buffer_(tab.buffer_), cursorx_(0) +{} InsetTabular::~InsetTabular() @@ -193,7 +182,7 @@ Buffer const & InsetTabular::buffer() const } -void InsetTabular::buffer(Buffer * b) +void InsetTabular::buffer(Buffer const * b) { buffer_ = b; } @@ -215,10 +204,10 @@ void InsetTabular::read(Buffer const & buf, LyXLex & lex) if (old_format) return; - lex.nextToken(); + lex.next(); string token = lex.getString(); while (lex.isOK() && (token != "\\end_inset")) { - lex.nextToken(); + lex.next(); token = lex.getString(); } if (token != "\\end_inset") { @@ -237,7 +226,27 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const BOOST_ASSERT(false); } - calculate_dimensions_of_cells(mi); + for (int i = 0, cell = -1; i < tabular.rows(); ++i) { + int maxAsc = 0; + int maxDesc = 0; + for (int j = 0; j < tabular.columns(); ++j) { + if (tabular.isPartOfMultiColumn(i, j)) + continue; + ++cell; + Dimension dim; + MetricsInfo m = mi; + LyXLength 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); + maxAsc = max(maxAsc, dim.asc); + maxDesc = max(maxDesc, dim.des); + tabular.setWidthOfCell(cell, dim.wid); + } + tabular.setAscentOfRow(i, maxAsc + ADD_TO_HEIGHT); + tabular.setDescentOfRow(i, maxDesc + ADD_TO_HEIGHT); + } dim.asc = tabular.getAscentOfRow(0); dim.des = tabular.getHeightOfTabular() - tabular.getAscentOfRow(0) + 1; @@ -251,25 +260,21 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const //lyxerr << "InsetTabular::draw: " << x << " " << y << endl; BufferView * bv = pi.base.bv; + setPosCache(pi, x, y); - if (!owner()) - x += scroll(); - - xo_ = x; - yo_ = y; + x += scroll(); x += ADD_TO_TABULAR_WIDTH; - int cell = 0; + int idx = 0; first_visible_cell = -1; for (int i = 0; i < tabular.rows(); ++i) { int nx = x; - cell = tabular.getCellNumber(i, 0); - if (y + tabular.getDescentOfRow(i) <= 0 && - y - tabular.getAscentOfRow(i) < pi.pain.paperHeight()) - { - y += tabular.getDescentOfRow(i) + - tabular.getAscentOfRow(i + 1) + - tabular.getAdditionalHeight(i + 1); + idx = tabular.getCellNumber(i, 0); + if (y + tabular.getDescentOfRow(i) <= 0 + && y - tabular.getAscentOfRow(i) < pi.pain.paperHeight()) { + y += tabular.getDescentOfRow(i) + + tabular.getAscentOfRow(i + 1) + + tabular.getAdditionalHeight(i + 1); continue; } for (int j = 0; j < tabular.columns(); ++j) { @@ -277,17 +282,16 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const break; if (tabular.isPartOfMultiColumn(i, j)) continue; - int cx = nx + tabular.getBeginningOfTextInCell(cell); if (first_visible_cell < 0) - first_visible_cell = cell; - if (hasSelection()) { - drawCellSelection(pi.pain, nx, y, i, j, cell); - } - - tabular.getCellInset(cell).draw(pi, cx, y); - drawCellLines(pi.pain, nx, y, i, cell); - nx += tabular.getWidthOfColumn(cell); - ++cell; + first_visible_cell = idx; + if (bv->cursor().selection()) + drawCellSelection(pi, nx, y, i, j, idx); + + int const cx = nx + tabular.getBeginningOfTextInCell(idx); + cell(idx).draw(pi, cx, y); + drawCellLines(pi.pain, nx, y, i, idx); + nx += tabular.getWidthOfColumn(idx); + ++idx; } // Would be nice, but for some completely unfathomable reason, @@ -343,29 +347,20 @@ void InsetTabular::drawCellLines(Painter & pain, int x, int y, } -void InsetTabular::drawCellSelection(Painter & pain, int x, int y, +void InsetTabular::drawCellSelection(PainterInfo & pi, int x, int y, int row, int column, int cell) const { - BOOST_ASSERT(hasSelection()); - int cs = tabular.column_of_cell(sel_cell_start); - int ce = tabular.column_of_cell(sel_cell_end); - if (cs > ce) { - ce = cs; - cs = tabular.column_of_cell(sel_cell_end); - } else { - ce = tabular.right_column_of_cell(sel_cell_end); - } - - int rs = tabular.row_of_cell(sel_cell_start); - int re = tabular.row_of_cell(sel_cell_end); - if (rs > re) - swap(rs, re); - - if ((column >= cs) && (column <= ce) && (row >= rs) && (row <= re)) { - int w = tabular.getWidthOfColumn(cell); - int h = tabular.getAscentOfRow(row) + tabular.getDescentOfRow(row)-1; - pain.fillRectangle(x, y - tabular.getAscentOfRow(row) + 1, - w, h, LColor::selection); + LCursor & cur = pi.base.bv->cursor(); + BOOST_ASSERT(cur.selection()); + if (tablemode(cur)) { + int rs, re, cs, ce; + getSelection(cur, rs, re, cs, ce); + if (column >= cs && column <= ce && row >= rs && row <= re) { + int w = tabular.getWidthOfColumn(cell); + int h = tabular.getAscentOfRow(row) + tabular.getDescentOfRow(row)-1; + pi.pain.fillRectangle(x, y - tabular.getAscentOfRow(row) + 1, + w, h, LColor::selection); + } } } @@ -376,448 +371,307 @@ string const InsetTabular::editMessage() const } -void InsetTabular::updateLocal(BufferView * bv) const -{ - bv->update(); - resetPos(bv); -} - - -int InsetTabular::insetInInsetY() const -{ - if (the_locking_inset) - return cursory_ + the_locking_inset->insetInInsetY(); - return 0; -} - - -bool InsetTabular::insertInset(BufferView * bv, InsetOld * inset) -{ - return the_locking_inset && the_locking_inset->insertInset(bv, inset); -} - - -void InsetTabular::lfunMousePress(FuncRequest const & cmd) -{ - if (hasSelection() && cmd.button() == mouse_button::button3) - return; - - if (hasSelection()) - clearSelection(); - - BufferView * bv = cmd.view(); - - the_locking_inset = 0; - setPos(bv, cmd.x, cmd.y); - clearSelection(); - the_locking_inset = 0; - - if (cmd.button() == mouse_button::button2) - dispatch(FuncRequest(bv, LFUN_PASTESELECTION, "paragraph")); -} - - -void InsetTabular::lfunMouseRelease(FuncRequest const & cmd) -{ - if (cmd.button() == mouse_button::button3) - InsetTabularMailer(*this).showDialog(cmd.view()); -} - - -void InsetTabular::lfunMouseMotion(FuncRequest const & cmd) -{ - BufferView * bv = cmd.view(); - int const old_cell = actcell; - - setPos(bv, cmd.x, cmd.y); - if (!hasSelection()) - setSelection(actcell, actcell); - else if (old_cell != actcell) - setSelection(sel_cell_start, actcell); -} - - -void InsetTabular::edit(BufferView * bv, bool left) +void InsetTabular::edit(LCursor & cur, bool left) { - lyxerr << "InsetTabular::edit: " << this - << " first text: " << tabular.cell_info[0][0].inset.getText(0) - << " first cell: " << &tabular.cell_info[0][0].inset << endl; - + lyxerr << "InsetTabular::edit: " << this << endl; finishUndo(); - the_locking_inset = 0; - + int cell; + cur.push(*this); if (left) { - if (isRightToLeft(bv)) - actcell = tabular.getLastCellInRow(0); + if (isRightToLeft(cur)) + cell = tabular.getLastCellInRow(0); else - actcell = 0; + cell = 0; } else { - if (isRightToLeft(bv)) - actcell = tabular.getFirstCellInRow(tabular.rows()-1); + if (isRightToLeft(cur)) + cell = tabular.getFirstCellInRow(tabular.rows()-1); else - actcell = tabular.getNumberOfCells() - 1; + cell = tabular.getNumberOfCells() - 1; } - clearSelection(); - resetPos(bv); - bv->fitCursor(); - bv->cursor().push(this); + cur.selection() = false; + // this accesses the position cache before it is initialized + //resetPos(cur); + //cur.bv().fitCursor(); + cur.idx() = cell; } -void InsetTabular::edit(BufferView * bv, int x, int y) +InsetBase * InsetTabular::editXY(LCursor & cur, int x, int y) const { - lyxerr << "InsetTabular::edit: " << this << " first cell " - << &tabular.cell_info[0][0].inset << endl; - - finishUndo(); - the_locking_inset = 0; - setPos(bv, x, y); - clearSelection(); - finishUndo(); - int xx = cursorx_ - xo_ + tabular.getBeginningOfTextInCell(actcell); - bv->cursor().push(this); - if (x > xx) - activateCellInset(bv, x - xx, y - cursory_); + //lyxerr << "InsetTabular::editXY: " << this << endl; + cur.selection() = false; + cur.push(const_cast(*this)); + return setPos(cur, x, y); + //int xx = cursorx_ - xo() + tabular.getBeginningOfTextInCell(actcell); } -DispatchResult -InsetTabular::priv_dispatch(FuncRequest const & cmd, idx_type &, pos_type &) +void InsetTabular::priv_dispatch(LCursor & cur, FuncRequest & cmd) { - lyxerr << "InsetTabular::dispatch: " << cmd << endl; - // We need to save the value of the_locking_inset as the call to - // the_locking_inset->localDispatch might unlock it. - DispatchResult result(true, true); - BufferView * bv = cmd.view(); - bool hs = hasSelection(); + lyxerr << "# InsetTabular::dispatch: cmd: " << cmd << endl; + //lyxerr << " cur:\n" << cur << endl; + CursorSlice sl = cur.top(); + LCursor & bvcur = cur.bv().cursor(); switch (cmd.action) { case LFUN_MOUSE_PRESS: - lfunMousePress(cmd); - return DispatchResult(true, true); + lyxerr << "# InsetTabular::MousePress\n" << cur.bv().cursor() << endl; - case LFUN_MOUSE_MOTION: - lfunMouseMotion(cmd); - return DispatchResult(true, true); + if (cmd.button() == mouse_button::button1) { + cur.selection() = false; + setPos(cur, cmd.x, cmd.y); + cur.resetAnchor(); + bvcur = cur; + break; + } - case LFUN_MOUSE_RELEASE: - lfunMouseRelease(cmd); - return DispatchResult(true, true); + //if (cmd.button() == mouse_button::button2) + // dispatch(cur, FuncRequest(LFUN_PASTESELECTION, "paragraph")); - case LFUN_CELL_BACKWARD: - case LFUN_CELL_FORWARD: - if (cmd.action == LFUN_CELL_FORWARD) - moveNextCell(bv, the_locking_inset != 0); - else - movePrevCell(bv, the_locking_inset != 0); - clearSelection(); - if (!the_locking_inset) - return DispatchResult(true); - return result; + // we'll pop up the table dialog on release + if (cmd.button() == mouse_button::button3) + break; + break; - case LFUN_SCROLL_INSET: - if (!cmd.argument.empty()) { - if (cmd.argument.find('.') != cmd.argument.npos) - scroll(cmd.view(), static_cast(strToDbl(cmd.argument))); - else - scroll(cmd.view(), strToInt(cmd.argument)); - cmd.view()->update(); - return DispatchResult(true, true); + case LFUN_MOUSE_MOTION: + lyxerr << "# InsetTabular::MouseMotion\n" << bvcur << endl; + if (cmd.button() == mouse_button::button1) { + // only accept motions to places not deeper nested than the real anchor + if (bvcur.anchor_.hasPart(cur)) { + setPos(cur, cmd.x, cmd.y); + bvcur.setCursor(cur); + bvcur.selection() = true; + } } + break; - case LFUN_RIGHTSEL: { - int const start = hasSelection() ? sel_cell_start : actcell; - if (tabular.isLastCellInRow(actcell)) { - setSelection(start, actcell); - break; - } + case LFUN_MOUSE_RELEASE: + lyxerr << "# InsetTabular::MouseRelease\n" << bvcur << endl; + if (cmd.button() == mouse_button::button3) + InsetTabularMailer(*this).showDialog(&cur.bv()); + break; - int end = actcell; - // if we are starting a selection, only select - // the current cell at the beginning - if (hasSelection()) { - moveRight(bv, false); - end = actcell; - } - setSelection(start, end); + case LFUN_CELL_BACKWARD: + movePrevCell(cur); + cur.selection() = false; break; - } - case LFUN_RIGHT: - result = moveRight(bv, true); - clearSelection(); + case LFUN_CELL_FORWARD: + moveNextCell(cur); + cur.selection() = false; break; - case LFUN_LEFTSEL: { - int const start = hasSelection() ? sel_cell_start : actcell; - if (tabular.isFirstCellInRow(actcell)) { - setSelection(start, actcell); + case LFUN_SCROLL_INSET: + if (cmd.argument.empty()) break; - } + if (cmd.argument.find('.') != cmd.argument.npos) + scroll(cur.bv(), static_cast(strToDbl(cmd.argument))); + else + scroll(cur.bv(), strToInt(cmd.argument)); + break; - int end = actcell; - // if we are starting a selection, only select - // the current cell at the beginning - if (hasSelection()) { - moveLeft(bv, false); - end = actcell; + case LFUN_RIGHTSEL: + case LFUN_RIGHT: + cell(cur.idx()).dispatch(cur, cmd); + cur.dispatched(); // override the cell's decision + if (sl == cur.top()) + isRightToLeft(cur) ? movePrevCell(cur) : moveNextCell(cur); + if (sl == cur.top()) { + cmd = FuncRequest(LFUN_FINISHED_RIGHT); + cur.undispatched(); } - setSelection(start, end); break; - } + case LFUN_LEFTSEL: case LFUN_LEFT: - result = moveLeft(bv, true); - clearSelection(); - break; - - case LFUN_DOWNSEL: { - int const start = hasSelection() ? sel_cell_start : actcell; - int const ocell = actcell; - // if we are starting a selection, only select - // the current cell at the beginning - if (hasSelection()) { - moveDown(bv, false); - if (ocell == sel_cell_end || - tabular.column_of_cell(ocell) > tabular.column_of_cell(actcell)) - setSelection(start, tabular.getCellBelow(sel_cell_end)); - else - setSelection(start, tabular.getLastCellBelow(sel_cell_end)); - } else { - setSelection(start, start); + cell(cur.idx()).dispatch(cur, cmd); + cur.dispatched(); // override the cell's decision + if (sl == cur.top()) + isRightToLeft(cur) ? moveNextCell(cur) : movePrevCell(cur); + if (sl == cur.top()) { + cmd = FuncRequest(LFUN_FINISHED_LEFT); + cur.undispatched(); } break; - } + case LFUN_DOWNSEL: case LFUN_DOWN: - result = moveDown(bv, the_locking_inset != 0); - clearSelection(); - break; - - case LFUN_UPSEL: { - int const start = hasSelection() ? sel_cell_start : actcell; - int const ocell = actcell; - // if we are starting a selection, only select - // the current cell at the beginning - if (hasSelection()) { - moveUp(bv, false); - if (ocell == sel_cell_end || - tabular.column_of_cell(ocell) > tabular.column_of_cell(actcell)) - setSelection(start, tabular.getCellAbove(sel_cell_end)); - else - setSelection(start, tabular.getLastCellAbove(sel_cell_end)); - } else { - setSelection(start, start); + cell(cur.idx()).dispatch(cur, cmd); + cur.dispatched(); // override the cell's decision + if (sl == cur.top()) + if (tabular.row_of_cell(cur.idx()) != tabular.rows() - 1) { + cur.idx() = tabular.getCellBelow(cur.idx()); + cur.par() = 0; + cur.pos() = 0; + resetPos(cur); + } + if (sl == cur.top()) { + cmd = FuncRequest(LFUN_FINISHED_DOWN); + cur.undispatched(); } break; - } + case LFUN_UPSEL: case LFUN_UP: - result = moveUp(bv, the_locking_inset != 0); - clearSelection(); + cell(cur.idx()).dispatch(cur, cmd); + cur.dispatched(); // override the cell's decision + if (sl == cur.top()) + if (tabular.row_of_cell(cur.idx()) != 0) { + cur.idx() = tabular.getCellAbove(cur.idx()); + cur.par() = cur.lastpar(); + cur.pos() = cur.lastpos(); + resetPos(cur); + } + if (sl == cur.top()) { + cmd = FuncRequest(LFUN_FINISHED_UP); + cur.undispatched(); + } break; case LFUN_NEXT: { - if (hs) - clearSelection(); + //if (hasSelection()) + // cur.selection() = false; + int actcell = cur.idx(); + int actcol = tabular.column_of_cell(actcell); int column = actcol; - if (bv->top_y() + bv->painter().paperHeight() - < yo_ + tabular.getHeightOfTabular()) + if (cur.bv().top_y() + cur.bv().painter().paperHeight() + < yo() + tabular.getHeightOfTabular()) { - bv->scrollDocView(bv->top_y() + bv->painter().paperHeight()); - actcell = tabular.getCellBelow(first_visible_cell) + column; + cur.bv().scrollDocView( + cur.bv().top_y() + cur.bv().painter().paperHeight()); + cur.idx() = tabular.getCellBelow(first_visible_cell) + column; } else { - actcell = tabular.getFirstCellInRow(tabular.rows() - 1) + column; + cur.idx() = tabular.getFirstCellInRow(tabular.rows() - 1) + column; } - resetPos(bv); + resetPos(cur); break; } case LFUN_PRIOR: { - if (hs) - clearSelection(); - int column = actcol; - if (yo_ < 0) { - bv->scrollDocView(bv->top_y() - bv->painter().paperHeight()); - if (yo_ > 0) - actcell = column; + //if (hasSelection()) + // cur.selection() = false; + int column = tabular.column_of_cell(cur.idx()); + if (yo() < 0) { + cur.bv().scrollDocView( + cur.bv().top_y() - cur.bv().painter().paperHeight()); + if (yo() > 0) + cur.idx() = column; else - actcell = tabular.getCellBelow(first_visible_cell) + column; + cur.idx() = tabular.getCellBelow(first_visible_cell) + column; } else { - actcell = column; + cur.idx() = column; } - resetPos(bv); + resetPos(cur); break; } - // none of these make sense for insettabular, - // but we must catch them to prevent any - // selection from being confused - case LFUN_PRIORSEL: - case LFUN_NEXTSEL: - case LFUN_WORDLEFT: - case LFUN_WORDLEFTSEL: - case LFUN_WORDRIGHT: - case LFUN_WORDRIGHTSEL: - case LFUN_WORDSEL: - case LFUN_DOWN_PARAGRAPH: - case LFUN_DOWN_PARAGRAPHSEL: - case LFUN_UP_PARAGRAPH: - case LFUN_UP_PARAGRAPHSEL: - case LFUN_BACKSPACE: - case LFUN_HOME: - case LFUN_HOMESEL: - case LFUN_END: - case LFUN_ENDSEL: - case LFUN_BEGINNINGBUF: - case LFUN_BEGINNINGBUFSEL: - case LFUN_ENDBUF: - case LFUN_ENDBUFSEL: - break; - case LFUN_LAYOUT_TABULAR: - InsetTabularMailer(*this).showDialog(bv); + InsetTabularMailer(*this).showDialog(&cur.bv()); break; case LFUN_INSET_DIALOG_UPDATE: - InsetTabularMailer(*this).updateDialog(bv); + InsetTabularMailer(*this).updateDialog(&cur.bv()); break; case LFUN_TABULAR_FEATURE: - if (!tabularFeatures(bv, cmd.argument)) - result = DispatchResult(false); + if (!tabularFeatures(cur, cmd.argument)) + cur.undispatched(); break; // insert file functions case LFUN_FILE_INSERT_ASCII_PARA: case LFUN_FILE_INSERT_ASCII: { - string tmpstr = getContentsOfAsciiFile(bv, cmd.argument, false); - if (!tmpstr.empty() && !insertAsciiString(bv, tmpstr, false)) - result = DispatchResult(false); + string tmpstr = getContentsOfAsciiFile(&cur.bv(), cmd.argument, false); + if (!tmpstr.empty() && !insertAsciiString(cur.bv(), tmpstr, false)) + cur.undispatched(); break; } - case LFUN_LANGUAGE: - case LFUN_EMPH: - case LFUN_BOLD: - case LFUN_NOUN: - case LFUN_CODE: - case LFUN_SANS: - case LFUN_ROMAN: - case LFUN_DEFAULT: - case LFUN_UNDERLINE: - case LFUN_FONT_SIZE: - lyxerr << "font changes not re-implemented for tables after LOCK" << endl; - break; - - case LFUN_FINISHED_LEFT: - lyxerr << "swallow LFUN_FINISHED_LEFT, act: " << actcell << endl; - if (!movePrevCell(bv, false)) - result = DispatchResult(FINISHED); - break; - - case LFUN_FINISHED_RIGHT: - lyxerr << "swallow LFUN_FINISHED_RIGHT, act: " << actcell << endl; - if (!moveNextCell(bv, false)) - result = DispatchResult(FINISHED_RIGHT); - break; - - case LFUN_FINISHED_UP: - lyxerr << "swallow LFUN_FINISHED_UP, act: " << actcell << endl; - result = moveUp(bv, true); - break; - - case LFUN_FINISHED_DOWN: - lyxerr << "swallow LFUN_FINISHED_DOWN, act: " << actcell << endl; - result = moveDown(bv, true); - break; - case LFUN_CUT: - if (copySelection(bv)) { - recordUndo(bv, Undo::DELETE); - cutSelection(bv->buffer()->params()); + if (copySelection(cur)) { + recordUndo(cur, Undo::DELETE); + cutSelection(cur); } break; + case LFUN_BACKSPACE: case LFUN_DELETE: - recordUndo(bv, Undo::DELETE); - cutSelection(bv->buffer()->params()); + recordUndo(cur, Undo::DELETE); + if (tablemode(cur)) + cutSelection(cur); + else + cell(cur.idx()).dispatch(cur, cmd); break; case LFUN_COPY: - if (!hasSelection()) + if (!cur.selection()) break; finishUndo(); - copySelection(bv); + copySelection(cur); break; case LFUN_PASTESELECTION: { - string const clip = bv->getClipboard(); + string const clip = cur.bv().getClipboard(); if (clip.empty()) break; -#if 0 if (clip.find('\t') != string::npos) { int cols = 1; int rows = 1; int maxCols = 1; - string::size_type len = clip.length(); - string::size_type p = 0; - - while (p < len && - ((p = clip.find_first_of("\t\n", p)) != string::npos)) { + 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) + if (p + 1 < len) ++rows; maxCols = max(cols, maxCols); cols = 1; break; } - ++p; } maxCols = max(cols, maxCols); paste_tabular.reset( - new LyXTabular(bv->buffer()->params(), - this, rows, maxCols) - ); + new LyXTabular(cur.buffer().params(), rows, maxCols)); string::size_type op = 0; int cell = 0; int cells = paste_tabular->getNumberOfCells(); - p = cols = 0; - while ((cell < cells) && (p < len) && - (p = clip.find_first_of("\t\n", p)) != string::npos) { - if (p >= len) + 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)); + 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)); + paste_tabular->getCellInset(cell). + setText(clip.substr(op, p - op), font); while (cols++ < maxCols) ++cell; cols = 0; break; } - ++p; - op = p; + op = p + 1; } // 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)); - } else -#else - if (!insertAsciiString(bv, clip, true)) -#endif - { + 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! @@ -828,36 +682,203 @@ InsetTabular::priv_dispatch(FuncRequest const & cmd, idx_type &, pos_type &) case LFUN_PASTE: if (hasPasteBuffer()) { - recordUndo(bv, Undo::INSERT); - pasteSelection(bv); + recordUndo(cur, Undo::INSERT); + pasteSelection(cur); break; } - // fall through - - // ATTENTION: the function above has to be PASTE and PASTESELECTION!!! + cell(cur.idx()).dispatch(cur, cmd); + break; default: - // handle font changing stuff on selection before we lock the inset - // in the default part! - result = DispatchResult(false); - // we try to activate the actual inset and put this event down to - // the insets dispatch function. - if (!the_locking_inset && activateCellInset(bv)) { - result = the_locking_inset->dispatch(cmd); - if (!result.dispatched()) { - // we need to update if this was requested before - result = DispatchResult(false); + // we try to handle this event in the insets dispatch function. + cell(cur.idx()).dispatch(cur, cmd); + break; + } + + InsetTabularMailer(*this).updateDialog(&cur.bv()); +} + + +// function sets an object as defined in func_status.h: +// states OK, Unknown, Disabled, On, Off. +bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd, + FuncStatus & status) const +{ + switch (cmd.action) { + case LFUN_TABULAR_FEATURE: { + int actcell = cur.idx(); + int action = LyXTabular::LAST_ACTION; + 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())) { + action = tabularFeature[i].action; break; } - if (hs) - clearSelection(); } - break; + if (action == LyXTabular::LAST_ACTION) { + status.clear(); + status.unknown(true); + return true; + } + + string const argument + = ltrim(cmd.argument.substr(tabularFeature[i].feature.length())); + + int sel_row_start = 0; + int sel_row_end = 0; + int dummy; + LyXTabular::ltType dummyltt; + bool flag = true; + + getSelection(cur, sel_row_start, sel_row_end, dummy, dummy); + + switch (action) { + case LyXTabular::SET_PWIDTH: + case LyXTabular::SET_MPWIDTH: + case LyXTabular::SET_SPECIAL_COLUMN: + case LyXTabular::SET_SPECIAL_MULTI: + case LyXTabular::APPEND_ROW: + case LyXTabular::APPEND_COLUMN: + case LyXTabular::DELETE_ROW: + case LyXTabular::DELETE_COLUMN: + case LyXTabular::SET_ALL_LINES: + case LyXTabular::UNSET_ALL_LINES: + status.clear(); + return true; + + case LyXTabular::MULTICOLUMN: + status.setOnOff(tabular.isMultiColumn(actcell)); + break; + + case LyXTabular::M_TOGGLE_LINE_TOP: + flag = false; + case LyXTabular::TOGGLE_LINE_TOP: + status.setOnOff(tabular.topLine(actcell, flag)); + break; + + case LyXTabular::M_TOGGLE_LINE_BOTTOM: + flag = false; + case LyXTabular::TOGGLE_LINE_BOTTOM: + status.setOnOff(tabular.bottomLine(actcell, flag)); + break; + + case LyXTabular::M_TOGGLE_LINE_LEFT: + flag = false; + case LyXTabular::TOGGLE_LINE_LEFT: + status.setOnOff(tabular.leftLine(actcell, flag)); + break; + + case LyXTabular::M_TOGGLE_LINE_RIGHT: + flag = false; + case LyXTabular::TOGGLE_LINE_RIGHT: + status.setOnOff(tabular.rightLine(actcell, flag)); + break; + + case LyXTabular::M_ALIGN_LEFT: + flag = false; + case LyXTabular::ALIGN_LEFT: + status.setOnOff(tabular.getAlignment(actcell, flag) == LYX_ALIGN_LEFT); + break; + + case LyXTabular::M_ALIGN_RIGHT: + flag = false; + case LyXTabular::ALIGN_RIGHT: + status.setOnOff(tabular.getAlignment(actcell, flag) == LYX_ALIGN_RIGHT); + break; + + case LyXTabular::M_ALIGN_CENTER: + flag = false; + case LyXTabular::ALIGN_CENTER: + status.setOnOff(tabular.getAlignment(actcell, flag) == LYX_ALIGN_CENTER); + break; + + case LyXTabular::ALIGN_BLOCK: + status.enabled(!tabular.getPWidth(actcell).zero()); + status.setOnOff(tabular.getAlignment(actcell, flag) == LYX_ALIGN_BLOCK); + break; + + case LyXTabular::M_VALIGN_TOP: + flag = false; + case LyXTabular::VALIGN_TOP: + status.setOnOff( + tabular.getVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_TOP); + break; + + case LyXTabular::M_VALIGN_BOTTOM: + flag = false; + case LyXTabular::VALIGN_BOTTOM: + status.setOnOff( + tabular.getVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_BOTTOM); + break; + + case LyXTabular::M_VALIGN_MIDDLE: + flag = false; + case LyXTabular::VALIGN_MIDDLE: + status.setOnOff( + tabular.getVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_MIDDLE); + break; + + case LyXTabular::SET_LONGTABULAR: + status.setOnOff(tabular.isLongTabular()); + break; + + case LyXTabular::UNSET_LONGTABULAR: + status.setOnOff(!tabular.isLongTabular()); + break; + + case LyXTabular::SET_ROTATE_TABULAR: + status.setOnOff(tabular.getRotateTabular()); + break; + + case LyXTabular::UNSET_ROTATE_TABULAR: + status.setOnOff(!tabular.getRotateTabular()); + break; + + case LyXTabular::SET_ROTATE_CELL: + status.setOnOff(tabular.getRotateCell(actcell)); + break; + + case LyXTabular::UNSET_ROTATE_CELL: + status.setOnOff(!tabular.getRotateCell(actcell)); + break; + + case LyXTabular::SET_USEBOX: + status.setOnOff(strToInt(argument) == tabular.getUsebox(actcell)); + break; + + case LyXTabular::SET_LTFIRSTHEAD: + status.setOnOff(tabular.getRowOfLTHead(sel_row_start, dummyltt)); + break; + + case LyXTabular::SET_LTHEAD: + status.setOnOff(tabular.getRowOfLTHead(sel_row_start, dummyltt)); + break; + + case LyXTabular::SET_LTFOOT: + status.setOnOff(tabular.getRowOfLTFoot(sel_row_start, dummyltt)); + break; + + case LyXTabular::SET_LTLASTFOOT: + status.setOnOff(tabular.getRowOfLTFoot(sel_row_start, dummyltt)); + break; + + case LyXTabular::SET_LTNEWPAGE: + status.setOnOff(tabular.getLTNewPage(sel_row_start)); + break; + + default: + status.clear(); + status.enabled(false); + break; + } + return true; } - updateLocal(bv); - InsetTabularMailer(*this).updateDialog(bv); - return result; + default: + // we try to handle this event in the insets dispatch function. + return cell(cur.idx()).getStatus(cur, cmd, status); + } } @@ -871,7 +892,7 @@ int InsetTabular::latex(Buffer const & buf, ostream & os, int InsetTabular::plaintext(Buffer const & buf, ostream & os, OutputParams const & runparams) const { - int dp = runparams.linelen ? ownerPar(buf, this).params().depth() : 0; + int dp = runparams.linelen ? runparams.depth : 0; return tabular.plaintext(buf, os, runparams, dp, false, 0); } @@ -887,13 +908,18 @@ int InsetTabular::docbook(Buffer const & buf, ostream & os, OutputParams const & runparams) const { int ret = 0; - InsetOld * master; + InsetOld * master = 0; +#ifdef WITH_WARNINGS +#warning Why not pass a proper DocIterator here? +#endif +#if 0 // if the table is inside a float it doesn't need the informaltable // wrapper. Search for it. - for (master = owner(); - master && master->lyxCode() != InsetOld::FLOAT_CODE; - master = master->owner()); + for (master = owner(); master; master = master->owner()) + if (master->lyxCode() == InsetOld::FLOAT_CODE) + break; +#endif if (!master) { os << ""; @@ -918,89 +944,40 @@ void InsetTabular::validate(LaTeXFeatures & features) const } -void InsetTabular::calculate_dimensions_of_cells(MetricsInfo & mi) const +InsetText const & InsetTabular::cell(int idx) const { -#if 1 - // if we have a locking_inset we should have to check only this cell for - // change so I'll try this to have a boost, but who knows ;) (Jug?) - // This is _really_ important (André) - if (the_locking_inset == &tabular.getCellInset(actcell)) { - int maxAsc = 0; - int maxDesc = 0; - for (int j = 0; j < tabular.columns(); ++j) { - Dimension dim; - MetricsInfo m = mi; - m.base.textwidth = - tabular.column_info[j].p_width.inPixels(mi.base.textwidth); - tabular.getCellInset(actrow, j).metrics(m, dim); - maxAsc = max(dim.asc, maxAsc); - maxDesc = max(dim.des, maxDesc); - } - tabular.setWidthOfCell(actcell, the_locking_inset->width()); - tabular.setAscentOfRow(actrow, maxAsc + ADD_TO_HEIGHT); - tabular.setDescentOfRow(actrow, maxDesc + ADD_TO_HEIGHT); - return; - } -#endif - - int cell = -1; - for (int i = 0; i < tabular.rows(); ++i) { - int maxAsc = 0; - int maxDesc = 0; - for (int j = 0; j < tabular.columns(); ++j) { - if (tabular.isPartOfMultiColumn(i, j)) - continue; - ++cell; - Dimension dim; - MetricsInfo m = mi; - m.base.textwidth = - tabular.column_info[j].p_width.inPixels(mi.base.textwidth); - tabular.getCellInset(cell).metrics(m, dim); - maxAsc = max(maxAsc, dim.asc); - maxDesc = max(maxDesc, dim.des); - tabular.setWidthOfCell(cell, dim.wid); - } - tabular.setAscentOfRow(i, maxAsc + ADD_TO_HEIGHT); - tabular.setDescentOfRow(i, maxDesc + ADD_TO_HEIGHT); - } + return tabular.getCellInset(idx); } -void InsetTabular::getCursorPos(BufferView *, int & x, int & y) const +InsetText & InsetTabular::cell(int idx) { - x = TEXT_TO_INSET_OFFSET + cursorx_ - xo_; - y = TEXT_TO_INSET_OFFSET + cursory_; + return tabular.getCellInset(idx); } -void InsetTabular::setPos(BufferView * bv, int x, int y) const +void InsetTabular::getCursorPos(LCursor const & cur, int & x, int & y) const { - cursory_ = 0; - actcell = 0; - actrow = 0; - actcol = 0; - int ly = tabular.getDescentOfRow(actrow); - - // first search the right row - while (ly < y && actrow + 1 < tabular.rows()) { - cursory_ += tabular.getDescentOfRow(actrow) + - tabular.getAscentOfRow(actrow + 1) + - tabular.getAdditionalHeight(actrow + 1); - ++actrow; - ly = cursory_ + tabular.getDescentOfRow(actrow); - } - actcell = tabular.getCellNumber(actrow, actcol); - - // now search the right column - int lx = tabular.getWidthOfColumn(actcell) - - tabular.getAdditionalWidth(actcell); + cell(cur.idx()).getCursorPos(cur, x, y); +} - for (; !tabular.isLastCellInRow(actcell) && lx < x; ++actcell) - lx += tabular.getWidthOfColumn(actcell + 1) - + tabular.getAdditionalWidth(actcell); - cursorx_ = lx - tabular.getWidthOfColumn(actcell) + xo_ + 2; - resetPos(bv); +InsetBase * InsetTabular::setPos(LCursor & cur, int x, int y) const +{ + lyxerr << "# InsetTabular::setPos() x=" << x << " y=" << y << endl; + int idx_min = 0; + int dist_min = 1000000; + for (idx_type i = 0; i < nargs(); ++i) { + int d = getText(i)->dist(x, y); + if (d < dist_min) { + dist_min = d; + idx_min = i; + } + } + cur.idx() = idx_min; + InsetBase * inset = cell(cur.idx()).text_.editXY(cur, x, y); + //lyxerr << "# InsetTabular::setPos()\n" << cur << endl; + return inset; } @@ -1014,233 +991,95 @@ int InsetTabular::getCellXPos(int cell) const for (; c < cell; ++c) lx += tabular.getWidthOfColumn(c); - return lx - tabular.getWidthOfColumn(cell) + xo_; + return lx - tabular.getWidthOfColumn(cell) + xo(); } -void InsetTabular::resetPos(BufferView * bv) const +void InsetTabular::resetPos(LCursor & cur) const { -#ifdef WITH_WARNINGS -#warning This should be fixed in the right manner (20011128 Jug) -#endif - // fast hack to fix infinite repaintings! - if (in_reset_pos > 0) - return; - - int cell = 0; - actcol = tabular.column_of_cell(actcell); - actrow = 0; - cursory_ = 0; - for (; cell < actcell && !tabular.isLastRow(cell); ++cell) { - if (tabular.isLastCellInRow(cell)) { - cursory_ += tabular.getDescentOfRow(actrow) + - tabular.getAscentOfRow(actrow + 1) + - tabular.getAdditionalHeight(actrow + 1); - ++actrow; - } - } + BufferView & bv = cur.bv(); + int actcell = cur.idx(); + int actcol = tabular.column_of_cell(actcell); - // we need this only from here on!!! - ++in_reset_pos; int const offset = ADD_TO_TABULAR_WIDTH + 2; int new_x = getCellXPos(actcell) + offset; int old_x = cursorx_; cursorx_ = new_x; // cursor.x(getCellXPos(actcell) + offset); if (actcol < tabular.columns() - 1 && scroll(false) && - tabular.getWidthOfTabular() < bv->workWidth()-20) + tabular.getWidthOfTabular() < bv.workWidth()-20) { scroll(bv, 0.0F); - updateLocal(bv); - } else if (the_locking_inset && - tabular.getWidthOfColumn(actcell) > bv->workWidth() - 20) - { - int xx = cursorx_ - offset; - if (xx > bv->workWidth()-20) { - scroll(bv, - xx + bv->workWidth() - 60); - updateLocal(bv); - } else if (xx < 20) { - if (xx < 0) - xx = -xx + 60; - else - xx = 60; - scroll(bv, xx); - updateLocal(bv); - } } else if (cursorx_ - offset > 20 && cursorx_ - offset + tabular.getWidthOfColumn(actcell) - > bv->workWidth() - 20) { + > bv.workWidth() - 20) { scroll(bv, - tabular.getWidthOfColumn(actcell) - 20); - updateLocal(bv); } else if (cursorx_ - offset < 20) { scroll(bv, 20 - cursorx_ + offset); - updateLocal(bv); - } else if (scroll() && xo_ > 20 && - xo_ + tabular.getWidthOfTabular() > bv->workWidth() - 20) { + } else if (scroll() && xo() > 20 && + xo() + tabular.getWidthOfTabular() > bv.workWidth() - 20) { scroll(bv, old_x - cursorx_); - updateLocal(bv); } - InsetTabularMailer(*this).updateDialog(bv); - in_reset_pos = 0; -} - -DispatchResult InsetTabular::moveRight(BufferView * bv, bool lock) -{ - if (lock) { - if (activateCellInset(bv)) - return DispatchResult(true, true); - } else { - bool moved = isRightToLeft(bv) - ? movePrevCell(bv) : moveNextCell(bv); - if (!moved) - return DispatchResult(false, FINISHED_RIGHT); - if (lock && activateCellInset(bv)) - return DispatchResult(true, true); - } - resetPos(bv); - return DispatchResult(true); + InsetTabularMailer(*this).updateDialog(&bv); } -DispatchResult InsetTabular::moveLeft(BufferView * bv, bool lock) +void InsetTabular::moveNextCell(LCursor & cur) { - bool moved = isRightToLeft(bv) ? moveNextCell(bv) : movePrevCell(bv); - if (!moved) - return DispatchResult(false, FINISHED); - // behind the inset - if (lock && activateCellInset(bv, 0, 0, true)) - return DispatchResult(true, true); - resetPos(bv); - return DispatchResult(true); -} - - -DispatchResult InsetTabular::moveUp(BufferView * bv, bool lock) -{ - int const ocell = actcell; - actcell = tabular.getCellAbove(actcell); - if (actcell == ocell) { // we moved out of the inset - return DispatchResult(false, FINISHED_UP); - } - resetPos(bv); - if (lock) - activateCellInset(bv, bv->x_target(), 0); - return DispatchResult(true, true); -} - - -DispatchResult InsetTabular::moveDown(BufferView * bv, bool lock) -{ - int const ocell = actcell; - actcell = tabular.getCellBelow(actcell); - if (actcell == ocell) { // we moved out of the inset - return DispatchResult(false, FINISHED_DOWN); - } - resetPos(bv); - if (lock) - activateCellInset(bv, bv->x_target(), 0); - return DispatchResult(true, true); -} - - -bool InsetTabular::moveNextCell(BufferView * bv, bool lock) -{ - if (isRightToLeft(bv)) { - if (tabular.isFirstCellInRow(actcell)) { - int row = tabular.row_of_cell(actcell); + lyxerr << "InsetTabular::moveNextCell 1 cur: " << cur.top() << endl; + if (isRightToLeft(cur)) { + lyxerr << "InsetTabular::moveNextCell A cur: " << endl; + if (tabular.isFirstCellInRow(cur.idx())) { + int row = tabular.row_of_cell(cur.idx()); if (row == tabular.rows() - 1) - return false; - actcell = tabular.getLastCellInRow(row); - actcell = tabular.getCellBelow(actcell); + return; + cur.idx() = tabular.getLastCellInRow(row); + cur.idx() = tabular.getCellBelow(cur.idx()); } else { - if (!actcell) - return false; - --actcell; + if (cur.idx() == 0) + return; + --cur.idx(); } } else { - if (tabular.isLastCell(actcell)) - return false; - ++actcell; - } - if (lock) { - bool rtl = tabular.getCellInset(actcell).paragraphs.begin()-> - isRightToLeftPar(bv->buffer()->params()); - activateCellInset(bv, 0, 0, !rtl); + lyxerr << "InsetTabular::moveNextCell B cur: " << endl; + if (tabular.isLastCell(cur.idx())) + return; + ++cur.idx(); } - resetPos(bv); - return true; + cur.par() = 0; + cur.pos() = 0; + lyxerr << "InsetTabular::moveNextCell 2 cur: " << cur.top() << endl; + resetPos(cur); } -bool InsetTabular::movePrevCell(BufferView * bv, bool lock) +void InsetTabular::movePrevCell(LCursor & cur) { - lyxerr << "move prevcell 1" << endl; - if (isRightToLeft(bv)) { - lyxerr << "move prevcell a" << endl; - if (tabular.isLastCellInRow(actcell)) { - int row = tabular.row_of_cell(actcell); + if (isRightToLeft(cur)) { + if (tabular.isLastCellInRow(cur.idx())) { + int row = tabular.row_of_cell(cur.idx()); if (row == 0) - return false; - actcell = tabular.getFirstCellInRow(row); - actcell = tabular.getCellAbove(actcell); + return; + cur.idx() = tabular.getFirstCellInRow(row); + cur.idx() = tabular.getCellAbove(cur.idx()); } else { - if (tabular.isLastCell(actcell)) - return false; - ++actcell; + if (tabular.isLastCell(cur.idx())) + return; + ++cur.idx(); } } else { - lyxerr << "move prevcell b" << endl; - if (actcell == 0) // first cell - return false; - --actcell; - } - lyxerr << "move prevcell 2" << endl; - if (lock) { - bool rtl = tabular.getCellInset(actcell).paragraphs.begin()-> - isRightToLeftPar(bv->buffer()->params()); - activateCellInset(bv, 0, 0, !rtl); - } - lyxerr << "move prevcell 3" << endl; - resetPos(bv); - lyxerr << "move prevcell 4" << endl; - return true; -} - - -void InsetTabular::setFont(BufferView * bv, LyXFont const & font, bool tall, - bool selectall) -{ - if (selectall) { - setSelection(0, tabular.getNumberOfCells() - 1); - } - if (hasSelection()) { - recordUndo(bv, Undo::ATOMIC); - bool const frozen = undo_frozen; - if (!frozen) - freezeUndo(); - // apply the fontchange on the whole selection - int sel_row_start; - int sel_row_end; - int sel_col_start; - int sel_col_end; - getSelection(sel_row_start, sel_row_end, sel_col_start, sel_col_end); - for (int i = sel_row_start; i <= sel_row_end; ++i) - for (int j = sel_col_start; j <= sel_col_end; ++j) - tabular.getCellInset(i, j).setFont(bv, font, tall, true); - - if (!frozen) - unFreezeUndo(); - if (selectall) - clearSelection(); - updateLocal(bv); + if (cur.idx() == 0) // first cell + return; + --cur.idx(); } - if (the_locking_inset) - the_locking_inset->setFont(bv, font, tall); + cur.par() = 0; + cur.pos() = 0; + resetPos(cur); } -bool InsetTabular::tabularFeatures(BufferView * bv, string const & what) +bool InsetTabular::tabularFeatures(LCursor & cur, string const & what) { LyXTabular::Feature action = LyXTabular::LAST_ACTION; @@ -1260,10 +1099,11 @@ bool InsetTabular::tabularFeatures(BufferView * bv, string const & what) string const val = ltrim(what.substr(tabularFeature[i].feature.length())); - tabularFeatures(bv, action, val); + tabularFeatures(cur, action, val); return true; } + namespace { void checkLongtableSpecial(LyXTabular::ltType & ltt, @@ -1287,9 +1127,11 @@ void checkLongtableSpecial(LyXTabular::ltType & ltt, } // anon namespace -void InsetTabular::tabularFeatures(BufferView * bv, +void InsetTabular::tabularFeatures(LCursor & cur, LyXTabular::Feature feature, string const & value) { + BufferView & bv = cur.bv(); + int actcell = cur.idx(); int sel_col_start; int sel_col_end; int sel_row_start; @@ -1338,14 +1180,9 @@ void InsetTabular::tabularFeatures(BufferView * bv, break; } - if (hasSelection()) { - getSelection(sel_row_start, sel_row_end, sel_col_start, sel_col_end); - } else { - sel_col_start = sel_col_end = tabular.column_of_cell(actcell); - sel_row_start = sel_row_end = tabular.row_of_cell(actcell); - } - recordUndo(bv, Undo::ATOMIC); + recordUndo(cur, Undo::ATOMIC); + getSelection(cur, sel_row_start, sel_row_end, sel_col_start, sel_col_end); int row = tabular.row_of_cell(actcell); int column = tabular.column_of_cell(actcell); bool flag = true; @@ -1358,10 +1195,10 @@ void InsetTabular::tabularFeatures(BufferView * bv, tabular.setColumnPWidth(actcell, len); if (len.zero() && tabular.getAlignment(actcell, true) == LYX_ALIGN_BLOCK) - tabularFeatures(bv, LyXTabular::ALIGN_CENTER, string()); + tabularFeatures(cur, LyXTabular::ALIGN_CENTER, string()); else if (!len.zero() && tabular.getAlignment(actcell, true) != LYX_ALIGN_BLOCK) - tabularFeatures(bv, LyXTabular::ALIGN_BLOCK, string()); + tabularFeatures(cur, LyXTabular::ALIGN_BLOCK, string()); break; } @@ -1376,14 +1213,12 @@ void InsetTabular::tabularFeatures(BufferView * bv, case LyXTabular::APPEND_ROW: // append the row into the tabular - tabular.appendRow(bv->buffer()->params(), actcell); - tabular.setOwner(this); + tabular.appendRow(bv.buffer()->params(), actcell); break; case LyXTabular::APPEND_COLUMN: // append the column into the tabular - tabular.appendColumn(bv->buffer()->params(), actcell); - tabular.setOwner(this); + tabular.appendColumn(bv.buffer()->params(), actcell); actcell = tabular.getCellNumber(row, column); break; @@ -1393,7 +1228,7 @@ void InsetTabular::tabularFeatures(BufferView * bv, if (sel_row_start >= tabular.rows()) --sel_row_start; actcell = tabular.getCellNumber(sel_row_start, column); - clearSelection(); + cur.selection() = false; break; case LyXTabular::DELETE_COLUMN: @@ -1402,7 +1237,7 @@ void InsetTabular::tabularFeatures(BufferView * bv, if (sel_col_start >= tabular.columns()) --sel_col_start; actcell = tabular.getCellNumber(row, sel_col_start); - clearSelection(); + cur.selection() = false; break; case LyXTabular::M_TOGGLE_LINE_TOP: @@ -1495,13 +1330,14 @@ void InsetTabular::tabularFeatures(BufferView * bv, _("You cannot set multicolumn vertically.")); return; } +#if 0 // just multicol for one Single Cell if (!hasSelection()) { - // check wether we are completly in a multicol + // check whether we are completly in a multicol if (tabular.isMultiColumn(actcell)) tabular.unsetMultiColumn(actcell); else - tabular.setMultiColumn(bv->buffer(), actcell, 1); + tabular.setMultiColumn(bv.buffer(), actcell, 1); break; } // we have a selection so this means we just add all this @@ -1516,19 +1352,22 @@ void InsetTabular::tabularFeatures(BufferView * bv, s_start = sel_cell_start; s_end = sel_cell_end; } - tabular.setMultiColumn(bv->buffer(), s_start, s_end - s_start + 1); + tabular.setMultiColumn(bv.buffer(), s_start, s_end - s_start + 1); actcell = s_start; - clearSelection(); +#endif + cur.selection() = false; break; } case LyXTabular::SET_ALL_LINES: setLines = true; case LyXTabular::UNSET_ALL_LINES: +#if 0 for (int i = sel_row_start; i <= sel_row_end; ++i) for (int j = sel_col_start; j <= sel_col_end; ++j) tabular.setAllLines( tabular.getCellNumber(i,j), setLines); +#endif break; case LyXTabular::SET_LONGTABULAR: @@ -1612,272 +1451,44 @@ void InsetTabular::tabularFeatures(BufferView * bv, break; } - updateLocal(bv); - InsetTabularMailer(*this).updateDialog(bv); -} - - -bool InsetTabular::activateCellInset(BufferView * bv, int x, int y, bool behind) -{ - UpdatableInset & inset = tabular.getCellInset(actcell); - if (behind) { -#warning metrics? - x = inset.x() + inset.width(); - y = inset.descent(); - } - inset.edit(bv, x, y); - bv->cursor().push(&inset); - if (!the_locking_inset) - return false; - updateLocal(bv); - return the_locking_inset; -} - - -void InsetTabular::deleteLyXText(BufferView * /*bv*/) const -{ -#warning this is strange, isnt it? But this is 1.3.x code... - //resizeLyXText(bv, recursive); + InsetTabularMailer(*this).updateDialog(&bv); } bool InsetTabular::showInsetDialog(BufferView * bv) const { - if (!the_locking_inset || !the_locking_inset->showInsetDialog(bv)) - InsetTabularMailer(*this).showDialog(bv); + InsetTabularMailer(*this).showDialog(bv); return true; } void InsetTabular::openLayoutDialog(BufferView * bv) const { -#warning Look here -/* - if (the_locking_inset) { - InsetTabular * inset = static_cast - (the_locking_inset->getFirstLockingInsetOfType(TABULAR_CODE)); - if (inset) { - inset->openLayoutDialog(bv); - return; - } - } -*/ InsetTabularMailer(*this).showDialog(bv); } -// -// function returns an object as defined in func_status.h: -// states OK, Unknown, Disabled, On, Off. -// -FuncStatus InsetTabular::getStatus(string const & what) const -{ - int action = LyXTabular::LAST_ACTION; - FuncStatus status; - - int i = 0; - for (; tabularFeature[i].action != LyXTabular::LAST_ACTION; ++i) { - string const tmp = tabularFeature[i].feature; - if (tmp == what.substr(0, tmp.length())) { - //if (!compare(tabularFeatures[i].feature.c_str(), what.c_str(), - // tabularFeatures[i].feature.length())) { - action = tabularFeature[i].action; - break; - } - } - if (action == LyXTabular::LAST_ACTION) { - status.clear(); - status.unknown(true); - return status; - } - - string const argument - = ltrim(what.substr(tabularFeature[i].feature.length())); - - int sel_row_start; - int sel_row_end; - int dummy; - LyXTabular::ltType dummyltt; - bool flag = true; - - if (hasSelection()) - getSelection(sel_row_start, sel_row_end, dummy, dummy); - else - sel_row_start = sel_row_end = tabular.row_of_cell(actcell); - - switch (action) { - case LyXTabular::SET_PWIDTH: - case LyXTabular::SET_MPWIDTH: - case LyXTabular::SET_SPECIAL_COLUMN: - case LyXTabular::SET_SPECIAL_MULTI: - case LyXTabular::APPEND_ROW: - case LyXTabular::APPEND_COLUMN: - case LyXTabular::DELETE_ROW: - case LyXTabular::DELETE_COLUMN: - case LyXTabular::SET_ALL_LINES: - case LyXTabular::UNSET_ALL_LINES: - status.clear(); - return status; - - case LyXTabular::MULTICOLUMN: - status.setOnOff(tabular.isMultiColumn(actcell)); - break; - - case LyXTabular::M_TOGGLE_LINE_TOP: - flag = false; - case LyXTabular::TOGGLE_LINE_TOP: - status.setOnOff(tabular.topLine(actcell, flag)); - break; - - case LyXTabular::M_TOGGLE_LINE_BOTTOM: - flag = false; - case LyXTabular::TOGGLE_LINE_BOTTOM: - status.setOnOff(tabular.bottomLine(actcell, flag)); - break; - - case LyXTabular::M_TOGGLE_LINE_LEFT: - flag = false; - case LyXTabular::TOGGLE_LINE_LEFT: - status.setOnOff(tabular.leftLine(actcell, flag)); - break; - - case LyXTabular::M_TOGGLE_LINE_RIGHT: - flag = false; - case LyXTabular::TOGGLE_LINE_RIGHT: - status.setOnOff(tabular.rightLine(actcell, flag)); - break; - - case LyXTabular::M_ALIGN_LEFT: - flag = false; - case LyXTabular::ALIGN_LEFT: - status.setOnOff(tabular.getAlignment(actcell, flag) == LYX_ALIGN_LEFT); - break; - - case LyXTabular::M_ALIGN_RIGHT: - flag = false; - case LyXTabular::ALIGN_RIGHT: - status.setOnOff(tabular.getAlignment(actcell, flag) == LYX_ALIGN_RIGHT); - break; - - case LyXTabular::M_ALIGN_CENTER: - flag = false; - case LyXTabular::ALIGN_CENTER: - status.setOnOff(tabular.getAlignment(actcell, flag) == LYX_ALIGN_CENTER); - break; - - case LyXTabular::ALIGN_BLOCK: - status.disabled(tabular.getPWidth(actcell).zero()); - status.setOnOff(tabular.getAlignment(actcell, flag) == LYX_ALIGN_BLOCK); - break; - - case LyXTabular::M_VALIGN_TOP: - flag = false; - case LyXTabular::VALIGN_TOP: - status.setOnOff(tabular.getVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_TOP); - break; - - case LyXTabular::M_VALIGN_BOTTOM: - flag = false; - case LyXTabular::VALIGN_BOTTOM: - status.setOnOff(tabular.getVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_BOTTOM); - break; - - case LyXTabular::M_VALIGN_MIDDLE: - flag = false; - case LyXTabular::VALIGN_MIDDLE: - status.setOnOff(tabular.getVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_MIDDLE); - break; - - case LyXTabular::SET_LONGTABULAR: - status.setOnOff(tabular.isLongTabular()); - break; - - case LyXTabular::UNSET_LONGTABULAR: - status.setOnOff(!tabular.isLongTabular()); - break; - - case LyXTabular::SET_ROTATE_TABULAR: - status.setOnOff(tabular.getRotateTabular()); - break; - - case LyXTabular::UNSET_ROTATE_TABULAR: - status.setOnOff(!tabular.getRotateTabular()); - break; - - case LyXTabular::SET_ROTATE_CELL: - status.setOnOff(tabular.getRotateCell(actcell)); - break; - - case LyXTabular::UNSET_ROTATE_CELL: - status.setOnOff(!tabular.getRotateCell(actcell)); - break; - - case LyXTabular::SET_USEBOX: - status.setOnOff(strToInt(argument) == tabular.getUsebox(actcell)); - break; - - case LyXTabular::SET_LTFIRSTHEAD: - status.setOnOff(tabular.getRowOfLTHead(sel_row_start, dummyltt)); - break; - - case LyXTabular::SET_LTHEAD: - status.setOnOff(tabular.getRowOfLTHead(sel_row_start, dummyltt)); - break; - - case LyXTabular::SET_LTFOOT: - status.setOnOff(tabular.getRowOfLTFoot(sel_row_start, dummyltt)); - break; - - case LyXTabular::SET_LTLASTFOOT: - status.setOnOff(tabular.getRowOfLTFoot(sel_row_start, dummyltt)); - break; - - case LyXTabular::SET_LTNEWPAGE: - status.setOnOff(tabular.getLTNewPage(sel_row_start)); - break; - - default: - status.clear(); - status.disabled(true); - break; - } - return status; -} - - void InsetTabular::getLabelList(Buffer const & buffer, - std::vector & list) const + vector & list) const { tabular.getLabelList(buffer, list); } -bool InsetTabular::copySelection(BufferView * bv) +bool InsetTabular::copySelection(LCursor & cur) { - if (!hasSelection()) + if (!cur.selection()) return false; - int sel_col_start = tabular.column_of_cell(sel_cell_start); - int sel_col_end = tabular.column_of_cell(sel_cell_end); - if (sel_col_start > sel_col_end) { - sel_col_start = sel_col_end; - sel_col_end = tabular.right_column_of_cell(sel_cell_start); - } else { - sel_col_end = tabular.right_column_of_cell(sel_cell_end); - } - - int sel_row_start = tabular.row_of_cell(sel_cell_start); - int sel_row_end = tabular.row_of_cell(sel_cell_end); - if (sel_row_start > sel_row_end) - swap(sel_row_start, sel_row_end); + int rs, re, cs, ce; + getSelection(cur, rs, re, cs, ce); paste_tabular.reset(new LyXTabular(tabular)); - paste_tabular->setOwner(this); - for (int i = 0; i < sel_row_start; ++i) + for (int i = 0; i < rs; ++i) paste_tabular->deleteRow(0); - int const rows = sel_row_end - sel_row_start + 1; + int const rows = re - rs + 1; while (paste_tabular->rows() > rows) paste_tabular->deleteRow(rows); @@ -1885,10 +1496,10 @@ bool InsetTabular::copySelection(BufferView * bv) paste_tabular->setBottomLine(paste_tabular->getFirstCellInRow(rows - 1), true, true); - for (int i = 0; i < sel_col_start; ++i) + for (int i = 0; i < cs; ++i) paste_tabular->deleteColumn(0); - int const columns = sel_col_end - sel_col_start + 1; + int const columns = ce - cs + 1; while (paste_tabular->columns() > columns) paste_tabular->deleteColumn(columns); @@ -1897,19 +1508,20 @@ bool InsetTabular::copySelection(BufferView * bv) true, true); ostringstream os; - OutputParams const runparams; - paste_tabular->plaintext(*bv->buffer(), os, runparams, - ownerPar(*bv->buffer(), this).params().depth(), true, '\t'); - bv->stuffClipboard(os.str()); + OutputParams const runparams; + paste_tabular->plaintext(cur.buffer(), os, runparams, 0, true, '\t'); + cur.bv().stuffClipboard(os.str()); return true; } -bool InsetTabular::pasteSelection(BufferView * bv) +bool InsetTabular::pasteSelection(LCursor & cur) { if (!paste_tabular) return false; - + int actcell = cur.idx(); + int actcol = tabular.column_of_cell(actcell); + int actrow = tabular.row_of_cell(actcell); for (int r1 = 0, r2 = actrow; r1 < paste_tabular->rows() && r2 < tabular.rows(); ++r1, ++r2) { @@ -1929,8 +1541,6 @@ bool InsetTabular::pasteSelection(BufferView * bv) } InsetText & inset = tabular.getCellInset(r2, c2); inset = paste_tabular->getCellInset(r1, c1); - inset.setOwner(this); - inset.deleteLyXText(bv); inset.markNew(); } } @@ -1938,111 +1548,73 @@ bool InsetTabular::pasteSelection(BufferView * bv) } -bool InsetTabular::cutSelection(BufferParams const & bp) +void InsetTabular::cutSelection(LCursor & cur) { - if (!hasSelection()) - return false; - - int sel_col_start = tabular.column_of_cell(sel_cell_start); - int sel_col_end = tabular.column_of_cell(sel_cell_end); - if (sel_col_start > sel_col_end) { - sel_col_start = sel_col_end; - sel_col_end = tabular.right_column_of_cell(sel_cell_start); - } else { - sel_col_end = tabular.right_column_of_cell(sel_cell_end); - } - - int sel_row_start = tabular.row_of_cell(sel_cell_start); - int sel_row_end = tabular.row_of_cell(sel_cell_end); - - if (sel_row_start > sel_row_end) - swap(sel_row_start, sel_row_end); - - if (sel_cell_start > sel_cell_end) - swap(sel_cell_start, sel_cell_end); - - for (int i = sel_row_start; i <= sel_row_end; ++i) - for (int j = sel_col_start; j <= sel_col_end; ++j) - tabular.getCellInset(tabular.getCellNumber(i, j)) - .clear(bp.tracking_changes); - return true; -} - + if (!cur.selection()) + return; -bool InsetTabular::isRightToLeft(BufferView * bv) -{ - return bv->getParentLanguage(this)->RightToLeft(); + bool const track = cur.buffer().params().tracking_changes; + int rs, re, cs, ce; + getSelection(cur, rs, re, cs, ce); + for (int i = rs; i <= re; ++i) + for (int j = cs; j <= ce; ++j) + cell(tabular.getCellNumber(i, j)).clear(track); } -int InsetTabular::scroll(bool recursive) const +bool InsetTabular::isRightToLeft(LCursor & cur) const { - int sx = UpdatableInset::scroll(false); - - if (recursive && the_locking_inset) - sx += the_locking_inset->scroll(recursive); - - return sx; + BOOST_ASSERT(cur.size() > 1); + Paragraph const & parentpar = cur[cur.size() - 2].paragraph(); + LCursor::pos_type const parentpos = cur[cur.size() - 2].pos(); + return parentpar.getFontSettings(cur.bv().buffer()->params(), + parentpos).language()->RightToLeft(); } -void InsetTabular::getSelection(int & srow, int & erow, - int & scol, int & ecol) const +void InsetTabular::getSelection(LCursor & cur, + int & rs, int & re, int & cs, int & ce) const { - int const start = hasSelection() ? sel_cell_start : actcell; - int const end = hasSelection() ? sel_cell_end : actcell; - - srow = tabular.row_of_cell(start); - erow = tabular.row_of_cell(end); - if (srow > erow) - swap(srow, erow); - - scol = tabular.column_of_cell(start); - ecol = tabular.column_of_cell(end); - if (scol > ecol) - swap(scol, ecol); - else - ecol = tabular.right_column_of_cell(end); -} - + CursorSlice const & beg = cur.selBegin(); + CursorSlice const & end = cur.selEnd(); + cs = tabular.column_of_cell(beg.idx()); + ce = tabular.column_of_cell(end.idx()); + if (cs > ce) { + ce = cs; + cs = tabular.column_of_cell(end.idx()); + } else { + ce = tabular.right_column_of_cell(end.idx()); + } -ParagraphList * InsetTabular::getParagraphs(int i) const -{ - return i < tabular.getNumberOfCells() - ? tabular.getCellInset(i).getParagraphs(0) - : 0; + rs = tabular.row_of_cell(beg.idx()); + re = tabular.row_of_cell(end.idx()); + if (rs > re) + swap(rs, re); } -int InsetTabular::numParagraphs() const +size_t InsetTabular::nargs() const { return tabular.getNumberOfCells(); } -LyXText * InsetTabular::getText(int i) const +LyXText * InsetTabular::getText(int idx) const { - return i < tabular.getNumberOfCells() - ? tabular.getCellInset(i).getText(0) - : 0; + return size_t(idx) < nargs() ? cell(idx).getText(0) : 0; } void InsetTabular::markErased() { - for (int cell = 0; cell < tabular.getNumberOfCells(); ++cell) - tabular.getCellInset(cell).markErased(); + for (idx_type idx = 0; idx < nargs(); ++idx) + cell(idx).markErased(); } -bool InsetTabular::insetAllowed(InsetOld::Code) const -{ - return false; -} - - -bool InsetTabular::forceDefaultParagraphs(InsetOld const * in) const +bool InsetTabular::forceDefaultParagraphs(InsetBase const *) const { +#if 0 const int cell = tabular.getCellFromInset(in); if (cell != -1) @@ -2056,10 +1628,12 @@ bool InsetTabular::forceDefaultParagraphs(InsetOld const * in) const // 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::insertAsciiString(BufferView * bv, string const & buf, +bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf, bool usePaste) { if (buf.length() <= 0) @@ -2071,6 +1645,10 @@ bool InsetTabular::insertAsciiString(BufferView * bv, string const & buf, string::size_type len = buf.length(); string::size_type p = 0; + int actcell = bv.cursor().idx(); + int actcol = tabular.column_of_cell(actcell); + int actrow = tabular.row_of_cell(actcell); + while (p < len && (p = buf.find_first_of("\t\n", p)) != string::npos) { switch (buf[p]) { case '\t': @@ -2092,10 +1670,7 @@ bool InsetTabular::insertAsciiString(BufferView * bv, string const & buf, int row = 0; if (usePaste) { paste_tabular.reset( - new LyXTabular(bv->buffer()->params(), rows, maxCols) - ); - - paste_tabular->setOwner(this); + new LyXTabular(bv.buffer()->params(), rows, maxCols)); loctab = paste_tabular.get(); cols = 0; } else { @@ -2122,8 +1697,8 @@ bool InsetTabular::insertAsciiString(BufferView * bv, string const & buf, // we can only set this if we are not too far right if (cols < columns) { InsetText & inset = loctab->getCellInset(cell); - LyXFont const font = inset.text_. - getFont(inset.paragraphs.begin(), 0); + Paragraph & par = inset.text_.getPar(0); + LyXFont const font = inset.text_.getFont(par, 0); inset.setText(buf.substr(op, p - op), font); ++cols; ++cell; @@ -2133,8 +1708,8 @@ bool InsetTabular::insertAsciiString(BufferView * bv, string const & buf, // we can only set this if we are not too far right if (cols < columns) { InsetText & inset = tabular.getCellInset(cell); - LyXFont const font = inset.text_. - getFont(inset.paragraphs.begin(), 0); + Paragraph & par = inset.text_.getPar(0); + LyXFont const font = inset.text_.getFont(par, 0); inset.setText(buf.substr(op, p - op), font); } cols = ocol; @@ -2149,10 +1724,10 @@ bool InsetTabular::insertAsciiString(BufferView * bv, string const & buf, // check for the last cell if there is no trailing '\n' if (cell < cells && op < len) { InsetText & inset = loctab->getCellInset(cell); - LyXFont const font = inset.text_.getFont(inset.paragraphs.begin(), 0); + Paragraph & par = inset.text_.getPar(0); + LyXFont const font = inset.text_.getFont(par, 0); inset.setText(buf.substr(op, len - op), font); } - return true; } @@ -2168,6 +1743,15 @@ void InsetTabular::addPreview(PreviewLoader & loader) const } +bool InsetTabular::tablemode(LCursor & cur) const +{ + return cur.selection() && cur.selBegin().idx() != cur.selEnd().idx(); +} + + + + + string const InsetTabularMailer::name_("tabular"); InsetTabularMailer::InsetTabularMailer(InsetTabular const & inset) @@ -2187,7 +1771,9 @@ int InsetTabularMailer::string2params(string const & in, InsetTabular & inset) LyXLex lex(0,0); lex.setStream(data); +#ifdef WITH_WARNINGS #warning CHECK verify that this is a sane value to return. +#endif if (in.empty()) return -1; @@ -2232,7 +1818,11 @@ int InsetTabularMailer::string2params(string const & in, InsetTabular & inset) string const InsetTabularMailer::params2string(InsetTabular const & inset) { ostringstream data; - data << name_ << " \\active_cell " << inset.getActCell() << '\n'; +#ifdef WITH_WARNINGS +#warning wrong! +#endif + //data << name_ << " \\active_cell " << inset.getActCell() << '\n'; + data << name_ << " \\active_cell " << 0 << '\n'; inset.write(inset.buffer(), data); data << "\\end_inset\n"; return data.str();