X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsettabular.C;h=fd5c283bf5ec97c75b41791d0ca0e9d53f7248d0;hb=4acce5c117e0d6101113f38e2e058d284b866de9;hp=232ada36a41988e15a875d0d91b44ac17de5a06c;hpb=75b485d11034232d3b335e68387d02bc82485386;p=lyx.git diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index 232ada36a4..fd5c283bf5 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -15,7 +15,9 @@ #include "buffer.h" #include "bufferparams.h" #include "BufferView.h" +#include "cursor.h" #include "debug.h" +#include "dispatchresult.h" #include "funcrequest.h" #include "FuncStatus.h" #include "gettext.h" @@ -24,33 +26,35 @@ #include "lyx_cb.h" #include "lyxlex.h" #include "metricsinfo.h" +#include "outputparams.h" #include "paragraph.h" #include "paragraph_funcs.h" #include "ParagraphParameters.h" -#include "undo_funcs.h" -#include "WordLangTuple.h" +#include "undo.h" #include "frontends/Alert.h" #include "frontends/font_metrics.h" #include "frontends/LyXView.h" #include "frontends/Painter.h" -#include "support/std_sstream.h" +#include #include using lyx::graphics::PreviewLoader; 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 { @@ -59,7 +63,7 @@ int const ADD_TO_HEIGHT = 2; int const ADD_TO_TABULAR_WIDTH = 2; /// -LyXTabular * paste_tabular = 0; +boost::scoped_ptr paste_tabular; struct TabularFeature { @@ -117,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: @@ -132,54 +138,30 @@ 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; } bool InsetTabular::hasPasteBuffer() const { - return (paste_tabular != 0); + return (paste_tabular.get() != 0); } 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); - // for now make it always display as display() inset - // just for test!!! - the_locking_inset = 0; - old_locking_inset = 0; - locked = false; - oldcell = -1; - actrow = actcell = 0; - clearSelection(); - in_reset_pos = 0; - inset_x = 0; - inset_y = 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; - old_locking_inset = 0; - locked = false; - oldcell = -1; - actrow = actcell = 0; - clearSelection(); - in_reset_pos = 0; - inset_x = 0; - inset_y = 0; -} + buffer_(tab.buffer_), cursorx_(0) +{} InsetTabular::~InsetTabular() @@ -200,14 +182,7 @@ Buffer const & InsetTabular::buffer() const } -BufferView * InsetTabular::view() const -{ - BOOST_ASSERT(false); - return 0; -} - - -void InsetTabular::buffer(Buffer * b) +void InsetTabular::buffer(Buffer const * b) { buffer_ = b; } @@ -229,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") { @@ -251,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; @@ -265,29 +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 0 - UpdatableInset::draw(pi, x, y); -#else - if (!owner()) - x += scroll(); -#endif - - top_x = x; - top_baseline = 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) { @@ -295,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, @@ -330,7 +316,7 @@ void InsetTabular::drawCellLines(Painter & pain, int x, int y, int row, int cell) const { int x2 = x + tabular.getWidthOfColumn(cell); - bool on_off; + bool on_off = false; if (!tabular.topAlreadyDrawn(cell)) { on_off = !tabular.topLine(cell); @@ -361,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); + } } } @@ -394,733 +371,566 @@ string const InsetTabular::editMessage() const } -void InsetTabular::insetUnlock(BufferView * bv) -{ - if (the_locking_inset) { - the_locking_inset->insetUnlock(bv); - updateLocal(bv); - the_locking_inset = 0; - } - actcell = 0; - oldcell = -1; - locked = false; - if (scroll(false) || hasSelection()) { - clearSelection(); - if (scroll(false)) - scroll(bv, 0.0F); - updateLocal(bv); - } -} - - -void InsetTabular::updateLocal(BufferView * bv) const -{ - bv->updateInset(this); - if (locked) - resetPos(bv); -} - - -bool InsetTabular::lockInsetInInset(BufferView * bv, UpdatableInset * inset) -{ - lyxerr[Debug::INSETTEXT] << "InsetTabular::LockInsetInInset(" - << inset << "): "; - if (!inset) - return false; - oldcell = -1; - if (inset == &tabular.getCellInset(actcell)) { - lyxerr[Debug::INSETTEXT] << "OK" << endl; - the_locking_inset = &tabular.getCellInset(actcell); - resetPos(bv); - return true; - } else if (!the_locking_inset) { - int const n = tabular.getNumberOfCells(); - int const id = inset->id(); - for (int i = 0; i < n; ++i) { - InsetText * in = &tabular.getCellInset(i); - if (inset == in) { - actcell = i; - the_locking_inset = in; - locked = true; - resetPos(bv); - return true; - } - if (in->getInsetFromID(id)) { - actcell = i; - in->localDispatch(FuncRequest(bv, LFUN_INSET_EDIT)); - return the_locking_inset->lockInsetInInset(bv, inset); - } - } - } else if (the_locking_inset && (the_locking_inset == inset)) { - lyxerr[Debug::INSETTEXT] << "OK" << endl; - resetPos(bv); - } else if (the_locking_inset) { - lyxerr[Debug::INSETTEXT] << "MAYBE" << endl; - return the_locking_inset->lockInsetInInset(bv, inset); - } - lyxerr[Debug::INSETTEXT] << "NOT OK" << endl; - return false; -} - - -bool InsetTabular::unlockInsetInInset(BufferView * bv, UpdatableInset * inset, - bool lr) -{ - if (!the_locking_inset) - return false; - if (the_locking_inset == inset) { - the_locking_inset->insetUnlock(bv); -#ifdef WITH_WARNINGS -#warning fix scrolling when cellinset has requested a scroll (Jug)!!! -#endif -#if 0 - if (scroll(false)) - scroll(bv, 0.0F); -#endif - updateLocal(bv); - // this has to be here otherwise we don't redraw the cell! - the_locking_inset = 0; - return true; - } - if (the_locking_inset->unlockInsetInInset(bv, inset, lr)) { - if (inset->lyxCode() == TABULAR_CODE && - !the_locking_inset->getFirstLockingInsetOfType(TABULAR_CODE)) { - InsetTabularMailer(*this).updateDialog(bv); - oldcell = actcell; - } - return true; - } - return false; -} - - -int InsetTabular::insetInInsetY() const -{ - if (!the_locking_inset) - return 0; - return inset_y + the_locking_inset->insetInInsetY(); -} - - -UpdatableInset * InsetTabular::getLockingInset() const -{ - return the_locking_inset ? the_locking_inset->getLockingInset() : - const_cast(this); -} - - -UpdatableInset * InsetTabular::getFirstLockingInsetOfType(InsetOld::Code c) -{ - if (c == lyxCode()) - return this; - if (the_locking_inset) - return the_locking_inset->getFirstLockingInsetOfType(c); - return 0; -} - - -bool InsetTabular::insertInset(BufferView * bv, InsetOld * inset) -{ - if (the_locking_inset) - return the_locking_inset->insertInset(bv, inset); - return false; -} - - -void InsetTabular::lfunMousePress(FuncRequest const & cmd) -{ - if (hasSelection() && cmd.button() == mouse_button::button3) - return; - - if (hasSelection()) { - clearSelection(); - updateLocal(cmd.view()); - } - - int const ocell = actcell; - BufferView * bv = cmd.view(); - - if (!locked) { - locked = true; - the_locking_inset = 0; - inset_x = 0; - inset_y = 0; - } - setPos(bv, cmd.x, cmd.y); - clearSelection(); - - bool const inset_hit = insetHit(bv, cmd.x, cmd.y); - - if ((ocell == actcell) && the_locking_inset && inset_hit) { - resetPos(bv); - FuncRequest cmd1 = cmd; - cmd1.x -= inset_x; - cmd1.y -= inset_y; - the_locking_inset->localDispatch(cmd1); - return; - } - - if (the_locking_inset) { - the_locking_inset->insetUnlock(bv); - updateLocal(bv); - the_locking_inset = 0; - } - - if (cmd.button() == mouse_button::button2) { - localDispatch(FuncRequest(bv, LFUN_PASTESELECTION, "paragraph")); - return; - } - - if (inset_hit && bv->theLockingInset()) { - if (!bv->lockInset(&tabular.getCellInset(actcell))) { - lyxerr[Debug::INSETS] << "Cannot lock inset" << endl; - return; - } - FuncRequest cmd1 = cmd; - cmd1.x -= inset_x; - cmd1.y -= inset_y; - the_locking_inset->localDispatch(cmd1); - } -} - - -bool InsetTabular::lfunMouseRelease(FuncRequest const & cmd) +void InsetTabular::edit(LCursor & cur, bool left) { - bool ret = false; - if (the_locking_inset) { - FuncRequest cmd1 = cmd; - cmd1.x -= inset_x; - cmd1.y -= inset_y; - ret = the_locking_inset->localDispatch(cmd1); - } - if (cmd.button() == mouse_button::button3 && !ret) { - InsetTabularMailer(*this).showDialog(cmd.view()); - return true; + lyxerr << "InsetTabular::edit: " << this << endl; + finishUndo(); + int cell; + cur.push(*this); + if (left) { + if (isRightToLeft(cur)) + cell = tabular.getLastCellInRow(0); + else + cell = 0; + } else { + if (isRightToLeft(cur)) + cell = tabular.getFirstCellInRow(tabular.rows()-1); + else + cell = tabular.getNumberOfCells() - 1; } - return ret; + cur.selection() = false; + // this accesses the position cache before it is initialized + //resetPos(cur); + //cur.bv().fitCursor(); + cur.idx() = cell; } -void InsetTabular::lfunMouseMotion(FuncRequest const & cmd) +InsetBase * InsetTabular::editXY(LCursor & cur, int x, int y) const { - if (the_locking_inset) { - FuncRequest cmd1 = cmd; - cmd1.x -= inset_x; - cmd1.y -= inset_y; - the_locking_inset->localDispatch(cmd1); - return; - } - - BufferView * bv = cmd.view(); - int const old_cell = actcell; - - setPos(bv, cmd.x, cmd.y); - if (!hasSelection()) { - setSelection(actcell, actcell); - updateLocal(bv); - } else if (old_cell != actcell) { - setSelection(sel_cell_start, actcell); - updateLocal(bv); - } + //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); } -dispatch_result InsetTabular::localDispatch(FuncRequest const & cmd) +void InsetTabular::priv_dispatch(LCursor & cur, FuncRequest & cmd) { - // We need to save the value of the_locking_inset as the call to - // the_locking_inset->localDispatch might unlock it. - old_locking_inset = the_locking_inset; - dispatch_result result = UpdatableInset::localDispatch(cmd); - BufferView * bv = cmd.view(); - - if (cmd.action == LFUN_INSET_EDIT) { + lyxerr << "# InsetTabular::dispatch: cmd: " << cmd << endl; + //lyxerr << " cur:\n" << cur << endl; + CursorSlice sl = cur.top(); + LCursor & bvcur = cur.bv().cursor(); - if (!bv->lockInset(this)) { - lyxerr[Debug::INSETTEXT] << "InsetTabular::Cannot lock inset" << endl; - return DISPATCHED; - } + switch (cmd.action) { - finishUndo(); - locked = true; - the_locking_inset = 0; - inset_x = 0; - inset_y = 0; - - if (cmd.argument.size()) { - if (cmd.argument == "left") { - if (isRightToLeft(bv)) - actcell = tabular.getLastCellInRow(0); - else - actcell = 0; - } else { - if (isRightToLeft(bv)) - actcell = tabular.getFirstCellInRow(tabular.rows()-1); - else - actcell = tabular.getNumberOfCells() - 1; - } - clearSelection(); - resetPos(bv); - bv->fitCursor(); - } + case LFUN_MOUSE_PRESS: + lyxerr << "# InsetTabular::MousePress\n" << cur.bv().cursor() << endl; - else { - setPos(bv, cmd.x, cmd.y); - clearSelection(); - finishUndo(); - if (insetHit(bv, cmd.x, cmd.y) && cmd.button() != mouse_button::button3) { - activateCellInsetAbs(bv, cmd.x, cmd.y, cmd.button()); - } + if (cmd.button() == mouse_button::button1) { + cur.selection() = false; + setPos(cur, cmd.x, cmd.y); + cur.resetAnchor(); + bvcur = cur; + break; } - return DISPATCHED; - } - - if (result == DISPATCHED || result == DISPATCHED_NOUPDATE) { - resetPos(bv); - return result; - } - - if (cmd.action < 0 && cmd.argument.empty()) - return FINISHED; - - bool hs = hasSelection(); - - result = DISPATCHED; - // this one have priority over the locked InsetText, if we're not already - // inside another tabular then that one get's priority! - if (getFirstLockingInsetOfType(InsetOld::TABULAR_CODE) == this) { - switch (cmd.action) { - case LFUN_MOUSE_PRESS: - lfunMousePress(cmd); - return DISPATCHED; - case LFUN_MOUSE_MOTION: - lfunMouseMotion(cmd); - return DISPATCHED; + //if (cmd.button() == mouse_button::button2) + // dispatch(cur, FuncRequest(LFUN_PASTESELECTION, "paragraph")); - case LFUN_MOUSE_RELEASE: - return lfunMouseRelease(cmd) ? DISPATCHED : UNDISPATCHED; - - case LFUN_CELL_BACKWARD: - case LFUN_CELL_FORWARD: - unlockInsetInInset(bv, the_locking_inset); - if (cmd.action == LFUN_CELL_FORWARD) - moveNextCell(bv, old_locking_inset != 0); - else - movePrevCell(bv, old_locking_inset != 0); - clearSelection(); - if (hs) - updateLocal(bv); - if (!the_locking_inset) - return DISPATCHED_NOUPDATE; - return result; - // this to avoid compiler warnings. - default: + // we'll pop up the table dialog on release + if (cmd.button() == mouse_button::button3) break; - } - } + break; - kb_action action = cmd.action; - string arg = cmd.argument; - if (the_locking_inset) { - result = the_locking_inset->localDispatch(cmd); - if (result == DISPATCHED_NOUPDATE) { - int sc = scroll(); - resetPos(bv); - if (sc != scroll()) { // inset has been scrolled - updateLocal(bv); + 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; } - return result; - } else if (result == DISPATCHED) { - updateLocal(bv); - return result; - } else if (result == FINISHED_UP) { - action = LFUN_UP; - // Make sure to reset status message after - // exiting, e.g. math inset - bv->owner()->clearMessage(); - } else if (result == FINISHED_DOWN) { - action = LFUN_DOWN; - bv->owner()->clearMessage(); - } else if (result == FINISHED_RIGHT) { - action = LFUN_RIGHT; - bv->owner()->clearMessage(); - } else if (result == FINISHED) { - bv->owner()->clearMessage(); } - } + break; - result = DISPATCHED; - switch (action) { - // --- Cursor Movements ---------------------------------- - 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); - updateLocal(bv); + case LFUN_CELL_BACKWARD: + movePrevCell(cur); + cur.selection() = false; break; - } - case LFUN_RIGHT: - result = moveRight(bv); - clearSelection(); - if (hs) - updateLocal(bv); + + 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); - updateLocal(bv); break; - } + + case LFUN_LEFTSEL: case LFUN_LEFT: - result = moveLeft(bv); - clearSelection(); - if (hs) - updateLocal(bv); - 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(); } - updateLocal(bv); - } - break; - case LFUN_DOWN: - result = moveDown(bv, old_locking_inset != 0); - clearSelection(); - if (hs) - updateLocal(bv); 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); + + case LFUN_DOWNSEL: + case LFUN_DOWN: + 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(); } - updateLocal(bv); - } - break; + break; + + case LFUN_UPSEL: case LFUN_UP: - result = moveUp(bv, old_locking_inset != 0); - clearSelection(); - if (hs) - updateLocal(bv); + 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; - unlockInsetInInset(bv, the_locking_inset); - if (bv->top_y() + bv->painter().paperHeight() < - top_baseline + tabular.getHeightOfTabular()) - { - bv->scrollDocView(bv->top_y() + bv->painter().paperHeight()); - actcell = tabular.getCellBelow(first_visible_cell) + column; - } else { - actcell = tabular.getFirstCellInRow(tabular.rows() - 1) + column; - } - resetPos(bv); - updateLocal(bv); + if (cur.bv().top_y() + cur.bv().painter().paperHeight() + < yo() + tabular.getHeightOfTabular()) + { + cur.bv().scrollDocView( + cur.bv().top_y() + cur.bv().painter().paperHeight()); + cur.idx() = tabular.getCellBelow(first_visible_cell) + column; + } else { + cur.idx() = tabular.getFirstCellInRow(tabular.rows() - 1) + column; + } + resetPos(cur); break; } + case LFUN_PRIOR: { - if (hs) - clearSelection(); - int column = actcol; - unlockInsetInInset(bv, the_locking_inset); - if (top_baseline < 0) { - bv->scrollDocView(bv->top_y() - bv->painter().paperHeight()); - if (top_baseline > 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); - updateLocal(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); + + case LFUN_LAYOUT_TABULAR: + InsetTabularMailer(*this).showDialog(&cur.bv()); break; - } - case LFUN_INSET_DIALOG_UPDATE: { - InsetTabularMailer(*this).updateDialog(bv); + + case LFUN_INSET_DIALOG_UPDATE: + InsetTabularMailer(*this).updateDialog(&cur.bv()); break; - } + case LFUN_TABULAR_FEATURE: - if (!tabularFeatures(bv, arg)) - result = UNDISPATCHED; + if (!tabularFeatures(cur, cmd.argument)) + cur.undispatched(); break; - // insert file functions + + // insert file functions case LFUN_FILE_INSERT_ASCII_PARA: - case LFUN_FILE_INSERT_ASCII: - { - string tmpstr = getContentsOfAsciiFile(bv, arg, false); - if (tmpstr.empty()) - break; - if (insertAsciiString(bv, tmpstr, false)) - updateLocal(bv); - else - result = UNDISPATCHED; + case LFUN_FILE_INSERT_ASCII: { + string tmpstr = getContentsOfAsciiFile(&cur.bv(), cmd.argument, false); + if (!tmpstr.empty() && !insertAsciiString(cur.bv(), tmpstr, false)) + cur.undispatched(); break; } - // cut and paste functions + case LFUN_CUT: - if (!copySelection(bv)) - break; - // no break here! + if (copySelection(cur)) { + recordUndo(cur, Undo::DELETE); + cutSelection(cur); + } + break; + + case LFUN_BACKSPACE: case LFUN_DELETE: - recordUndo(bv, Undo::DELETE); - cutSelection(bv->buffer()->params()); - updateLocal(bv); + 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()); - if (clip.empty()) + + case LFUN_PASTESELECTION: { + 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); - delete paste_tabular; - paste_tabular = new LyXTabular(bv->buffer()->params(), - this, rows, maxCols); + + paste_tabular.reset( + 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! - delete paste_tabular; - paste_tabular = 0; + paste_tabular.reset(); } + // fall through } + case LFUN_PASTE: if (hasPasteBuffer()) { - recordUndo(bv, Undo::INSERT); - pasteSelection(bv); - updateLocal(bv); + recordUndo(cur, Undo::INSERT); + pasteSelection(cur); break; } - // 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 = UNDISPATCHED; - if (hs) { - switch(action) { - 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: - if (bv->dispatch(FuncRequest(bv, action, arg))) - result = DISPATCHED; - break; - default: + // 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; } } - // we try to activate the actual inset and put this event down to - // the insets dispatch function. - if (result == DISPATCHED || the_locking_inset) - break; - if (activateCellInset(bv)) { - result = the_locking_inset->localDispatch(FuncRequest(bv, action, arg)); - if (result == UNDISPATCHED || result >= FINISHED) { - unlockInsetInInset(bv, the_locking_inset); - // we need to update if this was requested before - updateLocal(bv); - return UNDISPATCHED; - } - if (hs) - clearSelection(); - updateLocal(bv); - return result; + if (action == LyXTabular::LAST_ACTION) { + status.clear(); + status.unknown(true); + return true; } - break; - } - if (result < FINISHED) { - if (!the_locking_inset && bv->fitCursor()) - updateLocal(bv); - } else - bv->unlockInset(this); - return result; -} + 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; -int InsetTabular::latex(Buffer const & buf, ostream & os, - LatexRunParams const & runparams) const -{ - return tabular.latex(buf, os, runparams); -} + 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; -int InsetTabular::ascii(Buffer const & buf, ostream & os, int ll) const -{ - if (ll > 0) - return tabular.ascii(buf, os, ownerPar(buf, this).params().depth(), - false, 0); - return tabular.ascii(buf, os, 0, false, 0); -} + 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; -int InsetTabular::linuxdoc(Buffer const & buf, ostream & os) const -{ - return tabular.linuxdoc(buf,os); -} + 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; -int InsetTabular::docbook(Buffer const & buf, ostream & os, bool mixcont) const + 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; + } + + default: + // we try to handle this event in the insets dispatch function. + return cell(cur.idx()).getStatus(cur, cmd, status); + } +} + + +int InsetTabular::latex(Buffer const & buf, ostream & os, + OutputParams const & runparams) const +{ + return tabular.latex(buf, os, runparams); +} + + +int InsetTabular::plaintext(Buffer const & buf, ostream & os, + OutputParams const & runparams) const +{ + int dp = runparams.linelen ? runparams.depth : 0; + return tabular.plaintext(buf, os, runparams, dp, false, 0); +} + + +int InsetTabular::linuxdoc(Buffer const & buf, ostream & os, + OutputParams const & runparams) const +{ + return tabular.linuxdoc(buf,os, runparams); +} + + +int InsetTabular::docbook(Buffer const & buf, ostream & os, + 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 << ""; - if (mixcont) + if (runparams.mixed_content) os << endl; ++ret; } - ret += tabular.docbook(buf, os, mixcont); + ret += tabular.docbook(buf, os, runparams); if (!master) { os << ""; - if (mixcont) + if (runparams.mixed_content) os << endl; ++ret; } @@ -1134,127 +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); - } -} - - -void InsetTabular::getCursor(BufferView & bv, int & x, int & y) const -{ - if (the_locking_inset) { - the_locking_inset->getCursor(bv, x, y); - return; - } - - x = cursorx_; - y = cursory_ + InsetTabular::y(); - - // Fun stuff - int desc = tabular.getDescentOfRow(actrow); - y += desc; - int ascdesc = tabular.getAscentOfRow(actrow) + desc; - y -= ascdesc / 2; - y += ADD_TO_HEIGHT * 2; - y += TEXT_TO_INSET_OFFSET; + return tabular.getCellInset(idx); } -void InsetTabular::getCursorPos(BufferView * bv, int & x, int & y) const +InsetText & InsetTabular::cell(int idx) { - if (the_locking_inset) { - the_locking_inset->getCursorPos(bv, x, y); - return; - } - x = cursorx_ - top_x; - y = cursory_; + return tabular.getCellInset(idx); } -void InsetTabular::fitInsetCursor(BufferView * bv) const +void InsetTabular::getCursorPos(LCursor const & cur, int & x, int & y) const { - if (the_locking_inset) { - the_locking_inset->fitInsetCursor(bv); - return; - } - - LyXFont font; - int const asc = font_metrics::maxAscent(font); - int const desc = font_metrics::maxDescent(font); - resetPos(bv); - - bv->fitLockedInsetCursor(cursorx_, cursory_, asc, desc); + cell(cur.idx()).getCursorPos(cur, x, y); } -void InsetTabular::setPos(BufferView * bv, int x, int y) const +InsetBase * InsetTabular::setPos(LCursor & cur, int x, int y) const { - cursory_ = 0; - actcell = actrow = 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); + 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; + } } - actcell = tabular.getCellNumber(actrow, actcol); - - // now search the right column - int lx = tabular.getWidthOfColumn(actcell) - - tabular.getAdditionalWidth(actcell); - - for (; !tabular.isLastCellInRow(actcell) && lx < x; ++actcell) - lx += tabular.getWidthOfColumn(actcell + 1) - + tabular.getAdditionalWidth(actcell); - - cursorx_ = lx - tabular.getWidthOfColumn(actcell) + top_x + 2; - resetPos(bv); + cur.idx() = idx_min; + InsetBase * inset = cell(cur.idx()).text_.editXY(cur, x, y); + //lyxerr << "# InsetTabular::setPos()\n" << cur << endl; + return inset; } @@ -1268,256 +991,95 @@ int InsetTabular::getCellXPos(int cell) const for (; c < cell; ++c) lx += tabular.getWidthOfColumn(c); - return (lx - tabular.getWidthOfColumn(cell) + top_x); + 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; + BufferView & bv = cur.bv(); + int actcell = cur.idx(); + int actcol = tabular.column_of_cell(actcell); - 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; - } - } - if (!locked) { - if (the_locking_inset) - inset_y = cursory_; - return; - } - // we need this only from here on!!! - ++in_reset_pos; int const offset = ADD_TO_TABULAR_WIDTH + 2; - int new_x = getCellXPos(actcell); + int new_x = getCellXPos(actcell) + offset; int old_x = cursorx_; - new_x += offset; 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 + bv->text->getRealCursorX(); - 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) { - scroll(bv, -tabular.getWidthOfColumn(actcell) - 20); - updateLocal(bv); + > bv.workWidth() - 20) { + scroll(bv, - tabular.getWidthOfColumn(actcell) - 20); } else if (cursorx_ - offset < 20) { scroll(bv, 20 - cursorx_ + offset); - updateLocal(bv); - } else if (scroll() && top_x > 20 && - (top_x + tabular.getWidthOfTabular()) > bv->workWidth() - 20) { + } else if (scroll() && xo() > 20 && + xo() + tabular.getWidthOfTabular() > bv.workWidth() - 20) { scroll(bv, old_x - cursorx_); - updateLocal(bv); - } - if (the_locking_inset) { - inset_x = cursorx_ - top_x + tabular.getBeginningOfTextInCell(actcell); - inset_y = cursory_; } - if ((!the_locking_inset || - !the_locking_inset->getFirstLockingInsetOfType(TABULAR_CODE)) && - actcell != oldcell) { - InsetTabularMailer(*this).updateDialog(bv); - oldcell = actcell; - } - in_reset_pos = 0; -} - -dispatch_result InsetTabular::moveRight(BufferView * bv, bool lock) -{ - if (lock && !old_locking_inset) { - if (activateCellInset(bv)) - return DISPATCHED; - } else { - bool moved = isRightToLeft(bv) - ? movePrevCell(bv) : moveNextCell(bv); - if (!moved) - return FINISHED_RIGHT; - if (lock && activateCellInset(bv)) - return DISPATCHED; - } - resetPos(bv); - return DISPATCHED_NOUPDATE; -} - - -dispatch_result InsetTabular::moveLeft(BufferView * bv, bool lock) -{ - bool moved = isRightToLeft(bv) ? moveNextCell(bv) : movePrevCell(bv); - if (!moved) - return FINISHED; - if (lock) { // behind the inset - if (activateCellInset(bv, 0, 0, mouse_button::none, true)) - return DISPATCHED; - } - resetPos(bv); - return DISPATCHED_NOUPDATE; -} - - -dispatch_result InsetTabular::moveUp(BufferView * bv, bool lock) -{ - int const ocell = actcell; - actcell = tabular.getCellAbove(actcell); - if (actcell == ocell) // we moved out of the inset - return FINISHED_UP; - resetPos(bv); - if (lock) { - int x = 0; - int y = 0; - if (old_locking_inset) { - old_locking_inset->getCursorPos(bv, x, y); - x -= cursorx_ + tabular.getBeginningOfTextInCell(actcell); - } - if (activateCellInset(bv, x, 0)) - return DISPATCHED; - } - return DISPATCHED_NOUPDATE; + InsetTabularMailer(*this).updateDialog(&bv); } -dispatch_result InsetTabular::moveDown(BufferView * bv, bool lock) +void InsetTabular::moveNextCell(LCursor & cur) { - int const ocell = actcell; - actcell = tabular.getCellBelow(actcell); - if (actcell == ocell) // we moved out of the inset - return FINISHED_DOWN; - resetPos(bv); - if (lock) { - int x = 0; - int y = 0; - if (old_locking_inset) { - old_locking_inset->getCursorPos(bv, x, y); - x -= cursorx_ + tabular.getBeginningOfTextInCell(actcell); - } - if (activateCellInset(bv, x, 0)) - return DISPATCHED; - } - return DISPATCHED_NOUPDATE; -} - - -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, mouse_button::none, !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) { - if (isRightToLeft(bv)) { - 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 { - if (!actcell) // first cell - return false; - --actcell; - } - if (lock) { - bool rtl = tabular.getCellInset(actcell).paragraphs.begin()-> - isRightToLeftPar(bv->buffer()->params()); - activateCellInset(bv, 0, 0, mouse_button::none, !rtl); - } - resetPos(bv); - 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; @@ -1537,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, @@ -1561,13 +1124,14 @@ void checkLongtableSpecial(LyXTabular::ltType & ltt, } } -} +} // anon namespace -void InsetTabular::tabularFeatures(BufferView * bv, - LyXTabular::Feature feature, - string const & value) +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; @@ -1616,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; @@ -1631,103 +1190,71 @@ void InsetTabular::tabularFeatures(BufferView * bv, switch (feature) { - case LyXTabular::SET_PWIDTH: - { + case LyXTabular::SET_PWIDTH: { LyXLength const len(value); - LyXLength const & oldlen = tabular.getColumnPWidth(actcell); - tabular.setColumnPWidth(actcell, len); - if (oldlen != len) { - // We need this otherwise we won't resize - // the insettext of the active cell (if any) - // until later (see InsetText::do_resize) - unlockInsetInInset(bv, the_locking_inset); - bv->update(); - } - 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; } case LyXTabular::SET_MPWIDTH: - { - LyXLength const len(value); - LyXLength const & oldlen = tabular.getPWidth(actcell); - tabular.setMColumnPWidth(actcell, len); - if (oldlen != len) { - // We need this otherwise we won't resize - // the insettext of the active cell (if any) - // until later (see InsetText::do_resize) - unlockInsetInInset(bv, the_locking_inset); - updateLocal(bv); - } - } - break; + tabular.setMColumnPWidth(actcell, LyXLength(value)); + break; + case LyXTabular::SET_SPECIAL_COLUMN: case LyXTabular::SET_SPECIAL_MULTI: tabular.setAlignSpecial(actcell,value,feature); - updateLocal(bv); break; + case LyXTabular::APPEND_ROW: // append the row into the tabular - unlockInsetInInset(bv, the_locking_inset); - tabular.appendRow(bv->buffer()->params(), actcell); - tabular.setOwner(this); - updateLocal(bv); + tabular.appendRow(bv.buffer()->params(), actcell); break; + case LyXTabular::APPEND_COLUMN: // append the column into the tabular - unlockInsetInInset(bv, the_locking_inset); - tabular.appendColumn(bv->buffer()->params(), actcell); - tabular.setOwner(this); + tabular.appendColumn(bv.buffer()->params(), actcell); actcell = tabular.getCellNumber(row, column); - updateLocal(bv); break; + case LyXTabular::DELETE_ROW: - unlockInsetInInset(bv, the_locking_inset); - for(int i = sel_row_start; i <= sel_row_end; ++i) { + for (int i = sel_row_start; i <= sel_row_end; ++i) tabular.deleteRow(sel_row_start); - } if (sel_row_start >= tabular.rows()) --sel_row_start; actcell = tabular.getCellNumber(sel_row_start, column); - clearSelection(); - updateLocal(bv); + cur.selection() = false; break; + case LyXTabular::DELETE_COLUMN: - unlockInsetInInset(bv, the_locking_inset); - for(int i = sel_col_start; i <= sel_col_end; ++i) { + for (int i = sel_col_start; i <= sel_col_end; ++i) tabular.deleteColumn(sel_col_start); - } if (sel_col_start >= tabular.columns()) --sel_col_start; actcell = tabular.getCellNumber(row, sel_col_start); - clearSelection(); - updateLocal(bv); + cur.selection() = false; break; + case LyXTabular::M_TOGGLE_LINE_TOP: flag = false; - case LyXTabular::TOGGLE_LINE_TOP: - { + case LyXTabular::TOGGLE_LINE_TOP: { bool lineSet = !tabular.topLine(actcell, flag); for (int i = sel_row_start; i <= sel_row_end; ++i) for (int j = sel_col_start; j <= sel_col_end; ++j) tabular.setTopLine( tabular.getCellNumber(i, j), lineSet, flag); - updateLocal(bv); break; } case LyXTabular::M_TOGGLE_LINE_BOTTOM: flag = false; - case LyXTabular::TOGGLE_LINE_BOTTOM: - { + case LyXTabular::TOGGLE_LINE_BOTTOM: { bool lineSet = !tabular.bottomLine(actcell, flag); for (int i = sel_row_start; i <= sel_row_end; ++i) for (int j = sel_col_start; j <= sel_col_end; ++j) @@ -1735,14 +1262,12 @@ void InsetTabular::tabularFeatures(BufferView * bv, tabular.getCellNumber(i, j), lineSet, flag); - updateLocal(bv); break; } case LyXTabular::M_TOGGLE_LINE_LEFT: flag = false; - case LyXTabular::TOGGLE_LINE_LEFT: - { + case LyXTabular::TOGGLE_LINE_LEFT: { bool lineSet = !tabular.leftLine(actcell, flag); for (int i = sel_row_start; i <= sel_row_end; ++i) for (int j = sel_col_start; j <= sel_col_end; ++j) @@ -1750,14 +1275,12 @@ void InsetTabular::tabularFeatures(BufferView * bv, tabular.getCellNumber(i,j), lineSet, flag); - updateLocal(bv); break; } case LyXTabular::M_TOGGLE_LINE_RIGHT: flag = false; - case LyXTabular::TOGGLE_LINE_RIGHT: - { + case LyXTabular::TOGGLE_LINE_RIGHT: { bool lineSet = !tabular.rightLine(actcell, flag); for (int i = sel_row_start; i <= sel_row_end; ++i) for (int j = sel_col_start; j <= sel_col_end; ++j) @@ -1765,7 +1288,6 @@ void InsetTabular::tabularFeatures(BufferView * bv, tabular.getCellNumber(i,j), lineSet, flag); - updateLocal(bv); break; } @@ -1783,7 +1305,6 @@ void InsetTabular::tabularFeatures(BufferView * bv, tabular.getCellNumber(i, j), setAlign, flag); - updateLocal(bv); break; case LyXTabular::M_VALIGN_TOP: @@ -1798,7 +1319,6 @@ void InsetTabular::tabularFeatures(BufferView * bv, tabular.setVAlignment( tabular.getCellNumber(i, j), setVAlign, flag); - updateLocal(bv); break; case LyXTabular::MULTICOLUMN: { @@ -1810,14 +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); - updateLocal(bv); + tabular.setMultiColumn(bv.buffer(), actcell, 1); break; } // we have a selection so this means we just add all this @@ -1832,31 +1352,30 @@ 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(); - updateLocal(bv); +#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); - updateLocal(bv); +#endif break; case LyXTabular::SET_LONGTABULAR: tabular.setLongTabular(true); - updateLocal(bv); // because this toggles displayed break; case LyXTabular::UNSET_LONGTABULAR: tabular.setLongTabular(false); - updateLocal(bv); // because this toggles displayed break; case LyXTabular::SET_ROTATE_TABULAR: @@ -1869,7 +1388,7 @@ void InsetTabular::tabularFeatures(BufferView * bv, case LyXTabular::SET_ROTATE_CELL: for (int i = sel_row_start; i <= sel_row_end; ++i) - for (int j = sel_col_start; j<=sel_col_end; ++j) + for (int j = sel_col_start; j <= sel_col_end; ++j) tabular.setRotateCell( tabular.getCellNumber(i, j), true); break; @@ -1923,303 +1442,53 @@ void InsetTabular::tabularFeatures(BufferView * bv, tabular.setLTFoot(row, flag, ltt, true); break; - case LyXTabular::SET_LTNEWPAGE: { - bool what = !tabular.getLTNewPage(row); - tabular.setLTNewPage(row, what); + case LyXTabular::SET_LTNEWPAGE: + tabular.setLTNewPage(row, !tabular.getLTNewPage(row)); break; - } // dummy stuff just to avoid warnings case LyXTabular::LAST_ACTION: break; } - InsetTabularMailer(*this).updateDialog(bv); -} - - -bool InsetTabular::activateCellInset(BufferView * bv, int x, int y, - mouse_button::state button, bool behind) -{ - UpdatableInset & inset = tabular.getCellInset(actcell); - if (behind) { -#warning metrics? - x = inset.x() + inset.width(); - y = inset.descent(); - } - //inset_x = cursorx_ - top_x + tabular.getBeginningOfTextInCell(actcell); - //inset_y = cursory_; - inset.localDispatch(FuncRequest(bv, LFUN_INSET_EDIT, x, y, button)); - if (!the_locking_inset) - return false; - updateLocal(bv); - return the_locking_inset; -} - - -bool InsetTabular::activateCellInsetAbs(BufferView * bv, int x, int y, - mouse_button::state button) -{ - inset_x = cursorx_ - top_x + tabular.getBeginningOfTextInCell(actcell); - inset_y = cursory_; - return activateCellInset(bv, x - inset_x, y - inset_y, button); -} - - -bool InsetTabular::insetHit(BufferView *, int x, int) const -{ - return x + top_x > cursorx_ + tabular.getBeginningOfTextInCell(actcell); -} - - -void InsetTabular::deleteLyXText(BufferView * /*bv*/, bool /*recursive*/) const -{ - //resizeLyXText(bv, recursive); -} - - -LyXText * InsetTabular::getLyXText(BufferView const * bv, - bool const recursive) const -{ - if (the_locking_inset) - return the_locking_inset->getLyXText(bv, recursive); - return InsetOld::getLyXText(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 { - 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(); - return status.unknown(true); - } - - 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: - return status.clear(); - - 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); - delete paste_tabular; - paste_tabular = new LyXTabular(tabular); - paste_tabular->setOwner(this); + paste_tabular.reset(new LyXTabular(tabular)); - 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); @@ -2227,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); @@ -2239,18 +1508,20 @@ bool InsetTabular::copySelection(BufferView * bv) true, true); ostringstream os; - paste_tabular->ascii(*bv->buffer(), os, - 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) { @@ -2270,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(); } } @@ -2279,272 +1548,92 @@ bool InsetTabular::pasteSelection(BufferView * bv) } -bool InsetTabular::cutSelection(BufferParams const & bp) -{ - 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; -} - - -bool InsetTabular::isRightToLeft(BufferView * bv) +void InsetTabular::cutSelection(LCursor & cur) { - return bv->getParentLanguage(this)->RightToLeft(); -} - - -int InsetTabular::scroll(bool recursive) const -{ - int sx = UpdatableInset::scroll(false); - - if (recursive && the_locking_inset) - sx += the_locking_inset->scroll(recursive); - - return sx; -} - - -void InsetTabular::getSelection(int & srow, int & erow, - int & scol, int & ecol) 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); -} - + if (!cur.selection()) + return; -ParagraphList * InsetTabular::getParagraphs(int i) const -{ - return (i < tabular.getNumberOfCells()) - ? tabular.getCellInset(i).getParagraphs(0) - : 0; + 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); } -LyXCursor const & InsetTabular::cursor(BufferView * bv) const +bool InsetTabular::isRightToLeft(LCursor & cur) const { - if (the_locking_inset) - return the_locking_inset->cursor(bv); - return InsetOld::cursor(bv); + 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(); } -InsetOld * InsetTabular::getInsetFromID(int id_arg) const +void InsetTabular::getSelection(LCursor & cur, + int & rs, int & re, int & cs, int & ce) const { - if (id_arg == id()) - return const_cast(this); - - for (int i = 0; i < tabular.rows(); ++i) { - for (int j = 0; j < tabular.columns(); ++j) { - InsetOld * inset = tabular.getCellInset(i, j).getInsetFromID(id_arg); - if (inset) - return inset; - } + 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()); } - return 0; -} - -WordLangTuple const -InsetTabular::selectNextWordToSpellcheck(BufferView * bv, float & value) const -{ - if (the_locking_inset) { - WordLangTuple word(the_locking_inset->selectNextWordToSpellcheck(bv, value)); - if (!word.word().empty()) - return word; - if (tabular.isLastCell(actcell)) { - bv->unlockInset(const_cast(this)); - return WordLangTuple(); - } - ++actcell; - } - // otherwise we have to lock the next inset and ask for it's selecttion - tabular.getCellInset(actcell) - .localDispatch(FuncRequest(bv, LFUN_INSET_EDIT)); - WordLangTuple word(selectNextWordInt(bv, value)); - if (!word.word().empty()) - resetPos(bv); - return word; + rs = tabular.row_of_cell(beg.idx()); + re = tabular.row_of_cell(end.idx()); + if (rs > re) + swap(rs, re); } -WordLangTuple InsetTabular::selectNextWordInt(BufferView * bv, float & value) const +size_t InsetTabular::nargs() const { - // when entering this function the inset should be ALWAYS locked! - BOOST_ASSERT(the_locking_inset); - - WordLangTuple word(the_locking_inset->selectNextWordToSpellcheck(bv, value)); - if (!word.word().empty()) - return word; - - if (tabular.isLastCell(actcell)) { - bv->unlockInset(const_cast(this)); - return WordLangTuple(); - } - - // otherwise we have to lock the next inset and ask for it's selecttion - ++actcell; - tabular.getCellInset(actcell) - .localDispatch(FuncRequest(bv, LFUN_INSET_EDIT)); - return selectNextWordInt(bv, value); + return tabular.getNumberOfCells(); } -void InsetTabular::selectSelectedWord(BufferView * bv) +LyXText * InsetTabular::getText(int idx) const { - if (the_locking_inset) - the_locking_inset->selectSelectedWord(bv); + 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(); -} - - -bool InsetTabular::nextChange(BufferView * bv, lyx::pos_type & length) -{ - if (the_locking_inset) { - if (the_locking_inset->nextChange(bv, length)) { - updateLocal(bv); - return true; - } - if (tabular.isLastCell(actcell)) - return false; - ++actcell; - } - InsetText & inset = tabular.getCellInset(actcell); - if (inset.nextChange(bv, length)) { - updateLocal(bv); - return true; - } - while (!tabular.isLastCell(actcell)) { - ++actcell; - InsetText & inset = tabular.getCellInset(actcell); - if (inset.nextChange(bv, length)) { - updateLocal(bv); - return true; - } - } - return false; -} - - -bool InsetTabular::searchForward(BufferView * bv, string const & str, - bool cs, bool mw) -{ - int cell = 0; - if (the_locking_inset) { - if (the_locking_inset->searchForward(bv, str, cs, mw)) { - updateLocal(bv); - return true; - } - if (tabular.isLastCell(actcell)) - return false; - cell = actcell + 1; - } - InsetText & inset = tabular.getCellInset(cell); - if (inset.searchForward(bv, str, cs, mw)) { - updateLocal(bv); - return true; - } - while (!tabular.isLastCell(cell)) { - ++cell; - InsetText & inset = tabular.getCellInset(cell); - if (inset.searchForward(bv, str, cs, mw)) { - updateLocal(bv); - return true; - } - } - return false; + for (idx_type idx = 0; idx < nargs(); ++idx) + cell(idx).markErased(); } -bool InsetTabular::searchBackward(BufferView * bv, string const & str, - bool cs, bool mw) -{ - int cell = tabular.getNumberOfCells(); - if (the_locking_inset) { - if (the_locking_inset->searchBackward(bv, str, cs, mw)) { - updateLocal(bv); - return true; - } - cell = actcell; - } - - while (cell) { - --cell; - InsetText & inset = tabular.getCellInset(cell); - if (inset.searchBackward(bv, str, cs, mw)) { - updateLocal(bv); - return true; - } - } - return false; -} - - -bool InsetTabular::insetAllowed(InsetOld::Code code) const -{ - if (the_locking_inset) - return the_locking_inset->insetAllowed(code); - // we return true here because if the inset is not locked someone - // wants to insert something in one of our insettexts and we generally - // allow to do so. - return true; -} - - -bool InsetTabular::forceDefaultParagraphs(InsetOld const * in) const +bool InsetTabular::forceDefaultParagraphs(InsetBase const *) const { +#if 0 const int cell = tabular.getCellFromInset(in); if (cell != -1) return tabular.getPWidth(cell).zero(); + // this is a workaround for a crash (New, Insert->Tabular, + // Insert->FootNote) + if (!owner()) + return false; + // well we didn't obviously find it so maybe our owner knows more BOOST_ASSERT(owner()); return owner()->forceDefaultParagraphs(in); +#endif + return false; } -bool InsetTabular::insertAsciiString(BufferView * bv, string const & buf, +bool InsetTabular::insertAsciiString(BufferView & bv, string const & buf, bool usePaste) { if (buf.length() <= 0) @@ -2556,13 +1645,17 @@ 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': ++cols; break; case '\n': - if ((p+1) < len) + if (p + 1 < len) ++rows; maxCols = max(cols, maxCols); cols = 1; @@ -2576,11 +1669,9 @@ bool InsetTabular::insertAsciiString(BufferView * bv, string const & buf, int ocol = 0; int row = 0; if (usePaste) { - delete paste_tabular; - paste_tabular = new LyXTabular(bv->buffer()->params(), - rows, maxCols); - paste_tabular->setOwner(this); - loctab = paste_tabular; + paste_tabular.reset( + new LyXTabular(bv.buffer()->params(), rows, maxCols)); + loctab = paste_tabular.get(); cols = 0; } else { loctab = &tabular; @@ -2606,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.getLyXText(bv)-> - 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; @@ -2617,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.getLyXText(bv)-> - 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; @@ -2633,11 +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.getLyXText(bv)-> - 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; } @@ -2646,12 +1736,22 @@ void InsetTabular::addPreview(PreviewLoader & loader) const { int const rows = tabular.rows(); int const columns = tabular.columns(); - for (int i = 0; i < rows; ++i) + for (int i = 0; i < rows; ++i) { for (int j = 0; j < columns; ++j) tabular.getCellInset(i, j).addPreview(loader); + } } +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) @@ -2671,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; @@ -2715,11 +1817,13 @@ int InsetTabularMailer::string2params(string const & in, InsetTabular & inset) string const InsetTabularMailer::params2string(InsetTabular const & inset) { - Buffer const & buffer = inset.buffer(); - ostringstream data; - data << name_ << " \\active_cell " << inset.getActCell() << '\n'; - inset.write(buffer, data); +#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(); }