> 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