> We need a way to differentiate multiple bookmarks in the same buffer.
> Paragraph number gives the user a sense of position. Anyway, if
> filename is given, filename + bookmark number for that file should be
> enough.

That would be a nice improvement over current situation anyway.

Go to Bookmark1 1|1 etc are hard-coded in stdmenus.ui. Is there a way
to dynamically change the name of a menu item (without resorting to
MenuBackend.h/C)? I guess I have to add a type in MenuBackend, and
show only one saveBookmark, and show "go to filename" only when a
bookmark is available. This is hard work and has to be done
separately.

Also, can anyone refresh my mind how bookmarks[0] is used? The
attached patch, in the order of changes:

1. handle bookmarks directly in session.h/C. NO separate bookmarks code.
2. LFUN_BOOKMARK_GOTO is always valid, even without a valid buffer.
3. What is view()->savePosition(0) used for?
4. LFUN_BOOKMARK_GOTO go to a bookmark, open a file or switch buffer if needed.
5. save/restorePosition are moved out of BufferView
6. savePosition is handled by session().bookmarks().save() directly.

The attached patch works nicely, except for the menu name change, and
savePosition(0). Opinions?

Cheers,
Bo

Index: src/session.C
===================================================================
--- src/session.C       (revision 15607)
+++ src/session.C       (working copy)
@@ -225,8 +225,8 @@
                itmp.ignore(2);  // ignore ", "
                itmp >> fname;
                // only load valid bookmarks
-               if (fs::exists(fname))
-                       bookmarks.push_back(boost::tie(num, fname, id, pos));
+               if (num < max_bookmarks && fs::exists(fname))
+                       bookmarks[num] = Bookmark(fname, id, pos);
        } while (is.good());
}

@@ -234,23 +234,32 @@
 void BookmarksSection::write(ostream & os) const
{
        os << '\n' << sec_bookmarks << '\n';
-       for (BookmarkList::const_iterator bm = bookmarks.begin();
-               bm != bookmarks.end(); ++bm) {
-               // save bookmark number, id, pos, fname
-               os << bm->get<0>() << ", "
-                       << bm->get<2>() << ", "
-                       << bm->get<3>() << ", "
-                       << bm->get<1>() << '\n';
+       for (size_t i = 0; i < max_bookmarks; ++i) {
+               if (!bookmarks[i].filename.empty()) {
+                       // save bookmark number, id, pos, fname
+                       os << i << ", "
+                               << bookmarks[i].par_id << ", "
+                               << bookmarks[i].par_pos << ", "
+                               << bookmarks[i].filename << '\n';
+               }
        }
}


-void BookmarksSection::save(Bookmark const & bookmark)
+void BookmarksSection::save(unsigned int i, std::string const &
fname, int par_id, pos_type par_pos)
{
-       bookmarks.push_back(bookmark);
+       if (i >= max_bookmarks)
+               return;
+       bookmarks[i] = Bookmark(fname, par_id, par_pos);
}


+bool BookmarksSection::isValid(unsigned int i)
+{
+       return i < max_bookmarks && !bookmarks[i].filename.empty();
+}
+
+
 void SessionInfoSection::read(istream & is)
{
        string tmp;
Index: src/lyxfunc.C
===================================================================
--- src/lyxfunc.C       (revision 15607)
+++ src/lyxfunc.C       (working copy)
@@ -352,6 +352,10 @@
                flag.message(from_utf8(N_("Exiting")));
                flag.enabled(true);
                return flag;
+       } else if (cmd.action == LFUN_BOOKMARK_GOTO) {
+               // bookmarks can be valid even if there is no opened buffer
+               
flag.enabled(LyX::ref().session().bookmarks().isValid(convert<unsigned
int>(to_utf8(cmd.argument()))));
+               return flag;
        }

        LCursor & cur = view()->cursor();
@@ -1035,8 +1039,6 @@
                                // save cursor Position for opened files to 
.lyx/session
                                
LyX::ref().session().lastFilePos().save(lyx_view_->buffer()->fileName(),
                                        boost::tie(view()->cursor().pit(), 
view()->cursor().pos()) );
-                               // save bookmarks to .lyx/session
-                               view()->saveSavedPositions();
                        }

                        LyX::ref().quit();
@@ -1342,7 +1344,8 @@
                        // FIXME Should use bformat
                        setMessage(_("Opening child document ") +
                                         makeDisplayPath(filename) + "...");
-                       view()->savePosition(0);
+                       //// FIXME: bookmark[0]
+                       //view()->savePosition(0);
                        string const parentfilename = 
lyx_view_->buffer()->fileName();
                        if (theBufferList().exists(filename))
                                
lyx_view_->setBuffer(theBufferList().getBuffer(filename));
@@ -1660,6 +1663,24 @@
                        // We return here because lyx_view does not exists 
anymore.
                        return;

+               case LFUN_BOOKMARK_GOTO: {
+                       unsigned int idx = convert<unsigned 
int>(to_utf8(cmd.argument()));
+                       BookmarksSection::Bookmark bm =
LyX::ref().session().bookmarks().bookmark(idx);
+                       // if the file is not opened, open it.
+                       if (!theBufferList().exists(bm.filename))
+                               open(bm.filename);
+                       // well, open may fail, so we need to test it again
+                       if (theBufferList().exists(bm.filename)) {
+                               // if the current buffer is not that one
+                               if (lyx_view_->buffer()->fileName() != 
bm.filename)
+                                       // now switch to that buff.
+                                       
dispatch(FuncRequest(LFUN_BUFFER_SWITCH, bm.filename));
+                               BOOST_ASSERT(lyx_view_->buffer()->fileName() != 
bm.filename);
+                               view()->restorePosition(bm.par_id, bm.par_pos);
+                       }
+                       break;
+               }
+
                default: {
                        BOOST_ASSERT(lyx_view_);
                        view()->cursor().dispatch(cmd);
Index: src/session.h
===================================================================
--- src/session.h       (revision 15607)
+++ src/session.h       (working copy)
@@ -173,24 +173,47 @@
 class BookmarksSection : SessionSection
{
public:
-       ///
-       typedef boost::tuple<unsigned int, std::string, unsigned int,
pos_type> Bookmark;
+       /// bookmarks
+       class Bookmark {
+       public:
+               /// Filename
+               std::string filename;
+               /// Cursor paragraph Id
+               int par_id;
+               /// Cursor position
+               pos_type par_pos;
+               ///
+               Bookmark() : par_id(0), par_pos(0) {}
+               ///
+               Bookmark(std::string const & f, int id, pos_type pos)
+                       : filename(f), par_id(id), par_pos(pos) {}
+       };

        ///
        typedef std::vector<Bookmark> BookmarkList;

public:
+       /// constructor, set max_bookmarks
+       BookmarksSection::BookmarksSection() : max_bookmarks(20), bookmarks(20) 
{}
+
+       /// Save the current position as bookmark i
+       void save(unsigned int i, std::string const & fname, int par_id,
pos_type par_pos);
+
+       /// return bookmark
+       Bookmark const & bookmark(unsigned int i) const { return bookmarks[i]; }
+
+       /// does the given bookmark have a saved position ?
+       bool isValid(unsigned int i);
+
        ///
+       unsigned int maxBookmarks() const { return max_bookmarks; }
+
+       ///
        void read(std::istream & is);

        ///
        void write(std::ostream & os) const;

-       /** save a bookmark
-               @bookmark bookmark to be saved
-       */
-       void save(Bookmark const & bookmark);
-
        /** return bookmark list. Non-const container is used since
                bookmarks will be cleaned after use.
        */
@@ -199,6 +222,9 @@
private:
        /// a list of bookmarks
        BookmarkList bookmarks;
+
+       ///
+       unsigned int const max_bookmarks;
};


Index: src/BufferView.C
===================================================================
--- src/BufferView.C    (revision 15607)
+++ src/BufferView.C    (working copy)
@@ -129,17 +129,6 @@
          intl_(new Intl)
{
        xsel_cache_.set = false;
-
-       saved_positions.resize(saved_positions_num);
-       // load saved bookmarks
-       BookmarksSection::BookmarkList & bmList =
LyX::ref().session().bookmarks().load();
-       for (BookmarksSection::BookmarkList::iterator bm = bmList.begin();
-               bm != bmList.end(); ++bm)
-               if (bm->get<0>() < saved_positions_num)
-                       saved_positions[bm->get<0>()] = Position( bm->get<1>(),
bm->get<2>(), bm->get<3>() );
-       // and then clear them
-       bmList.clear();
-
        intl_->initKeyMapper(lyxrc.use_kbmap);
}

@@ -514,74 +503,18 @@
}


-void BufferView::savePosition(unsigned int i)
+void BufferView::restorePosition(int par_id, pos_type par_pos)
{
-       if (i >= saved_positions_num)
-               return;
-       BOOST_ASSERT(cursor_.inTexted());
-       saved_positions[i] = Position(buffer_->fileName(),
-                                     cursor_.paragraph().id(),
-                                     cursor_.pos());
-       if (i > 0)
-               // emit message signal.
-               message(bformat(_("Saved bookmark %1$d"), i));
-}
-
-
-void BufferView::restorePosition(unsigned int i)
-{
-       if (i >= saved_positions_num)
-               return;
-
-       string const fname = saved_positions[i].filename;
-
        cursor_.clearSelection();

-       if (fname != buffer_->fileName()) {
-               Buffer * b = 0;
-               if (theBufferList().exists(fname))
-                       b = theBufferList().getBuffer(fname);
-               else {
-                       b = theBufferList().newBuffer(fname);
-                       // Don't ask, just load it
-                       lyx::loadLyXFile(b, fname);
-               }
-               if (b)
-                       setBuffer(b);
-       }
-
-       ParIterator par = buffer_->getParFromID(saved_positions[i].par_id);
+       ParIterator par = buffer_->getParFromID(par_id);
        if (par == buffer_->par_iterator_end())
                return;

-       setCursor(makeDocIterator(par, min(par->size(), 
saved_positions[i].par_pos)));
-
-       if (i > 0)
-               // emit message signal.
-               message(bformat(_("Moved to bookmark %1$d"), i));
+       setCursor(makeDocIterator(par, min(par->size(), par_pos)));
}


-bool BufferView::isSavedPosition(unsigned int i)
-{
-       return i < saved_positions_num && !saved_positions[i].filename.empty();
-}
-
-void BufferView::saveSavedPositions()
-{
-       // save bookmarks. It is better to use the pit interface
-       // but I do not know how to effectively convert between
-       // par_id and pit.
-       for (unsigned int i=1; i < saved_positions_num; ++i) {
-               if ( isSavedPosition(i) )
-                       LyX::ref().session().bookmarks().save( boost::tie(
-                               i,
-                               saved_positions[i].filename,
-                               saved_positions[i].par_id,
-                               saved_positions[i].par_pos) );
-       }
-}
-
 void BufferView::switchKeyMap()
{
        if (!lyxrc.rtl_support)
@@ -663,10 +596,6 @@
                break;
        }

-       case LFUN_BOOKMARK_GOTO:
-               flag.enabled(isSavedPosition(convert<unsigned
int>(to_utf8(cmd.argument()))));
-               break;
-
        case LFUN_CHANGES_TRACK:
                flag.enabled(true);
                flag.setOnOff(buffer_->params().trackChanges);
@@ -760,13 +689,14 @@
                break;

        case LFUN_BOOKMARK_SAVE:
-               savePosition(convert<unsigned int>(to_utf8(cmd.argument())));
+               LyX::ref().session().bookmarks().save(
+                       convert<unsigned int>(to_utf8(cmd.argument())),
+                       buffer_->fileName(),
+                       cursor_.paragraph().id(),
+                       cursor_.pos()
+                       );
                break;

-       case LFUN_BOOKMARK_GOTO:
-               restorePosition(convert<unsigned int>(to_utf8(cmd.argument())));
-               break;
-
        case LFUN_LABEL_GOTO: {
                docstring label = cmd.argument();
                if (label.empty()) {
@@ -775,7 +705,8 @@
                                                         InsetBase::REF_CODE);
                        if (inset) {
                                label = inset->getParam("reference");
-                               savePosition(0);
+                               // FIXME FIXME: what is this position?
+                               //savePosition(0);
                        }
                }

Index: src/BufferView.h
===================================================================
--- src/BufferView.h    (revision 15607)
+++ src/BufferView.h    (working copy)
@@ -102,15 +102,8 @@
        /// return the Scrollbar Parameters
        ScrollbarParameters const & scrollbarParameters() const;

-       /// Save the current position as bookmark i
-       void savePosition(unsigned int i);
        /// Restore the position from bookmark i
-       void restorePosition(unsigned int i);
-       /// does the given bookmark have a saved position ?
-       bool isSavedPosition(unsigned int i);
-       /// save bookmarks to .lyx/session
-       void saveSavedPositions();
-
+       void restorePosition(int par_id, pos_type par_pos);
        /// return the current change at the cursor
        Change const getCurrentChange() const;

@@ -237,23 +230,7 @@
        /// Estimated average par height for scrollbar
        int wh_;
        ///
-       class Position {
-       public:
-               /// Filename
-               std::string filename;
-               /// Cursor paragraph Id
-               int par_id;
-               /// Cursor position
-               pos_type par_pos;
-               ///
-               Position() : par_id(0), par_pos(0) {}
-               ///
-               Position(std::string const & f, int id, pos_type pos)
-                       : filename(f), par_id(id), par_pos(pos) {}
-       };
        ///
-       std::vector<Position> saved_positions;
-       ///
        void menuInsertLyXFile(std::string const & filen);

        /// this is used to handle XSelection events in the right manner

Reply via email to