From: André Pönitz Date: Tue, 14 Oct 2003 13:01:49 +0000 (+0000) Subject: In insets: X-Git-Tag: 1.6.10~15947 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=5c2f0c5c4642d9302a9bb7d19327a7dc4539f079;p=features.git In insets: 2003-10-14 Andr� P�nitz * insetcollapsable.[Ch]: * insettabular.[Ch]: * insettext.[Ch]: * inset.h: getText() as alternative to getParagraphs() In src: 2003-10-14 Andr� P�nitz * iterators.[Ch]: new direct access to innermost LyXText and Inset * undo.[Ch]: restoring part of 'undo in insets' * Makefile.am: * undo_funcs.[Ch]: merge with undo.[Ch] * tabular.C: small cleansing stuff git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7919 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/BufferView.C b/src/BufferView.C index 88a8456d9d..f4b655850b 100644 --- a/src/BufferView.C +++ b/src/BufferView.C @@ -28,7 +28,7 @@ #include "paragraph.h" #include "paragraph_funcs.h" #include "texrow.h" -#include "undo_funcs.h" +#include "undo.h" #include "WordLangTuple.h" #include "frontends/Alert.h" diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 939d590d05..b51094424b 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -42,7 +42,7 @@ #include "paragraph_funcs.h" #include "ParagraphParameters.h" #include "TextCache.h" -#include "undo_funcs.h" +#include "undo.h" #include "vspace.h" #include "insets/insetfloatlist.h" diff --git a/src/ChangeLog b/src/ChangeLog index d97f9b4f97..62ba735680 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ + + +2003-10-14 André Pönitz + + * iterators.[Ch]: new direct access to innermost LyXText and Inset + + * undo.[Ch]: restoring part of 'undo in insets' + + * Makefile.am: + * undo_funcs.[Ch]: merge with undo.[Ch] + + * tabular.C: small cleansing stuff + 2003-10-14 Alfredo Braunstein * paragraph_funcs.C (readParToken): report unknown insets as error diff --git a/src/InsetList.C b/src/InsetList.C index 33200216ae..ef21a07310 100644 --- a/src/InsetList.C +++ b/src/InsetList.C @@ -182,11 +182,9 @@ void InsetList::deleteInsetsLyXText(BufferView * bv) List::iterator it = list.begin(); List::iterator end = list.end(); for (; it != end; ++it) { - if (it->inset) { - if (it->inset->isTextInset()) { - static_cast - (it->inset)->deleteLyXText(bv, true); - } + if (it->inset && it->inset->isTextInset()) { + static_cast + (it->inset)->deleteLyXText(bv, true); } } } diff --git a/src/Makefile.am b/src/Makefile.am index 9a54e1107a..e3a938b5a2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -260,8 +260,6 @@ lyx_SOURCES = \ trans_mgr.h \ undo.C \ undo.h \ - undo_funcs.C \ - undo_funcs.h \ vc-backend.C \ vc-backend.h \ version.C \ diff --git a/src/debug.h b/src/debug.h index 30fcd2501e..d19d350913 100644 --- a/src/debug.h +++ b/src/debug.h @@ -13,7 +13,6 @@ #ifndef LYXDEBUG_H #define LYXDEBUG_H - #include "support/debugstream.h" /** Ideally this should have been a namespace, but since we try to be diff --git a/src/insets/ChangeLog b/src/insets/ChangeLog index f283c448a5..90585a65e9 100644 --- a/src/insets/ChangeLog +++ b/src/insets/ChangeLog @@ -1,3 +1,11 @@ + +2003-10-14 André Pönitz + + * insetcollapsable.[Ch]: + * insettabular.[Ch]: + * insettext.[Ch]: + * inset.h: getText() as alternative to getParagraphs() + 2003-10-13 Angus Leeming * insetexternal.C: diff --git a/src/insets/inset.h b/src/insets/inset.h index 5e8cd824be..dcfad21748 100644 --- a/src/insets/inset.h +++ b/src/insets/inset.h @@ -233,6 +233,8 @@ public: /// should return it's very first one! virtual ParagraphList * getParagraphs(int /*num*/) const { return 0; } /// + virtual LyXText * getText(int /*num*/) const { return 0; } + /// virtual bool haveParagraphs() const { return false; } diff --git a/src/insets/insetcollapsable.C b/src/insets/insetcollapsable.C index c54f763e4f..3e5eb44570 100644 --- a/src/insets/insetcollapsable.C +++ b/src/insets/insetcollapsable.C @@ -456,6 +456,12 @@ ParagraphList * InsetCollapsable::getParagraphs(int i) const } +LyXText * InsetCollapsable::getText(int i) const +{ + return inset.getText(i); +} + + LyXCursor const & InsetCollapsable::cursor(BufferView * bv) const { return inset.cursor(bv); diff --git a/src/insets/insetcollapsable.h b/src/insets/insetcollapsable.h index 37e61f70f1..a1a4b10b60 100644 --- a/src/insets/insetcollapsable.h +++ b/src/insets/insetcollapsable.h @@ -118,6 +118,8 @@ public: /// ParagraphList * getParagraphs(int) const; /// + LyXText * getText(int) const; + /// LyXCursor const & cursor(BufferView *) const; /// bool isOpen() const; diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index c9f84033f9..283e62f1e9 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -27,7 +27,7 @@ #include "paragraph.h" #include "paragraph_funcs.h" #include "ParagraphParameters.h" -#include "undo_funcs.h" +#include "undo.h" #include "WordLangTuple.h" #include "frontends/Alert.h" @@ -427,13 +427,17 @@ bool InsetTabular::lockInsetInInset(BufferView * bv, UpdatableInset * inset) << 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) { + } + + if (!the_locking_inset) { int const n = tabular.getNumberOfCells(); int const id = inset->id(); for (int i = 0; i < n; ++i) { @@ -451,13 +455,20 @@ bool InsetTabular::lockInsetInInset(BufferView * bv, UpdatableInset * inset) return the_locking_inset->lockInsetInInset(bv, inset); } } - } else if (the_locking_inset && (the_locking_inset == inset)) { + return false; + } + + if (the_locking_inset && (the_locking_inset == inset)) { lyxerr[Debug::INSETTEXT] << "OK" << endl; resetPos(bv); - } else if (the_locking_inset) { + return false; + } + + if (the_locking_inset) { lyxerr[Debug::INSETTEXT] << "MAYBE" << endl; return the_locking_inset->lockInsetInInset(bv, inset); } + lyxerr[Debug::INSETTEXT] << "NOT OK" << endl; return false; } @@ -551,7 +562,7 @@ void InsetTabular::lfunMousePress(FuncRequest const & cmd) bool const inset_hit = insetHit(bv, cmd.x, cmd.y); - if ((ocell == actcell) && the_locking_inset && inset_hit) { + if (ocell == actcell && the_locking_inset && inset_hit) { resetPos(bv); FuncRequest cmd1 = cmd; cmd1.x -= inset_x; @@ -672,7 +683,9 @@ dispatch_result InsetTabular::localDispatch(FuncRequest const & cmd) clearSelection(); finishUndo(); if (insetHit(bv, cmd.x, cmd.y) && cmd.button() != mouse_button::button3) { - activateCellInsetAbs(bv, cmd.x, cmd.y, cmd.button()); + inset_x = cursorx_ - top_x + tabular.getBeginningOfTextInCell(actcell); + inset_y = cursory_; + activateCellInset(bv, cmd.x - inset_x, cmd.y - inset_y, cmd.button()); } } return DISPATCHED; @@ -911,14 +924,12 @@ dispatch_result InsetTabular::localDispatch(FuncRequest const & cmd) case LFUN_ENDBUF: case LFUN_ENDBUFSEL: break; - case LFUN_LAYOUT_TABULAR: { + case LFUN_LAYOUT_TABULAR: InsetTabularMailer(*this).showDialog(bv); break; - } - case LFUN_INSET_DIALOG_UPDATE: { + case LFUN_INSET_DIALOG_UPDATE: InsetTabularMailer(*this).updateDialog(bv); break; - } case LFUN_TABULAR_FEATURE: if (!tabularFeatures(bv, arg)) result = UNDISPATCHED; @@ -954,8 +965,8 @@ dispatch_result InsetTabular::localDispatch(FuncRequest const & cmd) break; case LFUN_PASTESELECTION: { - string const clip(bv->getClipboard()); - if (clip.empty()) + string const clip = bv->getClipboard(); + if (clip.empty()) break; #if 0 if (clip.find('\t') != string::npos) { @@ -1380,10 +1391,9 @@ 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; - } + // behind the inset + if (lock && activateCellInset(bv, 0, 0, mouse_button::none, true)) + return DISPATCHED; resetPos(bv); return DISPATCHED_NOUPDATE; } @@ -1506,8 +1516,8 @@ void InsetTabular::setFont(BufferView * bv, LyXFont const & font, bool tall, 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) + 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) @@ -1569,8 +1579,7 @@ void checkLongtableSpecial(LyXTabular::ltType & ltt, void InsetTabular::tabularFeatures(BufferView * bv, - LyXTabular::Feature feature, - string const & value) + LyXTabular::Feature feature, string const & value) { int sel_col_start; int sel_col_end; @@ -1635,8 +1644,7 @@ 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); @@ -1672,11 +1680,13 @@ void InsetTabular::tabularFeatures(BufferView * bv, } } 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); @@ -1684,6 +1694,7 @@ void InsetTabular::tabularFeatures(BufferView * bv, tabular.setOwner(this); updateLocal(bv); break; + case LyXTabular::APPEND_COLUMN: // append the column into the tabular unlockInsetInInset(bv, the_locking_inset); @@ -1692,32 +1703,32 @@ void InsetTabular::tabularFeatures(BufferView * bv, 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); 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); 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) @@ -1730,8 +1741,7 @@ void InsetTabular::tabularFeatures(BufferView * bv, 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) @@ -1745,8 +1755,7 @@ void InsetTabular::tabularFeatures(BufferView * bv, 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) @@ -1760,8 +1769,7 @@ void InsetTabular::tabularFeatures(BufferView * bv, 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) @@ -1873,7 +1881,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; @@ -1927,11 +1935,9 @@ 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: @@ -1961,15 +1967,6 @@ bool InsetTabular::activateCellInset(BufferView * bv, int x, int y, } -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); @@ -2353,12 +2350,20 @@ void InsetTabular::getSelection(int & srow, int & erow, ParagraphList * InsetTabular::getParagraphs(int i) const { - return (i < tabular.getNumberOfCells()) + return i < tabular.getNumberOfCells() ? tabular.getCellInset(i).getParagraphs(0) : 0; } +LyXText * InsetTabular::getText(int i) const +{ + return i < tabular.getNumberOfCells() + ? tabular.getCellInset(i).getText(0) + : 0; +} + + LyXCursor const & InsetTabular::cursor(BufferView * bv) const { if (the_locking_inset) @@ -2387,7 +2392,8 @@ WordLangTuple const InsetTabular::selectNextWordToSpellcheck(BufferView * bv, float & value) const { if (the_locking_inset) { - WordLangTuple word(the_locking_inset->selectNextWordToSpellcheck(bv, value)); + WordLangTuple word = + the_locking_inset->selectNextWordToSpellcheck(bv, value); if (!word.word().empty()) return word; if (tabular.isLastCell(actcell)) { @@ -2399,7 +2405,7 @@ InsetTabular::selectNextWordToSpellcheck(BufferView * bv, float & value) const // 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)); + WordLangTuple word = selectNextWordInt(bv, value); if (!word.word().empty()) resetPos(bv); return word; @@ -2411,7 +2417,8 @@ WordLangTuple InsetTabular::selectNextWordInt(BufferView * bv, float & value) co // when entering this function the inset should be ALWAYS locked! BOOST_ASSERT(the_locking_inset); - WordLangTuple word(the_locking_inset->selectNextWordToSpellcheck(bv, value)); + WordLangTuple word = + the_locking_inset->selectNextWordToSpellcheck(bv, value); if (!word.word().empty()) return word; @@ -2571,7 +2578,7 @@ bool InsetTabular::insertAsciiString(BufferView * bv, string const & buf, ++cols; break; case '\n': - if ((p+1) < len) + if (p + 1 < len) ++rows; maxCols = max(cols, maxCols); cols = 1; diff --git a/src/insets/insettabular.h b/src/insets/insettabular.h index 7878be10d1..d02c0ca323 100644 --- a/src/insets/insettabular.h +++ b/src/insets/insettabular.h @@ -161,6 +161,8 @@ public: /// ParagraphList * getParagraphs(int) const; /// + LyXText * getText(int) const; + /// LyXCursor const & cursor(BufferView *) const; /// bool allowSpellcheck() const { return true; } @@ -261,9 +263,6 @@ private: mouse_button::state button = mouse_button::none, bool behind = false); /// - bool activateCellInsetAbs(BufferView *, int x = 0, int y = 0, - mouse_button::state button = mouse_button::none); - /// bool insetHit(BufferView * bv, int x, int y) const; /// bool hasPasteBuffer() const; diff --git a/src/insets/insettext.C b/src/insets/insettext.C index 6c8d37a857..2cbaaeca09 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -33,7 +33,7 @@ #include "rowpainter.h" #include "sgml.h" #include "texrow.h" -#include "undo_funcs.h" +#include "undo.h" #include "WordLangTuple.h" #include "frontends/Alert.h" @@ -1582,6 +1582,12 @@ ParagraphList * InsetText::getParagraphs(int i) const } +LyXText * InsetText::getText(int i) const +{ + return (i == 0) ? const_cast(&text_) : 0; +} + + LyXCursor const & InsetText::cursor(BufferView * bv) const { if (the_locking_inset) diff --git a/src/insets/insettext.h b/src/insets/insettext.h index 614e8f996e..85ab71abb0 100644 --- a/src/insets/insettext.h +++ b/src/insets/insettext.h @@ -155,6 +155,8 @@ public: /// ParagraphList * getParagraphs(int) const; /// + LyXText * getText(int) const; + /// LyXCursor const & cursor(BufferView *) const; /// bool allowSpellcheck() const { return true; } diff --git a/src/iterators.C b/src/iterators.C index 0711990bb2..dd92fd8d01 100644 --- a/src/iterators.C +++ b/src/iterators.C @@ -13,6 +13,7 @@ #include "iterators.h" #include "paragraph.h" +#include "debug.h" #include "insets/inset.h" @@ -146,6 +147,28 @@ ParIterator & ParIterator::operator++() } +LyXText * ParIterator::text() const +{ + //lyxerr << "positions.size: " << pimpl_->positions.size() << std::endl; + if (pimpl_->positions.size() <= 1) + return 0; + + ParPosition const & pos = pimpl_->positions[pimpl_->positions.size() - 2]; + return (*pos.it)->inset->getText(*pos.index); +} + + +InsetOld * ParIterator::inset() const +{ + //lyxerr << "positions.size: " << pimpl_->positions.size() << std::endl; + if (pimpl_->positions.size() <= 1) + return 0; + + ParPosition const & pos = pimpl_->positions[pimpl_->positions.size() - 2]; + return (*pos.it)->inset; +} + + Paragraph & ParIterator::operator*() const { return *pimpl_->positions.back().pit; diff --git a/src/iterators.h b/src/iterators.h index 8a7ea614a6..e45e6dc3ab 100644 --- a/src/iterators.h +++ b/src/iterators.h @@ -16,6 +16,9 @@ #include +class LyXText; +class InsetOld; + class ParIterator { public: /// @@ -38,6 +41,11 @@ public: ParagraphList::iterator pit() const; /// ParagraphList & plist() const; + /// returns 'innermost' LyXText if in an inset or '0' instead of + //bv->text + LyXText * text() const; + /// + InsetOld * inset() const; /// size_t size() const; /// diff --git a/src/lyxfunc.C b/src/lyxfunc.C index a14ded7d7d..9c2508e26d 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -49,7 +49,7 @@ #include "paragraph.h" #include "ParagraphParameters.h" #include "TextCache.h" -#include "undo_funcs.h" +#include "undo.h" #include "insets/insetcommand.h" #include "insets/insetexternal.h" diff --git a/src/mathed/formulabase.C b/src/mathed/formulabase.C index 62f94bd749..15331df22b 100644 --- a/src/mathed/formulabase.C +++ b/src/mathed/formulabase.C @@ -28,7 +28,7 @@ #include "math_hullinset.h" #include "math_parser.h" #include "math_spaceinset.h" -#include "undo_funcs.h" +#include "undo.h" #include "ref_inset.h" #include "LColor.h" diff --git a/src/paragraph.C b/src/paragraph.C index b53949fd30..c949662f71 100644 --- a/src/paragraph.C +++ b/src/paragraph.C @@ -487,7 +487,7 @@ void Paragraph::setFont(pos_type pos, LyXFont const & font) BOOST_ASSERT(pos <= size()); // First, reduce font against layout/label font - // Update: The SetCharFont() routine in text2.C already + // Update: The setCharFont() routine in text2.C already // reduces font, so we don't need to do that here. (Asger) // No need to simplify this because it will disappear // in a new kernel. (Asger) diff --git a/src/paragraph.h b/src/paragraph.h index 3c6fddddb4..839cc54da4 100644 --- a/src/paragraph.h +++ b/src/paragraph.h @@ -69,6 +69,11 @@ public: /// the destructor removes the new paragraph from the list ~Paragraph(); + /// + int id() const; + /// + void id(int i); + /// Language const * getParLanguage(BufferParams const &) const; /// @@ -91,11 +96,6 @@ public: /// void validate(LaTeXFeatures &) const; - /// return the unique ID of this paragraph - int id() const; - /// Set the Id of this paragraph. - void id(int); - /// int startTeXParParams(BufferParams const &, std::ostream &, bool) const; diff --git a/src/support/debugstream.h b/src/support/debugstream.h index 9340def08c..b4f32cba77 100644 --- a/src/support/debugstream.h +++ b/src/support/debugstream.h @@ -12,8 +12,9 @@ #ifndef DEBUG_STREAM_HPP #define DEBUG_STREAM_HPP -#include +#include +#include struct debug_trait { enum type { diff --git a/src/text.C b/src/text.C index cf321783b4..5114548c38 100644 --- a/src/text.C +++ b/src/text.C @@ -36,7 +36,7 @@ #include "ParagraphParameters.h" #include "rowpainter.h" #include "text_funcs.h" -#include "undo_funcs.h" +#include "undo.h" #include "vspace.h" #include "WordLangTuple.h" @@ -1284,7 +1284,7 @@ void LyXText::redoParagraph() // same Paragraph one to the right and make a rebreak void LyXText::insertChar(char c) { - recordUndo(bv(), Undo::INSERT, ownerParagraphs(), cursor.par(), cursor.par()); + recordUndo(Undo::INSERT, this, cursor.par(), cursor.par()); // When the free-spacing option is set for the current layout, // disable the double-space checking @@ -1568,7 +1568,7 @@ void LyXText::acceptChange() if (selection.start.par() == selection.end.par()) { LyXCursor & startc = selection.start; LyXCursor & endc = selection.end; - recordUndo(bv(), Undo::INSERT, ownerParagraphs(), startc.par()); + recordUndo(Undo::INSERT, this, startc.par()); getPar(startc)->acceptChange(startc.pos(), endc.pos()); finishUndo(); clearSelection(); @@ -1587,7 +1587,7 @@ void LyXText::rejectChange() if (selection.start.par() == selection.end.par()) { LyXCursor & startc = selection.start; LyXCursor & endc = selection.end; - recordUndo(bv(), Undo::INSERT, ownerParagraphs(), startc.par()); + recordUndo(Undo::INSERT, this, startc.par()); getPar(startc)->rejectChange(startc.pos(), endc.pos()); finishUndo(); clearSelection(); @@ -1797,7 +1797,7 @@ void LyXText::changeCase(LyXText::TextCase action) setCursor(to.par(), to.pos() + 1); } - recordUndo(bv(), Undo::ATOMIC, ownerParagraphs(), from.par(), to.par()); + recordUndo(Undo::ATOMIC, this, from.par(), to.par()); pos_type pos = from.pos(); int par = from.par(); @@ -1858,7 +1858,7 @@ void LyXText::Delete() // if you had success make a backspace if (old_cursor.par() != cursor.par() || old_cursor.pos() != cursor.pos()) { - recordUndo(bv(), Undo::DELETE, ownerParagraphs(), old_cursor.par()); + recordUndo(Undo::DELETE, this, old_cursor.par()); backspace(); } } @@ -1908,8 +1908,7 @@ void LyXText::backspace() } if (cursor.par() != 0) - recordUndo(bv(), Undo::DELETE, ownerParagraphs(), - cursor.par() - 1, cursor.par()); + recordUndo(Undo::DELETE, this, cursor.par() - 1, cursor.par()); ParagraphList::iterator tmppit = cursorPar(); // We used to do cursorLeftIntern() here, but it is @@ -1948,7 +1947,7 @@ void LyXText::backspace() } else { // this is the code for a normal backspace, not pasting // any paragraphs - recordUndo(bv(), Undo::DELETE, ownerParagraphs(), cursor.par()); + recordUndo(Undo::DELETE, this, cursor.par()); // We used to do cursorLeftIntern() here, but it is // not a good idea since it triggers the auto-delete // mechanism. So we do a cursorLeftIntern()-lite, diff --git a/src/text2.C b/src/text2.C index b3102acf6f..a9a9bc0024 100644 --- a/src/text2.C +++ b/src/text2.C @@ -42,7 +42,7 @@ #include "paragraph.h" #include "paragraph_funcs.h" #include "ParagraphParameters.h" -#include "undo_funcs.h" +#include "undo.h" #include "vspace.h" #include "frontends/font_metrics.h" @@ -1938,13 +1938,13 @@ ParagraphList & LyXText::ownerParagraphs() const void LyXText::recUndo(paroffset_type first, paroffset_type last) const { - recordUndo(bv(), Undo::ATOMIC, ownerParagraphs(), first, last); + recordUndo(Undo::ATOMIC, this, first, last); } void LyXText::recUndo(lyx::paroffset_type par) const { - recordUndo(bv(), Undo::ATOMIC, ownerParagraphs(), par, par); + recordUndo(Undo::ATOMIC, this, par, par); } diff --git a/src/text3.C b/src/text3.C index 638ea44936..200d8c949f 100644 --- a/src/text3.C +++ b/src/text3.C @@ -31,7 +31,7 @@ #include "paragraph.h" #include "ParagraphParameters.h" #include "text_funcs.h" -#include "undo_funcs.h" +#include "undo.h" #include "vspace.h" #include "frontends/Dialogs.h" diff --git a/src/undo.C b/src/undo.C index 46854ecfef..634827a10b 100644 --- a/src/undo.C +++ b/src/undo.C @@ -3,8 +3,11 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * + * \author Asger Alstrup * \author Lars Gullik Bjønnes + * \author John Levon * \author André Pönitz + * \author Jürgen Vigna * * Full author contact details are available in file CREDITS. */ @@ -12,17 +15,37 @@ #include #include "undo.h" + +#include "buffer.h" +#include "debug.h" +#include "BufferView.h" +#include "funcrequest.h" +#include "iterators.h" +#include "lyxtext.h" #include "paragraph.h" -Undo::Undo(undo_kind kind_arg, int inset, - int plist_arg, +#include "insets/updatableinset.h" +#include "insets/insettext.h" + +#include + +using std::endl; +using lyx::paroffset_type; + + +/// The flag used by finishUndo(). +bool undo_finished; + +/// Whether actions are not added to the undo stacks. +bool undo_frozen; + +Undo::Undo(undo_kind kind_arg, int text_arg, int first, int last, int cursor, int cursor_pos_arg, ParagraphList const & par) : kind(kind_arg), - inset_id(inset), - plist(plist_arg), + text(text_arg), first_par_offset(first), last_par_offset(last), cursor_par_offset(cursor), @@ -30,3 +53,250 @@ Undo::Undo(undo_kind kind_arg, int inset, pars(par) {} + +std::ostream & operator<<(std::ostream & os, Undo const & undo) +{ + return os << " text: " << undo.text + << " first: " << undo.first_par_offset + << " last: " << undo.last_par_offset + << " cursor: " << undo.cursor_par_offset + << "/" << undo.cursor_pos; +} + + +namespace { + +void recordUndo(Undo::undo_kind kind, + LyXText * text, paroffset_type firstpar, paroffset_type lastpar, + limited_stack & stack) +{ + Buffer * buf = text->bv()->buffer(); + + ParagraphList & plist = text->ownerParagraphs(); + ParagraphList::iterator first = plist.begin(); + advance(first, firstpar); + ParagraphList::iterator last = plist.begin(); + advance(last, lastpar); + + // try to find the appropriate list by counting the + // texts from buffer begin + ParIterator null = buf->par_iterator_end(); + + int tcount = 0; + // it.text() returns 0 for outermost text. + if (text != text->bv()->text) + for (ParIterator it = buf->par_iterator_begin(); it != null; ++it, ++tcount) + if (it.text() == text) + break; + + // and calculate a stable reference to them + int const first_offset = firstpar; + int const last_offset = plist.size() - lastpar; + + // Undo::ATOMIC are always recorded (no overlapping there). + // overlapping only with insert and delete inside one paragraph: + // nobody wants all removed character appear one by one when undoing. + if (! undo_finished && kind != Undo::ATOMIC) { + // Check whether storing is needed. + if (! buf->undostack().empty() + && buf->undostack().top().kind == kind + && buf->undostack().top().first_par_offset == first_offset + && buf->undostack().top().last_par_offset == last_offset) { + // No additonal undo recording needed - + // effectively, we combine undo recordings to one. + return; + } + } + + // Record the cursor position in a stable way. + int const cursor_offset = text->cursor.par(); + + // make and push the Undo entry + stack.push(Undo(kind, tcount, + first_offset, last_offset, + cursor_offset, text->cursor.pos(), + ParagraphList())); + lyxerr << "undo record: " << stack.top() << endl; + + // record the relevant paragraphs + ParagraphList & undo_pars = stack.top().pars; + + for (ParagraphList::iterator it = first; it != last; ++it) { + undo_pars.push_back(*it); + undo_pars.back().id(it->id()); + } + undo_pars.push_back(*last); + undo_pars.back().id(last->id()); + + // and make sure that next time, we should be combining if possible + undo_finished = false; +} + + +// Returns false if no undo possible. +bool performUndoOrRedo(BufferView * bv, Undo const & undo) +{ + lyxerr << "undo, performing: " << undo << endl; + Buffer * buf = bv->buffer(); + ParIterator plit = buf->par_iterator_begin(); + ParIterator null = buf->par_iterator_end(); + + int tcount = undo.text; + for ( ; tcount && plit != null; ++plit, --tcount) + ; + + LyXText * text = plit.text(); + if (!text) + text = bv->text; + ParagraphList & plist = text->ownerParagraphs(); + + // remove new stuff between first and last + { + ParagraphList::iterator first = plist.begin(); + advance(first, undo.first_par_offset); + ParagraphList::iterator last = plist.begin(); + advance(last, plist.size() - undo.last_par_offset); + plist.erase(first, ++last); + } + + // re-insert old stuff instead + if (plist.empty()) { + plist.assign(undo.pars.begin(), undo.pars.end()); + } else { + ParagraphList::iterator first = plist.begin(); + advance(first, undo.first_par_offset); + plist.insert(first, undo.pars.begin(), undo.pars.end()); + } + + // set cursor + lyxerr << "undo, text: " << text << " inset: " << plit.inset() << endl; + InsetOld * inset = plit.inset(); + if (inset) { + // Magic needed to cope with inset locking + FuncRequest cmd(bv, LFUN_INSET_EDIT, "left"); + inset->localDispatch(cmd); + } + + // set cursor again to force the position to be the right one + text->setCursorIntern(undo.cursor_par_offset, undo.cursor_pos); + + // clear any selection + text->clearSelection(); + text->selection.cursor = text->cursor; + text->updateCounters(); + + // rebreak the entire document + bv->text->fullRebreak(); + + finishUndo(); + return true; +} + + +// Returns false if no undo possible. +bool textUndoOrRedo(BufferView * bv, + limited_stack & stack, limited_stack & otherstack) +{ + if (stack.empty()) { + /* + * Finish the undo operation in the case there was no entry + * on the stack to perform. + */ + freezeUndo(); + bv->unlockInset(bv->theLockingInset()); + finishUndo(); + unFreezeUndo(); + return false; + } + + Undo undo = stack.top(); + stack.pop(); + finishUndo(); + + if (!undo_frozen) { + otherstack.push(undo); + otherstack.top().pars.clear(); + Buffer * buf = bv->buffer(); + ParagraphList & plist = buf->paragraphs(); + if (undo.first_par_offset + undo.last_par_offset <= int(plist.size())) { + ParagraphList::iterator first = plist.begin(); + advance(first, undo.first_par_offset); + ParagraphList::iterator last = plist.begin(); + advance(last, plist.size() - undo.last_par_offset + 1); + otherstack.top().pars.insert(otherstack.top().pars.begin(), first, last); + } + otherstack.top().cursor_pos = text + lyxerr << " undo other: " << otherstack.top() << endl; + } + + // Now we can unlock the inset for safety because the inset + // pointer could be changed during the undo-function. Anyway + // if needed we have to lock the right inset/position if this + // is requested. + freezeUndo(); + bv->unlockInset(bv->theLockingInset()); + bool const ret = performUndoOrRedo(bv, undo); + unFreezeUndo(); + return ret; +} + +} // namespace anon + + +void freezeUndo() +{ + // This is dangerous and for internal use only. + undo_frozen = true; +} + + +void unFreezeUndo() +{ + // This is dangerous and for internal use only. + undo_frozen = false; +} + + +void finishUndo() +{ + // Makes sure the next operation will be stored. + undo_finished = true; +} + + +bool textUndo(BufferView * bv) +{ + return textUndoOrRedo(bv, bv->buffer()->undostack(), + bv->buffer()->redostack()); +} + + +bool textRedo(BufferView * bv) +{ + return textUndoOrRedo(bv, bv->buffer()->redostack(), + bv->buffer()->undostack()); +} + + +void recordUndo(Undo::undo_kind kind, + LyXText const * text, paroffset_type first, paroffset_type last) +{ + if (!undo_frozen) { + Buffer * buf = text->bv()->buffer(); + recordUndo(kind, const_cast(text), + first, last, buf->undostack()); + buf->redostack().clear(); + } +} + + +void recordUndo(Undo::undo_kind kind, LyXText const * text, paroffset_type par) +{ + recordUndo(kind, text, par, par); +} + + +void recordUndo(BufferView * bv, Undo::undo_kind kind) +{ + recordUndo(kind, bv->text, bv->text->cursor.par()); +} diff --git a/src/undo.h b/src/undo.h index 08cf5b9861..33ed9c34db 100644 --- a/src/undo.h +++ b/src/undo.h @@ -6,7 +6,9 @@ * * \author Asger Alstrup * \author Lars Gullik Bjønnes + * \author John Levon * \author André Pönitz + * \author Jürgen Vigna * * Full author contact details are available in file CREDITS. */ @@ -15,11 +17,15 @@ #define UNDO_H #include "ParagraphList_fwd.h" +#include "support/types.h" + +class LyXText; +class BufferView; /** * These are the elements put on the undo stack. Each object * contains complete paragraphs and sufficient information - * to restore the state. The work is done in undo_funcs.C + * to restore the state. */ class Undo { public: @@ -44,8 +50,7 @@ public: ATOMIC }; /// - Undo(undo_kind kind, int inset_id, - int plist, + Undo(undo_kind kind, int text, int first, int last, int cursor, int cursor_pos, ParagraphList const & par_arg); @@ -53,15 +58,8 @@ public: /// Which kind of operation are we recording for? undo_kind kind; - /// to what paragraph list do we belong? - int plist; - - /** - * ID of hosting inset if the cursor is in one. - * if -1, then the cursor is not in an inset. - * if >= 0, then the cursor is in inset with given id. - */ - int inset_id; + /// hosting LyXText counted from buffer begin + int text; /// Offset to the first paragraph in the main document paragraph list int first_par_offset; @@ -84,4 +82,42 @@ public: }; -#endif +/// This will undo the last action - returns false if no undo possible +bool textUndo(BufferView *); + +/// This will redo the last undo - returns false if no redo possible +bool textRedo(BufferView *); + +/// Makes sure the next operation will be stored +void finishUndo(); + +/** + * Whilst undo is frozen, all actions do not get added + * to the undo stack + */ +void freezeUndo(); + +/// Track undos again +void unFreezeUndo(); + +/** + * Record undo information - call with the first paragraph that will be changed + * and the last paragraph that will be changed. So we give an inclusive + * range. + * This is called before you make the changes to the paragraph, and it + * will record the original information of the paragraphs in the undo stack. + */ +void recordUndo(Undo::undo_kind kind, + LyXText const * text, lyx::paroffset_type first, lyx::paroffset_type last); + +/// Convienience: Prepare undo when change in a single paragraph. +void recordUndo(Undo::undo_kind kind, + LyXText const * text, lyx::paroffset_type par); + +/// Convienience: Prepare undo for the paragraph that contains the cursor +void recordUndo(BufferView *, Undo::undo_kind kind); + +/// Are we avoiding tracking undos currently ? +extern bool undo_frozen; + +#endif // UNDO_FUNCS_H diff --git a/src/undo_funcs.C b/src/undo_funcs.C deleted file mode 100644 index b9670d052f..0000000000 --- a/src/undo_funcs.C +++ /dev/null @@ -1,290 +0,0 @@ -/** - * \file undo_funcs.C - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Asger Alstrup - * \author Lars Gullik Bjønnes - * \author John Levon - * \author André Pönitz - * \author Jürgen Vigna - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "undo_funcs.h" - -#include "buffer.h" -#include "debug.h" -#include "BufferView.h" -#include "funcrequest.h" -#include "iterators.h" -#include "lyxtext.h" -#include "paragraph.h" - -#include "insets/updatableinset.h" - -#include - -using std::endl; -using lyx::paroffset_type; - - -/// The flag used by finishUndo(). -bool undo_finished; - -/// Whether actions are not added to the undo stacks. -bool undo_frozen; - -namespace { - - -void recordUndo(BufferView * bv, Undo::undo_kind kind, - ParagraphList & plist, paroffset_type firstpar, paroffset_type lastpar, - limited_stack & stack) -{ - Buffer * buf = bv->buffer(); - - ParagraphList::iterator first = plist.begin(); - advance(first, firstpar); - ParagraphList::iterator last = plist.begin(); - advance(last, lastpar); - - // First, record inset id, if cursor is in one - UpdatableInset * inset = first->inInset(); - LyXText * text = inset ? inset->getLyXText(bv) : bv->text; - int const inset_id = inset ? inset->id() : -1; - - // Try to find the appropriate list by counting the, - ParIterator null = buf->par_iterator_end(); - - int pcount = 0; - for (ParIterator it = buf->par_iterator_begin(); it != null; ++it, ++pcount) - if (&it.plist() == &plist) - break; - - // And calculate a stable reference to them - int const first_offset = firstpar; - int const last_offset = plist.size() - lastpar; - - // Undo::ATOMIC are always recorded (no overlapping there). - // Overlapping only with insert and delete inside one paragraph: - // Nobody wants all removed character appear one by one when undoing. - if (! undo_finished && kind != Undo::ATOMIC) { - // Check whether storing is needed. - if (! buf->undostack().empty() - && buf->undostack().top().kind == kind - && buf->undostack().top().first_par_offset == first_offset - && buf->undostack().top().last_par_offset == last_offset) { - // No additonal undo recording needed - - // effectively, we combine undo recordings to one. - return; - } - } - - // Record the cursor position in a stable way. - int const cursor_offset = text->cursor.par(); - - // Make and push the Undo entry - stack.push(Undo(kind, inset_id, - pcount, - first_offset, last_offset, - cursor_offset, text->cursor.pos(), - ParagraphList())); - - // Record the relevant paragraphs - ParagraphList & undo_pars = stack.top().pars; - - for (ParagraphList::iterator it = first; it != last; ++it) { - undo_pars.push_back(*it); - undo_pars.back().id(it->id()); - } - undo_pars.push_back(*last); - undo_pars.back().id(last->id()); - - // And make sure that next time, we should be combining if possible - undo_finished = false; -} - - -// Returns false if no undo possible. -bool performUndoOrRedo(BufferView * bv, Undo const & undo) -{ - Buffer * buf = bv->buffer(); - - ParIterator null = buf->par_iterator_end(); - ParIterator plit = buf->par_iterator_begin(); - int n = undo.plist; - for ( ; n && plit != null; ++plit, --n) - ; - BOOST_ASSERT(plit != null); - ParagraphList & plist = plit.plist(); - - // Remove new stuff between first and last - { - ParagraphList::iterator first = plist.begin(); - advance(first, undo.first_par_offset); - ParagraphList::iterator last = plist.begin(); - advance(last, plist.size() - undo.last_par_offset); - plist.erase(first, ++last); - } - - // Re-insert old stuff instead - { - if (plist.empty()) { - plist.assign(undo.pars.begin(), undo.pars.end()); - } else { - ParagraphList::iterator first = plist.begin(); - advance(first, undo.first_par_offset); - plist.insert(first, undo.pars.begin(), undo.pars.end()); - } - } - - // Rebreak the entire document - bv->text->fullRebreak(); - - // set cursor - { - // Get a hold of the inset for the cursor, if relevant - UpdatableInset * inset = - static_cast( - buf->getInsetFromID(undo.inset_id)); - - LyXText * text = inset ? inset->getLyXText(bv) : bv->text; - text->setCursorIntern(undo.cursor_par_offset, undo.cursor_pos); - - //lyxerr << "undo, inset: " << inset << endl; - - if (inset) { - //lyxerr << "undo, inset owner: " << inset->owner() << endl; - - // Magic needed to update inset internal state - FuncRequest cmd(bv, LFUN_INSET_EDIT, "left"); - if (inset->owner()) - inset->owner()->localDispatch(cmd); - else - inset->localDispatch(cmd); - } - - // set cursor again to force the position to be the right one - text->setCursorIntern(undo.cursor_par_offset, undo.cursor_pos); - - // Clear any selection and set the selection - // cursor for any new selection. - text->clearSelection(); - text->selection.cursor = text->cursor; - text->updateCounters(); - } - - finishUndo(); - return true; -} - - -// Returns false if no undo possible. -bool textUndoOrRedo(BufferView * bv, - limited_stack & stack, - limited_stack & otherstack) -{ - if (stack.empty()) { - /* - * Finish the undo operation in the case there was no entry - * on the stack to perform. - */ - freezeUndo(); - bv->unlockInset(bv->theLockingInset()); - finishUndo(); - unFreezeUndo(); - return false; - } - - Undo undo = stack.top(); - stack.pop(); - finishUndo(); - - if (!undo_frozen) { - otherstack.push(undo); - otherstack.top().pars.clear(); - Buffer * buf = bv->buffer(); - ParagraphList & plist = buf->paragraphs(); - if (undo.first_par_offset + undo.last_par_offset <= int(plist.size())) { - ParagraphList::iterator first = plist.begin(); - advance(first, undo.first_par_offset); - ParagraphList::iterator last = plist.begin(); - advance(last, plist.size() - undo.last_par_offset + 1); - otherstack.top().pars.insert(otherstack.top().pars.begin(), first, last); - } - } - - // Now we can unlock the inset for safety because the inset - // pointer could be changed during the undo-function. Anyway - // if needed we have to lock the right inset/position if this - // is requested. - freezeUndo(); - bv->unlockInset(bv->theLockingInset()); - bool const ret = performUndoOrRedo(bv, undo); - unFreezeUndo(); - return ret; -} - -} // namespace anon - - -void freezeUndo() -{ - // This is dangerous and for internal use only. - undo_frozen = true; -} - - -void unFreezeUndo() -{ - // This is dangerous and for internal use only. - undo_frozen = false; -} - - -void finishUndo() -{ - // Makes sure the next operation will be stored. - undo_finished = true; -} - - -bool textUndo(BufferView * bv) -{ - return textUndoOrRedo(bv, bv->buffer()->undostack(), - bv->buffer()->redostack()); -} - - -bool textRedo(BufferView * bv) -{ - return textUndoOrRedo(bv, bv->buffer()->redostack(), - bv->buffer()->undostack()); -} - - -void recordUndo(BufferView * bv, Undo::undo_kind kind, - ParagraphList & plist, paroffset_type first, paroffset_type last) -{ - if (!undo_frozen) { - recordUndo(bv, kind, plist, first, last, bv->buffer()->undostack()); - bv->buffer()->redostack().clear(); - } -} - - -void recordUndo(BufferView * bv, Undo::undo_kind kind, - ParagraphList & plist, paroffset_type par) -{ - recordUndo(bv, kind, plist, par, par); -} - - -void recordUndo(BufferView * bv, Undo::undo_kind kind) -{ - recordUndo(bv, kind, bv->text->ownerParagraphs(), bv->text->cursor.par()); -} diff --git a/src/undo_funcs.h b/src/undo_funcs.h deleted file mode 100644 index 96efcb9564..0000000000 --- a/src/undo_funcs.h +++ /dev/null @@ -1,64 +0,0 @@ -// -*- C++ -*- -/** - * \file undo_funcs.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Asger Alstrup - * \author Lars Gullik Bjønnes - * \author John Levon - * \author André Pönitz - * \author Jürgen Vigna - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef UNDO_FUNCS_H -#define UNDO_FUNCS_H - -#include "undo.h" -#include "ParagraphList_fwd.h" -#include "support/types.h" - -class BufferView; -class Paragraph; - -/// This will undo the last action - returns false if no undo possible -bool textUndo(BufferView *); - -/// This will redo the last undo - returns false if no redo possible -bool textRedo(BufferView *); - -/// Makes sure the next operation will be stored -void finishUndo(); - -/** - * Whilst undo is frozen, all actions do not get added - * to the undo stack - */ -void freezeUndo(); - -/// Track undos again -void unFreezeUndo(); - -/** - * Record undo information - call with the first paragraph that will be changed - * and the last paragraph that will be changed. So we give an inclusive - * range. - * This is called before you make the changes to the paragraph, and it - * will record the original information of the paragraphs in the undo stack. - */ -void recordUndo(BufferView *, Undo::undo_kind kind, - ParagraphList & plist, lyx::paroffset_type first, lyx::paroffset_type last); - -/// Convienience: Prepare undo when change in a single paragraph. -void recordUndo(BufferView *, Undo::undo_kind kind, - ParagraphList & plist, lyx::paroffset_type par); - -/// Convienience: Prepare undo for the paragraph that contains the cursor -void recordUndo(BufferView *, Undo::undo_kind kind); - -/// Are we avoiding tracking undos currently ? -extern bool undo_frozen; - -#endif // UNDO_FUNCS_H