Dear list,
The patch does not add or change any feature of session.h/C. It
separates session class into sections. Adding features like
session/toolbars will be much easier (and cleaner) using the new
interfaces.
The patch is messy so session.h/C are also attached. Will apply
tomorrow (subject to final adjust of style) if there is no objection.
Cheers,
Bo
Index: src/lyx_cb.C
===================================================================
--- src/lyx_cb.C (revision 15573)
+++ src/lyx_cb.C (working copy)
@@ -101,7 +101,7 @@
bool menuWrite(Buffer * buffer)
{
if (buffer->save()) {
- LyX::ref().session().addLastFile(buffer->fileName());
+ LyX::ref().session().LastFiles().add(buffer->fileName());
return true;
}
Index: src/bufferlist.C
===================================================================
--- src/bufferlist.C (revision 15573)
+++ src/bufferlist.C (working copy)
@@ -135,7 +135,7 @@
// if master/slave are both open, do not save slave since it
// will be automatically loaded when the master is loaded
if ((*it)->getMasterBuffer() == (*it))
- LyX::ref().session().addLastOpenedFile((*it)->fileName());
+ LyX::ref().session().LastOpened().add((*it)->fileName());
}
return true;
Index: src/session.C
===================================================================
--- src/session.C (revision 15573)
+++ src/session.C (working copy)
@@ -33,6 +33,8 @@
using std::string;
using std::ifstream;
using std::ofstream;
+using std::istream;
+using std::ostream;
using std::endl;
using std::istringstream;
using std::copy;
@@ -46,32 +48,21 @@
string const sec_lastopened = "[last opened files]";
string const sec_bookmarks = "[bookmarks]";
string const sec_session = "[session info]";
-int const id_lastfiles = 0;
-int const id_lastfilepos = 1;
-int const id_lastopened = 2;
-int const id_bookmarks = 3;
-int const id_session = 4;
} // anon namespace
namespace lyx {
-Session::Session(unsigned int num) :
+LastFilesSection::LastFilesSection(unsigned int num) :
default_num_last_files(4),
- absolute_max_last_files(100),
- num_lastfilepos(100)
+ absolute_max_last_files(100)
{
setNumberOfLastFiles(num);
- // locate the session file
- // note that the session file name 'session' is hard-coded
- session_file = addName(package().user_support(), "session");
- //
- readFile();
}
-void Session::setNumberOfLastFiles(unsigned int no)
+void LastFilesSection::setNumberOfLastFiles(unsigned int no)
{
if (0 < no && no <= absolute_max_last_files)
num_lastfiles = no;
@@ -84,134 +75,31 @@
}
-void Session::readFile()
+void LastFilesSection::read(istream & is)
{
- // we will not complain if we can't find session_file nor will
- // we issue a warning. (Lgb)
- ifstream ifs(session_file.c_str());
string tmp;
- int section = -1;
-
- // the following is currently not implemented very
- // robustly. (Manually editing of the session file may crash lyx)
- //
- while (getline(ifs, tmp)) {
- // Ignore comments, empty line or line stats with ' '
- if (tmp == "" || tmp[0] == '#' || tmp[0] == ' ')
+ do {
+ char c = is.peek();
+ if (c == '[')
+ break;
+ getline(is, tmp);
+ // read lastfiles
+ if (!fs::exists(tmp) || lastfiles.size() >= num_lastfiles)
continue;
-
- // Determine section id
- if (tmp == sec_lastfiles) {
- section = id_lastfiles;
- } else if (tmp == sec_lastfilepos) {
- section = id_lastfilepos;
- } else if (tmp == sec_lastopened) {
- section = id_lastopened;
- } else if (tmp == sec_bookmarks) {
- section = id_bookmarks;
- } else if (tmp == sec_session) {
- section = id_session;
- } else if (section == id_lastfiles) {
- // read lastfiles
- if (!fs::exists(tmp) || lastfiles.size() >= num_lastfiles)
- continue;
- lastfiles.push_back(tmp);
- } else if (section == id_lastfilepos) {
- // read lastfilepos
- // pos, file\n
- pit_type pit;
- pos_type pos;
- string fname;
- istringstream itmp(tmp);
- itmp >> pit;
- itmp.ignore(2); // ignore ", "
- itmp >> pos;
- itmp.ignore(2); // ignore ", "
- itmp >> fname;
- if (!fs::exists(fname) || lastfilepos.size() >= num_lastfilepos)
- continue;
- lastfilepos[fname] = boost::tie(pit, pos);
- } else if (section == id_lastopened) {
- // read lastopened
- // files
- if (!fs::exists(tmp))
- continue;
- lastopened.push_back(tmp);
- } else if (section == id_bookmarks) {
- // read bookmarks
- // bookmarkid, id, pos, file\n
- unsigned int num;
- unsigned int id;
- pos_type pos;
- string fname;
- istringstream itmp(tmp);
- itmp >> num;
- itmp.ignore(2); // ignore ", "
- itmp >> id;
- itmp.ignore(2); // ignore ", "
- itmp >> pos;
- itmp.ignore(2); // ignore ", "
- itmp >> fname;
- // only load valid bookmarks
- if (fs::exists(fname))
- bookmarks.push_back(boost::tie(num, fname, id, pos));
- } else if (section == id_session) {
- // Read session info, saved as key/value pairs
- // would better yell if pos returns npos
- string::size_type pos = tmp.find_first_of(" = ");
- string key = tmp.substr(0, pos);
- string value = tmp.substr(pos + 3);
- sessioninfo[key] = value;
- }
- }
+ lastfiles.push_back(tmp);
+ } while (is.good());
}
-void Session::writeFile() const
+void LastFilesSection::write(ostream & os) const
{
- ofstream ofs(session_file.c_str());
- if (ofs) {
- ofs << "## Automatically generated lyx session file \n"
- << "## Editing this file manually may cause lyx to crash.\n";
- // first section
- ofs << '\n' << sec_lastfiles << '\n';
- copy(lastfiles.begin(), lastfiles.end(),
- ostream_iterator<string>(ofs, "\n"));
- // second section
- ofs << '\n' << sec_lastfilepos << '\n';
- for (FilePosMap::const_iterator file = lastfilepos.begin();
- file != lastfilepos.end(); ++file) {
- ofs << file->second.get<0>() << ", "
- << file->second.get<1>() << ", "
- << file->first << '\n';
- }
- // third section
- ofs << '\n' << sec_lastopened << '\n';
- copy(lastopened.begin(), lastopened.end(),
- ostream_iterator<string>(ofs, "\n"));
- // fourth section
- ofs << '\n' << sec_bookmarks << '\n';
- for (BookmarkList::const_iterator bm = bookmarks.begin();
- bm != bookmarks.end(); ++bm) {
- // save bookmark number, id, pos, fname
- ofs << bm->get<0>() << ", "
- << bm->get<2>() << ", "
- << bm->get<3>() << ", "
- << bm->get<1>() << '\n';
- }
- // fifth section
- ofs << '\n' << sec_session << '\n';
- for (MiscInfo::const_iterator val = sessioninfo.begin();
- val != sessioninfo.end(); ++val) {
- ofs << val->first << " = " << val->second << '\n';
- }
- } else
- lyxerr << "LyX: Warning: unable to save Session: "
- << session_file << endl;
+ os << '\n' << sec_lastfiles << '\n';
+ copy(lastfiles.begin(), lastfiles.end(),
+ ostream_iterator<string>(os, "\n"));
}
-void Session::addLastFile(string const & file)
+void LastFilesSection::add(string const & file)
{
// If file already exist, delete it and reinsert at front.
LastFiles::iterator it = find(lastfiles.begin(), lastfiles.end(), file);
@@ -223,13 +111,86 @@
}
-void Session::saveFilePosition(string const & fname, FilePos pos)
+void LastOpenedSection::read(istream & is)
{
+ string tmp;
+ do {
+ char c = is.peek();
+ if (c == '[')
+ break;
+ getline(is, tmp);
+ if (!fs::exists(tmp))
+ continue;
+ lastopened.push_back(tmp);
+ } while (is.good());
+}
+
+
+void LastOpenedSection::write(ostream & os) const
+{
+ os << '\n' << sec_lastopened << '\n';
+ copy(lastopened.begin(), lastopened.end(),
+ ostream_iterator<string>(os, "\n"));
+}
+
+
+void LastOpenedSection::clear()
+{
+ lastopened.clear();
+}
+
+
+void LastOpenedSection::add(string const & file)
+{
+ lastopened.push_back(file);
+}
+
+
+void LastFilePosSection::read(istream & is)
+{
+ string tmp;
+ do {
+ char c = is.peek();
+ if (c == '[')
+ break;
+ getline(is, tmp);
+ // read lastfilepos
+ // pos, file\n
+ pit_type pit;
+ pos_type pos;
+ string fname;
+ istringstream itmp(tmp);
+ itmp >> pit;
+ itmp.ignore(2); // ignore ", "
+ itmp >> pos;
+ itmp.ignore(2); // ignore ", "
+ itmp >> fname;
+ if (!fs::exists(fname) || lastfilepos.size() >= num_lastfilepos)
+ continue;
+ lastfilepos[fname] = boost::tie(pit, pos);
+ } while (is.good());
+}
+
+
+void LastFilePosSection::write(ostream & os) const
+{
+ os << '\n' << sec_lastfilepos << '\n';
+ for (FilePosMap::const_iterator file = lastfilepos.begin();
+ file != lastfilepos.end(); ++file) {
+ os << file->second.get<0>() << ", "
+ << file->second.get<1>() << ", "
+ << file->first << '\n';
+ }
+}
+
+
+void LastFilePosSection::save(string const & fname, FilePos pos)
+{
lastfilepos[fname] = pos;
}
-Session::FilePos Session::loadFilePosition(string const & fname) const
+LastFilePosSection::FilePos LastFilePosSection::load(string const & fname) const
{
FilePosMap::const_iterator entry = lastfilepos.find(fname);
// Has position information, return it.
@@ -241,31 +202,91 @@
}
-void Session::clearLastOpenedFiles()
+void BookmarksSection::read(istream & is)
{
- lastopened.clear();
+ string tmp;
+ do {
+ char c = is.peek();
+ if (c == '[')
+ break;
+ getline(is, tmp);
+ // read bookmarks
+ // bookmarkid, id, pos, file\n
+ unsigned int num;
+ unsigned int id;
+ pos_type pos;
+ string fname;
+ istringstream itmp(tmp);
+ itmp >> num;
+ itmp.ignore(2); // ignore ", "
+ itmp >> id;
+ itmp.ignore(2); // ignore ", "
+ itmp >> pos;
+ itmp.ignore(2); // ignore ", "
+ itmp >> fname;
+ // only load valid bookmarks
+ if (fs::exists(fname))
+ bookmarks.push_back(boost::tie(num, fname, id, pos));
+ } while (is.good());
}
-void Session::addLastOpenedFile(string const & file)
+void BookmarksSection::write(ostream & os) const
{
- lastopened.push_back(file);
+ 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';
+ }
}
-void Session::saveBookmark(Bookmark const & bookmark)
+void BookmarksSection::save(Bookmark const & bookmark)
{
bookmarks.push_back(bookmark);
}
-void Session::saveSessionInfo(string const & key, string const & value)
+void SessionInfoSection::read(istream & is)
{
+ string tmp;
+ do {
+ char c = is.peek();
+ if (c == '[')
+ break;
+ getline(is, tmp);
+
+ // Read session info, saved as key/value pairs
+ // would better yell if pos returns npos
+ string::size_type pos = tmp.find_first_of(" = ");
+ string key = tmp.substr(0, pos);
+ string value = tmp.substr(pos + 3);
+ sessioninfo[key] = value;
+ } while (is.good());
+}
+
+
+void SessionInfoSection::write(ostream & os) const
+{
+ os << '\n' << sec_session << '\n';
+ for (MiscInfo::const_iterator val = sessioninfo.begin();
+ val != sessioninfo.end(); ++val) {
+ os << val->first << " = " << val->second << '\n';
+ }
+}
+
+
+void SessionInfoSection::save(string const & key, string const & value)
+{
sessioninfo[key] = value;
}
-string const Session::loadSessionInfo(string const & key, bool release)
+string const SessionInfoSection::load(string const & key, bool release)
{
MiscInfo::const_iterator pos = sessioninfo.find(key);
string value;
@@ -276,4 +297,63 @@
return value;
}
+
+
+Session::Session(unsigned int num) :
+ last_files(num)
+{
+ // locate the session file
+ // note that the session file name 'session' is hard-coded
+ session_file = addName(package().user_support(), "session");
+ //
+ readFile();
}
+
+
+void Session::readFile()
+{
+ // we will not complain if we can't find session_file nor will
+ // we issue a warning. (Lgb)
+ ifstream is(session_file.c_str());
+ string tmp;
+
+ while (getline(is, tmp)) {
+ // Ignore comments, empty line or line stats with ' '
+ if (tmp == "" || tmp[0] == '#' || tmp[0] == ' ')
+ continue;
+
+ // Determine section id
+ if (tmp == sec_lastfiles)
+ LastFiles().read(is);
+ else if (tmp == sec_lastopened)
+ LastOpened().read(is);
+ else if (tmp == sec_lastfilepos)
+ LastFilePos().read(is);
+ else if (tmp == sec_bookmarks)
+ Bookmarks().read(is);
+ else if (tmp == sec_session)
+ SessionInfo().read(is);
+ else
+ lyxerr << "LyX: Warning: unknown Session section: " << tmp << endl;
+ }
+}
+
+
+void Session::writeFile() const
+{
+ ofstream os(session_file.c_str());
+ if (os) {
+ os << "## Automatically generated lyx session file \n"
+ << "## Editing this file manually may cause lyx to crash.\n";
+
+ LastFiles().write(os);
+ LastOpened().write(os);
+ LastFilePos().write(os);
+ Bookmarks().write(os);
+ SessionInfo().write(os);
+ } else
+ lyxerr << "LyX: Warning: unable to save Session: "
+ << session_file << endl;
+}
+
+}
Index: src/lyxfunc.C
===================================================================
--- src/lyxfunc.C (revision 15573)
+++ src/lyxfunc.C (working copy)
@@ -1033,7 +1033,7 @@
// might be visible in more than one LyXView.
if (lyx_view_ && lyx_view_->view()->buffer()) {
// save cursor Position for opened files to .lyx/session
- LyX::ref().session().saveFilePosition(lyx_view_->buffer()->fileName(),
+ LyX::ref().session().LastFilePos().save(lyx_view_->buffer()->fileName(),
boost::tie(view()->cursor().pit(), view()->cursor().pos()) );
// save bookmarks to .lyx/session
view()->saveSavedPositions();
@@ -1968,7 +1968,7 @@
void LyXFunc::closeBuffer()
{
// save current cursor position
- LyX::ref().session().saveFilePosition(lyx_view_->buffer()->fileName(),
+ LyX::ref().session().LastFilePos().save(lyx_view_->buffer()->fileName(),
boost::tie(view()->cursor().pit(), view()->cursor().pos()) );
if (theBufferList().close(lyx_view_->buffer(), true) && !quitting) {
if (theBufferList().empty()) {
Index: src/frontends/qt4/GuiView.C
===================================================================
--- src/frontends/qt4/GuiView.C (revision 15573)
+++ src/frontends/qt4/GuiView.C (working copy)
@@ -137,12 +137,12 @@
// save windows size and position
Session & session = LyX::ref().session();
- session.saveSessionInfo("WindowWidth", convert<string>(geometry.width()));
- session.saveSessionInfo("WindowHeight", convert<string>(geometry.height()));
- session.saveSessionInfo("WindowIsMaximized", (isMaximized() ? "yes" : "no"));
+ session.SessionInfo().save("WindowWidth", convert<string>(geometry.width()));
+ session.SessionInfo().save("WindowHeight", convert<string>(geometry.height()));
+ session.SessionInfo().save("WindowIsMaximized", (isMaximized() ? "yes" : "no"));
if (lyxrc.geometry_xysaved) {
- session.saveSessionInfo("WindowPosX", convert<string>(geometry.x()));
- session.saveSessionInfo("WindowPosY", convert<string>(geometry.y()));
+ session.SessionInfo().save("WindowPosX", convert<string>(geometry.x()));
+ session.SessionInfo().save("WindowPosY", convert<string>(geometry.y()));
}
}
Index: src/session.h
===================================================================
--- src/session.h (revision 15573)
+++ src/session.h (working copy)
@@ -35,34 +35,22 @@
*/
namespace lyx {
-class Session : boost::noncopyable {
+class SessionSection : boost::noncopyable {
public:
- ///
- typedef boost::tuple<pit_type, pos_type> FilePos;
- ///
- typedef std::map<std::string, FilePos> FilePosMap;
- ///
- typedef std::deque<std::string> LastFiles;
- ///
- typedef std::vector<std::string> LastOpened;
- ///
- typedef boost::tuple<unsigned int, std::string, unsigned int, pos_type> Bookmark;
- ///
- typedef std::vector<Bookmark> BookmarkList;
- ///
- typedef std::map<std::string, std::string> MiscInfo;
+ /// read section from std::istream
+ virtual void read(std::istream & is) = 0;
-public:
- /** Read the session file.
- @param num length of lastfiles
- */
- explicit Session(unsigned int num = 4);
+ /// write to std::ostream
+ virtual void write(std::ostream & os) const = 0;
+};
- /** Write the session file.
- */
- void writeFile() const;
+class LastFilesSection : SessionSection
+{
+public:
+ ///
+ typedef std::deque<std::string> LastFiles;
/** Insert #file# into the lastfile dequeue.
This funtion inserts #file# into the last files list. If the file
already exists it is moved to the top of the list, else exist it
@@ -70,87 +58,219 @@
file in the list is popped from the end.
@param file the file to insert in the lastfile list.
*/
- void addLastFile(std::string const & file);
+ void add(std::string const & file);
- /** add cursor position to the fname entry in the filepos map
- @param fname file entry for which to save position information
- @param pos position of the cursor when the file is closed.
+public:
+ ///
+ explicit LastFilesSection(unsigned int num = 4);
+
+ ///
+ void read(std::istream & is);
+
+ ///
+ void write(std::ostream & os) const;
+
+ /// Return lastfiles container (deque)
+ LastFiles const lastFiles() const { return lastfiles; }
+
+private:
+ /// Default number of lastfiles.
+ unsigned int const default_num_last_files;
+
+ /// Max number of lastfiles.
+ unsigned int const absolute_max_last_files;
+
+ /// a list of lastfiles
+ LastFiles lastfiles;
+
+ /// number of files in the lastfiles list.
+ unsigned int num_lastfiles;
+
+ /** Used by the constructor to set the number of stored last files.
+ @param num the number of lastfiles to set.
*/
- void saveFilePosition(std::string const & fname, FilePos pos);
+ void setNumberOfLastFiles(unsigned int num);
+};
+
+class LastOpenedSection : SessionSection
+{
+
+public:
+ ///
+ typedef std::vector<std::string> LastOpened;
+
/** clear lastopened file list
*/
- void clearLastOpenedFiles();
+ void clear();
/** add file to lastopened file list
@param file filename to add
*/
- void addLastOpenedFile(std::string const & file);
+ void add(std::string const & file);
+ /// Return lastopened container (vector)
+ LastOpened const lastOpenedFiles() const { return lastopened; }
+
+ ///
+ void read(std::istream & is);
+
+ ///
+ void write(std::ostream & os) const;
+
+private:
+ /// a list of lastopened files
+ LastOpened lastopened;
+};
+
+
+class LastFilePosSection : SessionSection
+{
+public:
+ ///
+ LastFilePosSection() : num_lastfilepos(100) {}
+
+ ///
+ typedef boost::tuple<pit_type, pos_type> FilePos;
+
+ ///
+ typedef std::map<std::string, FilePos> FilePosMap;
+
+ /** add cursor position to the fname entry in the filepos map
+ @param fname file entry for which to save position information
+ @param pos position of the cursor when the file is closed.
+ */
+ void save(std::string const & fname, FilePos pos);
+
/** load saved cursor position from the fname entry in the filepos map
@param fname file entry for which to load position information
*/
- FilePos loadFilePosition(std::string const & fname) const;
+ FilePos load(std::string const & fname) const;
- /// Return lastfiles container (deque)
- LastFiles const lastFiles() const { return lastfiles; }
+ ///
+ void read(std::istream & is);
- /// Return lastopened container (vector)
- LastOpened const lastOpenedFiles() const { return lastopened; }
+ ///
+ void write(std::ostream & os) const;
+private:
+ /// default number of lastfilepos to save */
+ unsigned int const num_lastfilepos;
+
+
+ /// a map of file positions
+ FilePosMap lastfilepos;
+};
+
+
+class BookmarksSection : SessionSection
+{
+public:
+ ///
+ void read(std::istream & is);
+
+ ///
+ void write(std::ostream & os) const;
+
+ /// ///
+ typedef boost::tuple<unsigned int, std::string, unsigned int, pos_type> Bookmark;
+
+ ///
+ typedef std::vector<Bookmark> BookmarkList;
+
/** save a bookmark
@bookmark bookmark to be saved
*/
- void saveBookmark(Bookmark const & bookmark);
+ void save(Bookmark const & bookmark);
/** return bookmark list. Non-const container is used since
bookmarks will be cleaned after use.
*/
- BookmarkList & loadBookmarks() { return bookmarks; }
+ BookmarkList & load() { return bookmarks; }
+private:
+ /// a list of bookmarks
+ BookmarkList bookmarks;
+};
+
+
+class SessionInfoSection : SessionSection
+{
+public:
+ ///
+ void read(std::istream & is);
+
+ ///
+ void write(std::ostream & os) const;
+
+ ///
+ typedef std::map<std::string, std::string> MiscInfo;
+
/** set session info
@param key key of the value to store
@param value value, a string without newline ('\n')
*/
- void saveSessionInfo(std::string const & key, std::string const & value);
+ void save(std::string const & key, std::string const & value);
/** load session info
@param key a key to extract value from the session file
@param release whether or not clear the value. Default to true
since most of such values are supposed to be used only once.
*/
- std::string const loadSessionInfo(std::string const & key, bool release = true);
+ std::string const load(std::string const & key, bool release = true);
+
private:
- /// Default number of lastfiles.
- unsigned int const default_num_last_files;
+ /// a map to save session info
+ MiscInfo sessioninfo;
+};
- /// Max number of lastfiles.
- unsigned int const absolute_max_last_files;
- /// default number of lastfilepos to save */
- unsigned int const num_lastfilepos;
+class Session : boost::noncopyable {
- /// file to save session, determined in the constructor.
- std::string session_file;
+public:
+ /** Read the session file.
+ @param num length of lastfiles
+ */
+ explicit Session(unsigned int num = 4);
- /// a list of lastfiles
- LastFiles lastfiles;
+ /** Write the session file.
+ */
+ void writeFile() const;
- /// a list of bookmarks
- BookmarkList bookmarks;
+ ///
+ LastFilesSection & LastFiles() { return last_files; }
+
+ ///
+ LastFilesSection const & LastFiles() const { return last_files; }
- /// a map to save session info
- MiscInfo sessioninfo;
+ ///
+ LastOpenedSection & LastOpened() { return last_opened; }
- /// number of files in the lastfiles list.
- unsigned int num_lastfiles;
+ ///
+ LastOpenedSection const & LastOpened() const { return last_opened; }
+
+ ///
+ LastFilePosSection & LastFilePos() { return last_file_pos; }
+
+ ///
+ LastFilePosSection const & LastFilePos() const { return last_file_pos; }
- /// a map of file positions
- FilePosMap lastfilepos;
+ ///
+ BookmarksSection & Bookmarks() { return bookmarks; }
- /// a list of lastopened files
- LastOpened lastopened;
+ ///
+ BookmarksSection const & Bookmarks() const { return bookmarks; }
+ ///
+ SessionInfoSection & SessionInfo() { return session_info; }
+
+ ///
+ SessionInfoSection const & SessionInfo() const { return session_info; }
+
+private:
+ /// file to save session, determined in the constructor.
+ std::string session_file;
+
/** Read the session file.
Reads the #.lyx/session# at the beginning of the LyX session.
This will read the session file (usually #.lyx/session#).
@@ -158,10 +278,20 @@
*/
void readFile();
- /** Used by the constructor to set the number of stored last files.
- @param num the number of lastfiles to set.
- */
- void setNumberOfLastFiles(unsigned int num);
+ ///
+ LastFilesSection last_files;
+
+ ///
+ LastOpenedSection last_opened;
+
+ ///
+ LastFilePosSection last_file_pos;
+
+ ///
+ BookmarksSection bookmarks;
+
+ ///
+ SessionInfoSection session_info;
};
}
Index: src/BufferView.C
===================================================================
--- src/BufferView.C (revision 15573)
+++ src/BufferView.C (working copy)
@@ -132,8 +132,8 @@
saved_positions.resize(saved_positions_num);
// load saved bookmarks
- Session::BookmarkList & bmList = LyX::ref().session().loadBookmarks();
- for (Session::BookmarkList::iterator bm = bmList.begin();
+ 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>() );
@@ -167,7 +167,7 @@
buffer_->saveCursor(cursor_.selectionBegin(),
cursor_.selectionEnd());
// current buffer is going to be switched-off, save cursor pos
- LyX::ref().session().saveFilePosition(buffer_->fileName(),
+ LyX::ref().session().LastFilePos().save(buffer_->fileName(),
boost::tie(cursor_.pit(), cursor_.pos()) );
}
@@ -280,7 +280,7 @@
if (lyxrc.use_lastfilepos) {
pit_type pit;
pos_type pos;
- boost::tie(pit, pos) = LyX::ref().session().loadFilePosition(s);
+ boost::tie(pit, pos) = LyX::ref().session().LastFilePos().load(s);
// I am not sure how to separate the following part to a function
// so I will leave this to Lars.
//
@@ -299,7 +299,7 @@
}
if (tolastfiles)
- LyX::ref().session().addLastFile(b->fileName());
+ LyX::ref().session().LastFiles().add(b->fileName());
return true;
}
@@ -574,7 +574,7 @@
// par_id and pit.
for (unsigned int i=1; i < saved_positions_num; ++i) {
if ( isSavedPosition(i) )
- LyX::ref().session().saveBookmark( boost::tie(
+ LyX::ref().session().Bookmarks().save( boost::tie(
i,
saved_positions[i].filename,
saved_positions[i].par_id,
Index: src/MenuBackend.C
===================================================================
--- src/MenuBackend.C (revision 15573)
+++ src/MenuBackend.C (working copy)
@@ -427,8 +427,8 @@
void expandLastfiles(Menu & tomenu)
{
- lyx::Session::LastFiles const & lf = LyX::cref().session().lastFiles();
- lyx::Session::LastFiles::const_iterator lfit = lf.begin();
+ lyx::LastFilesSection::LastFiles const & lf = LyX::cref().session().LastFiles().lastFiles();
+ lyx::LastFilesSection::LastFiles::const_iterator lfit = lf.begin();
int ii = 1;
Index: src/lyx_main.C
===================================================================
--- src/lyx_main.C (revision 15573)
+++ src/lyx_main.C (working copy)
@@ -493,7 +493,7 @@
// if a file is specified, I assume that user wants to edit *that* file
if (files.empty() && lyxrc.load_session) {
- vector<string> const & lastopened = pimpl_->session_->lastOpenedFiles();
+ vector<string> const & lastopened = pimpl_->session_->LastOpened().lastOpenedFiles();
// do not add to the lastfile list since these files are restored from
// last seesion, and should be already there (regular files), or should
// not be added at all (help files).
@@ -501,7 +501,7 @@
bind(&LyXView::loadLyXFile, view, _1, false));
}
// clear this list to save a few bytes of RAM
- pimpl_->session_->clearLastOpenedFiles();
+ pimpl_->session_->LastOpened().clear();
}
@@ -522,13 +522,13 @@
}
// if lyxrc returns (0,0), then use session info
else {
- string val = session().loadSessionInfo("WindowWidth");
+ string val = session().SessionInfo().load("WindowWidth");
if (!val.empty())
width = convert<unsigned int>(val);
- val = session().loadSessionInfo("WindowHeight");
+ val = session().SessionInfo().load("WindowHeight");
if (!val.empty())
height = convert<unsigned int>(val);
- if (session().loadSessionInfo("WindowIsMaximized") == "yes")
+ if (session().SessionInfo().load("WindowIsMaximized") == "yes")
maximize = true;
}
@@ -536,10 +536,10 @@
int posx = -1;
int posy = -1;
if (lyxrc.geometry_xysaved) {
- string val = session().loadSessionInfo("WindowPosX");
+ string val = session().SessionInfo().load("WindowPosX");
if (!val.empty())
posx = convert<int>(val);
- val = session().loadSessionInfo("WindowPosY");
+ val = session().SessionInfo().load("WindowPosY");
if (!val.empty())
posy = convert<int>(val);
}
// -*- C++ -*-
/**
* \file session.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Lars Gullik Bjønnes
* \author Bo Peng
*
* Full author contact details are available in file CREDITS.
*/
#ifndef SESSION_H
#define SESSION_H
#include <support/types.h>
#include <boost/utility.hpp>
#include <boost/tuple/tuple.hpp>
#include <string>
#include <deque>
#include <vector>
#include <map>
// used by at least frontends/qt2/QPref.C
const long maxlastfiles = 20;
/** This session file maintains
1. the latest documents loaded (lastfiles)
2. cursor positions of files closed (lastfilepos)
3. opened files when a lyx session is closed (lastopened)
4. bookmarks
5. general purpose session info in the form of key/value pairs
*/
namespace lyx {
class SessionSection : boost::noncopyable {
public:
/// read section from std::istream
virtual void read(std::istream & is) = 0;
/// write to std::ostream
virtual void write(std::ostream & os) const = 0;
};
class LastFilesSection : SessionSection
{
public:
///
typedef std::deque<std::string> LastFiles;
/** Insert #file# into the lastfile dequeue.
This funtion inserts #file# into the last files list. If the file
already exists it is moved to the top of the list, else exist it
is placed on the top of the list. If the list is full the last
file in the list is popped from the end.
@param file the file to insert in the lastfile list.
*/
void add(std::string const & file);
public:
///
explicit LastFilesSection(unsigned int num = 4);
///
void read(std::istream & is);
///
void write(std::ostream & os) const;
/// Return lastfiles container (deque)
LastFiles const lastFiles() const { return lastfiles; }
private:
/// Default number of lastfiles.
unsigned int const default_num_last_files;
/// Max number of lastfiles.
unsigned int const absolute_max_last_files;
/// a list of lastfiles
LastFiles lastfiles;
/// number of files in the lastfiles list.
unsigned int num_lastfiles;
/** Used by the constructor to set the number of stored last files.
@param num the number of lastfiles to set.
*/
void setNumberOfLastFiles(unsigned int num);
};
class LastOpenedSection : SessionSection
{
public:
///
typedef std::vector<std::string> LastOpened;
/** clear lastopened file list
*/
void clear();
/** add file to lastopened file list
@param file filename to add
*/
void add(std::string const & file);
/// Return lastopened container (vector)
LastOpened const lastOpenedFiles() const { return lastopened; }
///
void read(std::istream & is);
///
void write(std::ostream & os) const;
private:
/// a list of lastopened files
LastOpened lastopened;
};
class LastFilePosSection : SessionSection
{
public:
///
LastFilePosSection() : num_lastfilepos(100) {}
///
typedef boost::tuple<pit_type, pos_type> FilePos;
///
typedef std::map<std::string, FilePos> FilePosMap;
/** add cursor position to the fname entry in the filepos map
@param fname file entry for which to save position information
@param pos position of the cursor when the file is closed.
*/
void save(std::string const & fname, FilePos pos);
/** load saved cursor position from the fname entry in the filepos map
@param fname file entry for which to load position information
*/
FilePos load(std::string const & fname) const;
///
void read(std::istream & is);
///
void write(std::ostream & os) const;
private:
/// default number of lastfilepos to save */
unsigned int const num_lastfilepos;
/// a map of file positions
FilePosMap lastfilepos;
};
class BookmarksSection : SessionSection
{
public:
///
void read(std::istream & is);
///
void write(std::ostream & os) const;
/// ///
typedef boost::tuple<unsigned int, std::string, unsigned int, pos_type> Bookmark;
///
typedef std::vector<Bookmark> BookmarkList;
/** 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.
*/
BookmarkList & load() { return bookmarks; }
private:
/// a list of bookmarks
BookmarkList bookmarks;
};
class SessionInfoSection : SessionSection
{
public:
///
void read(std::istream & is);
///
void write(std::ostream & os) const;
///
typedef std::map<std::string, std::string> MiscInfo;
/** set session info
@param key key of the value to store
@param value value, a string without newline ('\n')
*/
void save(std::string const & key, std::string const & value);
/** load session info
@param key a key to extract value from the session file
@param release whether or not clear the value. Default to true
since most of such values are supposed to be used only once.
*/
std::string const load(std::string const & key, bool release = true);
private:
/// a map to save session info
MiscInfo sessioninfo;
};
class Session : boost::noncopyable {
public:
/** Read the session file.
@param num length of lastfiles
*/
explicit Session(unsigned int num = 4);
/** Write the session file.
*/
void writeFile() const;
///
LastFilesSection & LastFiles() { return last_files; }
///
LastFilesSection const & LastFiles() const { return last_files; }
///
LastOpenedSection & LastOpened() { return last_opened; }
///
LastOpenedSection const & LastOpened() const { return last_opened; }
///
LastFilePosSection & LastFilePos() { return last_file_pos; }
///
LastFilePosSection const & LastFilePos() const { return last_file_pos; }
///
BookmarksSection & Bookmarks() { return bookmarks; }
///
BookmarksSection const & Bookmarks() const { return bookmarks; }
///
SessionInfoSection & SessionInfo() { return session_info; }
///
SessionInfoSection const & SessionInfo() const { return session_info; }
private:
/// file to save session, determined in the constructor.
std::string session_file;
/** Read the session file.
Reads the #.lyx/session# at the beginning of the LyX session.
This will read the session file (usually #.lyx/session#).
@param file the file containing the session.
*/
void readFile();
///
LastFilesSection last_files;
///
LastOpenedSection last_opened;
///
LastFilePosSection last_file_pos;
///
BookmarksSection bookmarks;
///
SessionInfoSection session_info;
};
}
#endif
/**
* \file session.C
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Lars Gullik Bjønnes
* \author Bo Peng
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "session.h"
#include "debug.h"
#include "support/package.h"
#include "support/filetools.h"
#include <boost/filesystem/operations.hpp>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <iterator>
using lyx::support::addName;
using lyx::support::package;
namespace fs = boost::filesystem;
using std::vector;
using std::getline;
using std::string;
using std::ifstream;
using std::ofstream;
using std::istream;
using std::ostream;
using std::endl;
using std::istringstream;
using std::copy;
using std::find;
using std::ostream_iterator;
namespace {
string const sec_lastfiles = "[recent files]";
string const sec_lastfilepos = "[cursor positions]";
string const sec_lastopened = "[last opened files]";
string const sec_bookmarks = "[bookmarks]";
string const sec_session = "[session info]";
} // anon namespace
namespace lyx {
LastFilesSection::LastFilesSection(unsigned int num) :
default_num_last_files(4),
absolute_max_last_files(100)
{
setNumberOfLastFiles(num);
}
void LastFilesSection::setNumberOfLastFiles(unsigned int no)
{
if (0 < no && no <= absolute_max_last_files)
num_lastfiles = no;
else {
lyxerr << "LyX: session: too many last files\n"
<< "\tdefault (=" << default_num_last_files
<< ") used." << endl;
num_lastfiles = default_num_last_files;
}
}
void LastFilesSection::read(istream & is)
{
string tmp;
do {
char c = is.peek();
if (c == '[')
break;
getline(is, tmp);
// read lastfiles
if (!fs::exists(tmp) || lastfiles.size() >= num_lastfiles)
continue;
lastfiles.push_back(tmp);
} while (is.good());
}
void LastFilesSection::write(ostream & os) const
{
os << '\n' << sec_lastfiles << '\n';
copy(lastfiles.begin(), lastfiles.end(),
ostream_iterator<string>(os, "\n"));
}
void LastFilesSection::add(string const & file)
{
// If file already exist, delete it and reinsert at front.
LastFiles::iterator it = find(lastfiles.begin(), lastfiles.end(), file);
if (it != lastfiles.end())
lastfiles.erase(it);
lastfiles.push_front(file);
if (lastfiles.size() > num_lastfiles)
lastfiles.pop_back();
}
void LastOpenedSection::read(istream & is)
{
string tmp;
do {
char c = is.peek();
if (c == '[')
break;
getline(is, tmp);
if (!fs::exists(tmp))
continue;
lastopened.push_back(tmp);
} while (is.good());
}
void LastOpenedSection::write(ostream & os) const
{
os << '\n' << sec_lastopened << '\n';
copy(lastopened.begin(), lastopened.end(),
ostream_iterator<string>(os, "\n"));
}
void LastOpenedSection::clear()
{
lastopened.clear();
}
void LastOpenedSection::add(string const & file)
{
lastopened.push_back(file);
}
void LastFilePosSection::read(istream & is)
{
string tmp;
do {
char c = is.peek();
if (c == '[')
break;
getline(is, tmp);
// read lastfilepos
// pos, file\n
pit_type pit;
pos_type pos;
string fname;
istringstream itmp(tmp);
itmp >> pit;
itmp.ignore(2); // ignore ", "
itmp >> pos;
itmp.ignore(2); // ignore ", "
itmp >> fname;
if (!fs::exists(fname) || lastfilepos.size() >= num_lastfilepos)
continue;
lastfilepos[fname] = boost::tie(pit, pos);
} while (is.good());
}
void LastFilePosSection::write(ostream & os) const
{
os << '\n' << sec_lastfilepos << '\n';
for (FilePosMap::const_iterator file = lastfilepos.begin();
file != lastfilepos.end(); ++file) {
os << file->second.get<0>() << ", "
<< file->second.get<1>() << ", "
<< file->first << '\n';
}
}
void LastFilePosSection::save(string const & fname, FilePos pos)
{
lastfilepos[fname] = pos;
}
LastFilePosSection::FilePos LastFilePosSection::load(string const & fname) const
{
FilePosMap::const_iterator entry = lastfilepos.find(fname);
// Has position information, return it.
if (entry != lastfilepos.end())
return entry->second;
// Not found, return the first paragraph
else
return 0;
}
void BookmarksSection::read(istream & is)
{
string tmp;
do {
char c = is.peek();
if (c == '[')
break;
getline(is, tmp);
// read bookmarks
// bookmarkid, id, pos, file\n
unsigned int num;
unsigned int id;
pos_type pos;
string fname;
istringstream itmp(tmp);
itmp >> num;
itmp.ignore(2); // ignore ", "
itmp >> id;
itmp.ignore(2); // ignore ", "
itmp >> pos;
itmp.ignore(2); // ignore ", "
itmp >> fname;
// only load valid bookmarks
if (fs::exists(fname))
bookmarks.push_back(boost::tie(num, fname, id, pos));
} while (is.good());
}
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';
}
}
void BookmarksSection::save(Bookmark const & bookmark)
{
bookmarks.push_back(bookmark);
}
void SessionInfoSection::read(istream & is)
{
string tmp;
do {
char c = is.peek();
if (c == '[')
break;
getline(is, tmp);
// Read session info, saved as key/value pairs
// would better yell if pos returns npos
string::size_type pos = tmp.find_first_of(" = ");
string key = tmp.substr(0, pos);
string value = tmp.substr(pos + 3);
sessioninfo[key] = value;
} while (is.good());
}
void SessionInfoSection::write(ostream & os) const
{
os << '\n' << sec_session << '\n';
for (MiscInfo::const_iterator val = sessioninfo.begin();
val != sessioninfo.end(); ++val) {
os << val->first << " = " << val->second << '\n';
}
}
void SessionInfoSection::save(string const & key, string const & value)
{
sessioninfo[key] = value;
}
string const SessionInfoSection::load(string const & key, bool release)
{
MiscInfo::const_iterator pos = sessioninfo.find(key);
string value;
if (pos != sessioninfo.end())
value = pos->second;
if (release)
sessioninfo.erase(key);
return value;
}
Session::Session(unsigned int num) :
last_files(num)
{
// locate the session file
// note that the session file name 'session' is hard-coded
session_file = addName(package().user_support(), "session");
//
readFile();
}
void Session::readFile()
{
// we will not complain if we can't find session_file nor will
// we issue a warning. (Lgb)
ifstream is(session_file.c_str());
string tmp;
while (getline(is, tmp)) {
// Ignore comments, empty line or line stats with ' '
if (tmp == "" || tmp[0] == '#' || tmp[0] == ' ')
continue;
// Determine section id
if (tmp == sec_lastfiles)
LastFiles().read(is);
else if (tmp == sec_lastopened)
LastOpened().read(is);
else if (tmp == sec_lastfilepos)
LastFilePos().read(is);
else if (tmp == sec_bookmarks)
Bookmarks().read(is);
else if (tmp == sec_session)
SessionInfo().read(is);
else
lyxerr << "LyX: Warning: unknown Session section: " << tmp << endl;
}
}
void Session::writeFile() const
{
ofstream os(session_file.c_str());
if (os) {
os << "## Automatically generated lyx session file \n"
<< "## Editing this file manually may cause lyx to crash.\n";
LastFiles().write(os);
LastOpened().write(os);
LastFilePos().write(os);
Bookmarks().write(os);
SessionInfo().write(os);
} else
lyxerr << "LyX: Warning: unable to save Session: "
<< session_file << endl;
}
}