The following patch fixes several *GOTO* lfuns: - use proper inset iterators to be able to move inside/outside insets
- use BufferView::setCursor so that insets are open as needed - move the handling of these LFUNS from LyXText to BufferView::Pimpl - move gotoInset to bufferview_funcs.C. It would be nice to have some testing before committing it. JMarc
Index: src/BufferView.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView.C,v retrieving revision 1.259 diff -u -p -r1.259 BufferView.C --- src/BufferView.C 8 Feb 2005 13:17:53 -0000 1.259 +++ src/BufferView.C 14 Feb 2005 11:23:07 -0000 @@ -275,9 +275,7 @@ void BufferView::gotoLabel(string const vector<string> labels; it->getLabelList(*buffer(), labels); if (find(labels.begin(),labels.end(),label) != labels.end()) { - cursor().clearSelection(); - text()->setCursor(cursor(), it.pit(), it.pos()); - cursor().resetAnchor(); + setCursor(it); update(); return; } @@ -324,12 +322,13 @@ LyXText * BufferView::text() const } -void BufferView::setCursor(ParIterator const & par, lyx::pos_type pos) +void BufferView::setCursor(DocIterator const & dit) { - for (int i = 0, n = par.depth(); i < n; ++i) - par[i].inset().edit(cursor(), true); + size_t const n = dit.depth(); + for (size_t i = 0; i < n; ++i) + dit[i].inset().edit(cursor(), true); - cursor().setCursor(makeDocIterator(par, pos)); + cursor().setCursor(dit); cursor().selection() = false; } @@ -337,11 +336,9 @@ void BufferView::setCursor(ParIterator c void BufferView::putSelectionAt(DocIterator const & cur, int length, bool backwards) { - ParIterator par(cur); - cursor().clearSelection(); - setCursor(par, cur.pos()); + setCursor(cur); if (length) { if (backwards) { Index: src/BufferView.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView.h,v retrieving revision 1.184 diff -u -p -r1.184 BufferView.h --- src/BufferView.h 31 Jan 2005 16:29:35 -0000 1.184 +++ src/BufferView.h 14 Feb 2005 11:23:07 -0000 @@ -165,7 +165,7 @@ public: /// LyXText * text() const; /// - void setCursor(ParIterator const & par, lyx::pos_type pos); + void setCursor(DocIterator const &); /* Sets the selection. When \c backwards == false, set anchor * to \c cur and cursor to \c cur + \c length. When \c * backwards == true, set anchor to \c cur and cursor to \c Index: src/BufferView_pimpl.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView_pimpl.C,v retrieving revision 1.578 diff -u -p -r1.578 BufferView_pimpl.C --- src/BufferView_pimpl.C 14 Feb 2005 08:24:16 -0000 1.578 +++ src/BufferView_pimpl.C 14 Feb 2005 11:23:07 -0000 @@ -76,6 +76,7 @@ #include <boost/bind.hpp> #include <functional> +#include <vector> using lyx::pos_type; @@ -96,6 +97,7 @@ using std::min; using std::max; using std::string; using std::mem_fun_ref; +using std::vector; extern BufferList bufferlist; @@ -132,7 +134,6 @@ T * getInsetByCode(LCursor & cur, InsetB return inset; } - } // anon namespace @@ -722,8 +723,7 @@ void BufferView::Pimpl::restorePosition( if (par == buffer_->par_iterator_end()) return; - bv_->text()->setCursor(cursor_, par.pit(), - min(par->size(), saved_positions[i].par_pos)); + bv_->setCursor(makeDocIterator(par, min(par->size(), saved_positions[i].par_pos))); if (i > 0) owner_->message(bformat(_("Moved to bookmark %1$d"), i)); @@ -966,6 +966,9 @@ FuncStatus BufferView::Pimpl::getStatus( case LFUN_BOOKMARK_SAVE: case LFUN_REF_GOTO: case LFUN_GOTO_PARAGRAPH: + case LFUN_GOTOERROR: + case LFUN_GOTONOTE: + case LFUN_REFERENCE_GOTO: case LFUN_WORD_FIND: case LFUN_WORD_REPLACE: case LFUN_MARK_OFF: @@ -1102,10 +1105,26 @@ bool BufferView::Pimpl::dispatch(FuncReq } // Set the cursor - bv_->setCursor(par, 0); + bv_->setCursor(makeDocIterator(par, 0)); update(); switchKeyMap(); + break; + } + + case LFUN_GOTOERROR: + bv_funcs::gotoInset(bv_, InsetBase::ERROR_CODE, false); + break; + + case LFUN_GOTONOTE: + bv_funcs::gotoInset(bv_, InsetBase::NOTE_CODE, false); + break; + + case LFUN_REFERENCE_GOTO: { + vector<InsetBase_code> tmp; + tmp.push_back(InsetBase::LABEL_CODE); + tmp.push_back(InsetBase::REF_CODE); + bv_funcs::gotoInset(bv_, tmp, true); break; } Index: src/ChangeLog =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ChangeLog,v retrieving revision 1.2120 diff -u -p -r1.2120 ChangeLog --- src/ChangeLog 14 Feb 2005 08:24:16 -0000 1.2120 +++ src/ChangeLog 14 Feb 2005 11:23:08 -0000 @@ -1,3 +1,23 @@ +2005-02-14 Jean-Marc Lasgouttes <[EMAIL PROTECTED]> + + * BufferView.C (setCursor): change to use a DocIterator. + (gotoLabel): use BufferView::setCursor (other part of bug 781). + (putSelectionAt): adapt to BufferView::setCursor change. + + * bufferview_funcs.C (gotoNextInset, gotoInset): new functions, + moved here from LyXText and rewritten to use proper cursor + methods. Fixes bug 1787, 616 and 835. + + * BufferView_pimpl.C (restorePosition): set the cursor correctly + when inside an inset (part of bug 781). + (dispatch): adapt to change of BufferView::setCursor. + (getStatus, dispatch): handle LFUN_GOTOERROR, + LFUN_GOTONOTE and LFUN_REFERENCE_GOTO. + + * text3.C (getStatus, dispatch): do not handle LFUN_GOTOERROR, + LFUN_GOTONOTE and LFUN_REFERENCE_GOTO. + * text3.C (gotoNextInset, gotoInset): removed. + 2005-02-14 Jürgen Spitzmüller <[EMAIL PROTECTED]> * BufferView_pimpl.C: revert accidental commit. Index: src/bufferview_funcs.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/bufferview_funcs.C,v retrieving revision 1.148 diff -u -p -r1.148 bufferview_funcs.C --- src/bufferview_funcs.C 8 Feb 2005 13:17:57 -0000 1.148 +++ src/bufferview_funcs.C 14 Feb 2005 11:23:08 -0000 @@ -33,6 +33,7 @@ #include "frontends/Alert.h" #include "frontends/LyXView.h" +#include "insets/insetcommand.h" #include "insets/insettext.h" #include "support/convert.h" @@ -44,6 +45,7 @@ using lyx::support::bformat; using std::istringstream; using std::ostringstream; using std::string; +using std::vector; namespace bv_funcs { @@ -204,6 +206,67 @@ CurStatus status(BufferView const * bv, return CUR_ABOVE; else return CUR_BELOW; +} + +namespace { + +bool gotoNextInset(LCursor & cur, + vector<InsetBase_code> const & codes, + string const & contents) +{ + LCursor tmpcur = cur; + + while (tmpcur) { + InsetBase const * inset = tmpcur.nextInset(); + if (inset + && find(codes.begin(), codes.end(), inset->lyxCode()) != codes.end() + && (contents.empty() || + static_cast<InsetCommand const *>(inset)->getContents() == contents)) { + cur = tmpcur; + return true; + } + tmpcur.forwardInset(); + } + + return false; +} + +} + + +void gotoInset(BufferView * bv, vector<InsetBase_code> const & codes, + bool same_content) +{ + string contents; + LCursor tmpcur = bv->cursor(); + tmpcur.forwardInset(); + + if (same_content) { + InsetBase const * inset = tmpcur.nextInset(); + if (inset + && find(codes.begin(), codes.end(), inset->lyxCode()) != codes.end()) { + contents = static_cast<InsetCommand const *>(inset)->getContents(); + } + } + + if (!gotoNextInset(tmpcur, codes, contents)) { + if (tmpcur != doc_iterator_begin(tmpcur.inset())) { + tmpcur.reset(tmpcur.bottom().inset()); + if (!gotoNextInset(tmpcur, codes, contents)) + bv->cursor().message(_("No more insets")); + } else { + bv->cursor().message(_("No more insets")); + } + } + + tmpcur.clearSelection(); + bv->setCursor(tmpcur); +} + + +void gotoInset(BufferView * bv, InsetBase_code code, bool same_content) +{ + gotoInset(bv, vector<InsetBase_code>(1, code), same_content); } Index: src/bufferview_funcs.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/bufferview_funcs.h,v retrieving revision 1.34 diff -u -p -r1.34 bufferview_funcs.h --- src/bufferview_funcs.h 30 Nov 2004 01:59:32 -0000 1.34 +++ src/bufferview_funcs.h 14 Feb 2005 11:23:08 -0000 @@ -15,11 +15,13 @@ #define BUFFERVIEW_FUNCS_H #include <string> +#include <vector> class LyXFont; class Point; class DocIterator; class BufferView; +class InsetBase_code; namespace bv_funcs { @@ -48,6 +50,13 @@ CurStatus status(BufferView const * bv, Point coordOffset(DocIterator const & dit); + +// Moves cursor to the next inset with one of the given codes. +void gotoInset(BufferView * bv, std::vector<InsetBase_code> const & codes, + bool same_content); + +// Moves cursor to the next inset with given code. +void gotoInset(BufferView * bv, InsetBase_code code, bool same_content); } // namespace bv_funcs Index: src/lyxtext.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxtext.h,v retrieving revision 1.318 diff -u -p -r1.318 lyxtext.h --- src/lyxtext.h 8 Feb 2005 02:06:35 -0000 1.318 +++ src/lyxtext.h 14 Feb 2005 11:23:08 -0000 @@ -255,16 +255,6 @@ public: /// needed to insert the selection void insertStringAsParagraphs(LCursor & cur, std::string const & str); - /// Find next inset of some specified type. - bool gotoNextInset(LCursor & cur, - std::vector<InsetBase_code> const & codes, - std::string const & contents = std::string()); - /// - void gotoInset(LCursor & cur, - std::vector<InsetBase_code> const & codes, bool same_content); - /// - void gotoInset(LCursor & cur, InsetBase_code code, bool same_content); - /// current text width int width() const; Index: src/text3.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text3.C,v retrieving revision 1.283 diff -u -p -r1.283 text3.C --- src/text3.C 8 Feb 2005 13:18:02 -0000 1.283 +++ src/text3.C 14 Feb 2005 11:23:08 -0000 @@ -74,10 +74,8 @@ using lyx::support::isStrUnsignedInt; using lyx::support::token; using std::endl; -using std::find; using std::string; using std::istringstream; -using std::vector; extern string current_layout; @@ -181,77 +179,6 @@ string const freefont2string() } -bool LyXText::gotoNextInset(LCursor & cur, - vector<InsetBase_code> const & codes, string const & contents) -{ - BOOST_ASSERT(this == cur.text()); - pit_type end = paragraphs().size(); - pit_type pit = cur.pit(); - pos_type pos = cur.pos(); - - InsetBase * inset; - do { - if (pos + 1 < pars_[pit].size()) { - ++pos; - } else { - ++pit; - pos = 0; - } - - } while (pit != end && - !(pars_[pit].isInset(pos) && - (inset = pars_[pit].getInset(pos)) != 0 && - find(codes.begin(), codes.end(), inset->lyxCode()) != codes.end() && - (contents.empty() || - static_cast<InsetCommand *>(pars_[pit].getInset(pos))->getContents() - == contents))); - - if (pit == end) - return false; - - setCursor(cur, pit, pos, false); - return true; -} - - -void LyXText::gotoInset(LCursor & cur, - vector<InsetBase_code> const & codes, bool same_content) -{ - cur.clearSelection(); - - string contents; - if (same_content - && cur.pos() < cur.lastpos() - && cur.paragraph().isInset(cur.pos())) { - InsetBase const * inset = cur.paragraph().getInset(cur.pos()); - if (find(codes.begin(), codes.end(), inset->lyxCode()) - != codes.end()) - contents = static_cast<InsetCommand const *>(inset)->getContents(); - } - - if (!gotoNextInset(cur, codes, contents)) { - if (cur.pos() || cur.pit() != 0) { - CursorSlice tmp = cur.top(); - cur.pit() = 0; - cur.pos() = 0; - if (!gotoNextInset(cur, codes, contents)) { - cur.top() = tmp; - cur.message(_("No more insets")); - } - } else { - cur.message(_("No more insets")); - } - } - cur.resetAnchor(); -} - - -void LyXText::gotoInset(LCursor & cur, InsetBase_code code, bool same_content) -{ - gotoInset(cur, vector<InsetBase_code>(1, code), same_content); -} - - bool LyXText::cursorPrevious(LCursor & cur) { pos_type cpos = cur.pos(); @@ -997,22 +924,6 @@ void LyXText::dispatch(LCursor & cur, Fu break; } - case LFUN_GOTOERROR: - gotoInset(cur, InsetBase::ERROR_CODE, false); - break; - - case LFUN_GOTONOTE: - gotoInset(cur, InsetBase::NOTE_CODE, false); - break; - - case LFUN_REFERENCE_GOTO: { - vector<InsetBase_code> tmp; - tmp.push_back(InsetBase::LABEL_CODE); - tmp.push_back(InsetBase::REF_CODE); - gotoInset(cur, tmp, true); - break; - } - case LFUN_QUOTE: { lyx::cap::replaceSelection(cur); Paragraph & par = cur.paragraph(); @@ -1887,9 +1798,6 @@ bool LyXText::getStatus(LCursor & cur, F case LFUN_GETLAYOUT: case LFUN_LAYOUT: case LFUN_PASTESELECTION: - case LFUN_GOTOERROR: - case LFUN_GOTONOTE: - case LFUN_REFERENCE_GOTO: case LFUN_DATE_INSERT: case LFUN_SELFINSERT: case LFUN_INSERT_LABEL: