]> git.lyx.org Git - features.git/commitdiff
2006-04-06 Bo Peng <ben.bob@gmail.com>
authorLars Gullik Bjønnes <larsbj@gullik.org>
Wed, 5 Apr 2006 22:56:18 +0000 (22:56 +0000)
committerLars Gullik Bjønnes <larsbj@gullik.org>
Wed, 5 Apr 2006 22:56:18 +0000 (22:56 +0000)
  session support that
    * handle recent opened files (previously lastfile)
    * save/load bookmarks when quit lyx
    * save/load buffer cursor location whan a file is closed
    * save/load windows position and size when a file is closed
    * add rc entries load_session, use_lastfilepos,
      screen_geometry_height, screen_geometry_width,
      screen_geometry_xysaved.
    * trigger LFUN_QUIT when Alt-F4 or close-button is used to close lyx.
    * remove lastfile.h lastfile.C (merged in session.h, session.C)

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13561 a592a061-630c-0410-9148-cb99ea01b6c8

29 files changed:
src/BufferView.C
src/BufferView.h
src/BufferView_pimpl.C
src/BufferView_pimpl.h
src/Makefile.am
src/MenuBackend.C
src/bufferlist.C
src/frontends/gtk/GView.C
src/frontends/qt2/QPrefs.C
src/frontends/qt2/QtView.C
src/frontends/qt2/lyx_gui.C
src/frontends/qt4/QPrefs.C
src/frontends/qt4/QPrefsDialog.C
src/frontends/qt4/QtView.C
src/frontends/qt4/lyx_gui.C
src/frontends/xforms/FormPreferences.C
src/frontends/xforms/XFormsView.C
src/frontends/xforms/XFormsView.h
src/frontends/xforms/lyx_gui.C
src/lastfiles.C [deleted file]
src/lastfiles.h [deleted file]
src/lyx_cb.C
src/lyx_main.C
src/lyx_main.h
src/lyxfunc.C
src/lyxrc.C
src/lyxrc.h
src/session.C [new file with mode: 0644]
src/session.h [new file with mode: 0644]

index d5160a74205274b997ceecacc2882329254a6197..aa4ff6fcb3713e5fd86192cb0ba858f94dd45de1 100644 (file)
@@ -188,6 +188,10 @@ bool BufferView::isSavedPosition(unsigned int i)
        return pimpl_->isSavedPosition(i);
 }
 
+void BufferView::saveSavedPositions()
+{
+       return pimpl_->saveSavedPositions();
+}
 
 void BufferView::switchKeyMap()
 {
index 2940d7758660adc54e47d477dbf2a9811a6951a8..95910a97f146282ac627093a9ffa80434821c1a3 100644 (file)
@@ -120,6 +120,8 @@ public:
        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();
 
        /// return the current change at the cursor
        Change const getCurrentChange();
index d75f1730bb6b427acb5c5393499f46a8b895af30..061f9385a971d5c9a4fd6d660eeabb9621c68638 100644 (file)
@@ -42,7 +42,7 @@
 #include "lyxfunc.h"
 #include "lyxtext.h"
 #include "lyxrc.h"
-#include "lastfiles.h"
+#include "session.h"
 #include "metricsinfo.h"
 #include "paragraph.h"
 #include "paragraph_funcs.h"
@@ -170,6 +170,14 @@ BufferView::Pimpl::Pimpl(BufferView & bv, LyXView * owner,
                .connect(boost::bind(&BufferView::Pimpl::cursorToggle, this));
        cursor_timeout.start();
        saved_positions.resize(saved_positions_num);
+       // load saved bookmarks
+       lyx::Session::BookmarkList & bmList = LyX::ref().session().loadBookmarks();
+       for (lyx::Session::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();
 }
 
 
@@ -294,9 +302,31 @@ bool BufferView::Pimpl::loadLyXFile(string const & filename, bool tolastfiles)
 
        setBuffer(b);
        bv_->showErrorList(_("Parse"));
+    
+       // scroll to the position when the file was last closed
+       if (lyxrc.use_lastfilepos) {
+               lyx::pit_type pit;
+               lyx::pos_type pos;
+               boost::tie(pit, pos) = LyX::ref().session().loadFilePosition(s);
+               // I am not sure how to separate the following part to a function
+               // so I will leave this to Lars. 
+               //
+               // check pit since the document may be externally changed.
+               if ( static_cast<size_t>(pit) < b->paragraphs().size() ) {
+                       ParIterator it = b->par_iterator_begin();
+                       ParIterator const end = b->par_iterator_end();
+                       for (; it != end; ++it)
+                               if (it.pit() == pit) {
+                                       // restored pos may be bigger than it->size
+                                       bv_->setCursor(makeDocIterator(it, min(pos, it->size())));
+                                       bv_->update(Update::FitCursor);
+                                       break;
+                               }       
+               }
+       }
 
        if (tolastfiles)
-               LyX::ref().lastfiles().newFile(b->fileName());
+               LyX::ref().session().addLastFile(b->fileName());
 
        return true;
 }
@@ -332,6 +362,9 @@ void BufferView::Pimpl::setBuffer(Buffer * b)
                // to this buffer later on.
                buffer_->saveCursor(cursor_.selectionBegin(),
                                    cursor_.selectionEnd());
+               // current buffer is going to be switched-off, save cursor pos
+               LyX::ref().session().saveFilePosition(buffer_->fileName(),
+                       boost::tie(cursor_.pit(), cursor_.pos()) );
        }
 
        // If we are closing current buffer, switch to the first in
@@ -812,6 +845,22 @@ bool BufferView::Pimpl::isSavedPosition(unsigned int i)
 }
 
 
+void BufferView::Pimpl::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().saveBookmark( boost::tie(
+                               i, 
+                               saved_positions[i].filename,
+                               saved_positions[i].par_id,
+                               saved_positions[i].par_pos) );
+       }
+}
+
+
 void BufferView::Pimpl::switchKeyMap()
 {
        if (!lyxrc.rtl_support)
index c6ac78f6f7af61561e1dd911ede071772871df26..8c4393516fdd7f6494258b0d2e69a5c1a12c06b2 100644 (file)
@@ -95,6 +95,8 @@ public:
        void restorePosition(unsigned int i);
        ///
        bool isSavedPosition(unsigned int i);
+       /// save bookmarks to .lyx/session
+       void saveSavedPositions();
        ///
        void switchKeyMap();
        ///
index 58afae30631880a6ff09924ba865440888d2c36d..4ed39157ff4564d24181fa7b0cd9fcbc80fa3155 100644 (file)
@@ -190,8 +190,8 @@ lyx_SOURCES = \
        kbsequence.h \
        language.C \
        language.h \
-       lastfiles.C \
-       lastfiles.h \
+       session.C \
+       session.h \
        layout.h \
        lengthcommon.C \
        lengthcommon.h \
index 44789444a7a4f86d2d8a0207afad0e88bd8e62da..58e4b266834229e28e321cae0af8bfdb4619d477 100644 (file)
@@ -30,7 +30,7 @@
 #include "gettext.h"
 #include "importer.h"
 #include "kbmap.h"
-#include "lastfiles.h"
+#include "session.h"
 #include "LyXAction.h"
 #include "lyx_main.h" // for lastfiles
 #include "lyxfunc.h"
@@ -428,13 +428,12 @@ string const limit_string_length(string const & str)
 
 void expandLastfiles(Menu & tomenu, LyXView const * view)
 {
-       LastFiles const & lastfiles = LyX::cref().lastfiles();
+       lyx::Session::LastFiles const & lf = LyX::cref().session().lastFiles();
+       lyx::Session::LastFiles::const_iterator lfit = lf.begin();
 
        int ii = 1;
-       LastFiles::const_iterator lfit = lastfiles.begin();
-       LastFiles::const_iterator end = lastfiles.end();
 
-       for (; lfit != end && ii < 10; ++lfit, ++ii) {
+       for (; lfit != lf.end() && ii < 10; ++lfit, ++ii) {
                string const label = convert<string>(ii) + ". "
                        + MakeDisplayPath((*lfit), 30)
                        + '|' + convert<string>(ii);
index da708c72e184ed0c90b9cb02004141c4644b5c24..a4d2d6a0fd5512402cc7c93831bb9ea75a4bbb88 100644 (file)
@@ -17,7 +17,7 @@
 #include "bufferparams.h"
 #include "debug.h"
 #include "gettext.h"
-#include "lastfiles.h"
+#include "session.h"
 #include "lyx_cb.h"
 #include "lyx_main.h"
 #include "output_latex.h"
@@ -187,7 +187,7 @@ bool BufferList::close(Buffer * buf, bool const ask)
                        if (!WriteAs(buf))
                                return false;
                } else if (buf->save()) {
-                       LyX::ref().lastfiles().newFile(buf->fileName());
+                       LyX::ref().session().addLastFile(buf->fileName());
                } else {
                        return false;
                }
index 6889516db33fa77ae5c38fc1d91e697b1db332a9..8d41e47b40ba21e8010cfab36026e8ad2e00dc78 100644 (file)
 
 #include "BufferView.h"
 #include "lyx_cb.h"
+#include "lyxrc.h"
+#include "lyx_main.h"
+#include "session.h"
 #include "lyxfunc.h"
 #include "MenuBackend.h"
+#include "funcrequest.h"
 
 #include "frontends/Toolbars.h"
 
 #include "support/filetools.h"
+#include "support/convert.h"
 
 #include <boost/bind.hpp>
 
@@ -95,7 +100,24 @@ GView::GView()
                boost::bind(&GMiniBuffer::editMode, minibuffer_.get()));
        view_state_changed.connect(boost::bind(&GView::showViewState, this));
        signal_focus_in_event().connect(sigc::mem_fun(*this, &GView::onFocusIn));
-       set_default_size(750, 550);
+       // 
+       int width = 750;
+       int height = 550;
+       // first try lyxrc
+       if (lyxrc.geometry_width != 0 && lyxrc.geometry_height != 0 ) {
+               width = lyxrc.geometry_width;
+               height = lyxrc.geometry_height;
+       }
+       // if lyxrc returns (0,0), then use session info
+       else {
+               string val = LyX::ref().session().loadSessionInfo("WindowWidth");
+               if (val != "")
+                       width = convert<unsigned int>(val);
+               val = LyX::ref().session().loadSessionInfo("WindowHeight");
+               if (val != "")
+                       height = convert<unsigned int>(val);
+       }       
+       set_default_size(width, height);
        // Make sure the buttons are disabled if needed.
        updateToolbars();
        string const iconName =
@@ -117,7 +139,14 @@ Gtk::Box & GView::getBox(Position pos)
 
 bool GView::on_delete_event(GdkEventAny * /*event*/)
 {
-       QuitLyX(false);
+       // save windows size and position
+       Gtk::Requisition req = workArea_->size_request();
+       LyX::ref().session().saveSessionInfo("WindowWidth", convert<string>(req.width));
+       LyX::ref().session().saveSessionInfo("WindowHeight", convert<string>(req.height));
+       // trigger LFUN_QUIT instead of quit directly
+       // since LFUN_QUIT may have more cleanup stuff
+       //
+       getLyXFunc().dispatch(FuncRequest(LFUN_QUIT));
        return true;
 }
 
index e6f97c8a8574acce9f0d18d47541716d41dedd1c..8bdb6d08792a6eb680a3a054a3beec795c631fcb 100644 (file)
@@ -35,7 +35,7 @@
 #include "ui/QPrefIdentityModule.h"
 
 #include "debug.h"
-#include "lastfiles.h"
+#include "session.h"
 #include "LColor.h"
 #include "lyxfont.h"
 
index 7f7e98c490fa7474f6fcc2c70492cca5f0f27d25..b83a767e4bfea13f255910e5572a233d61723215 100644 (file)
 
 #include "BufferView.h"
 #include "lyx_cb.h"
+#include "lyxrc.h"
+#include "lyx_main.h"
+#include "session.h"
 #include "lyxfunc.h"
 #include "MenuBackend.h"
+#include "funcrequest.h"
 
 #include "frontends/Toolbars.h"
 
 #include "support/filetools.h"
+#include "support/convert.h"
 
 #include <boost/bind.hpp>
 
@@ -155,7 +160,16 @@ bool QtView::hasFocus() const
 
 void QtView::closeEvent(QCloseEvent *)
 {
-       QuitLyX(false);
+       // save windows size and position
+       LyX::ref().session().saveSessionInfo("WindowWidth", convert<string>(width()));
+       LyX::ref().session().saveSessionInfo("WindowHeight", convert<string>(height()));
+       if (lyxrc.geometry_xysaved) {
+               LyX::ref().session().saveSessionInfo("WindowPosX", convert<string>(x()));
+               LyX::ref().session().saveSessionInfo("WindowPosY", convert<string>(y()));
+       }
+       // trigger LFUN_QUIT instead of quit directly
+       // since LFUN_QUIT may have more cleanup stuff
+       getLyXFunc().dispatch(FuncRequest(LFUN_QUIT));
 }
 
 
index 360c8be66611e72a670a16bb3312c6284a7fb811..e676c4a2fe96f20e56ce2d61b225e7e8a2f4f578 100644 (file)
 #include "lyxrc.h"
 #include "lyxserver.h"
 #include "lyxsocket.h"
+#include "session.h"
 
 #include "graphics/LoaderQueue.h"
 
 #include "support/lstrings.h"
+#include "support/convert.h"
 #include "support/os.h"
 #include "support/package.h"
 #include "debug.h"
@@ -224,11 +226,37 @@ void start(string const & batch, vector<string> const & files)
        // initial geometry
        unsigned int width = 690;
        unsigned int height = 510;
+       // first try lyxrc
+       if (lyxrc.geometry_width != 0 && lyxrc.geometry_height != 0 ) {
+               width = lyxrc.geometry_width;
+               height = lyxrc.geometry_height;
+       }
+       // if lyxrc returns (0,0), then use session info
+       else {
+               string val = LyX::ref().session().loadSessionInfo("WindowWidth");
+               if (val != "")
+                       width = convert<unsigned int>(val);
+               val = LyX::ref().session().loadSessionInfo("WindowHeight");
+               if (val != "")
+                       height = convert<unsigned int>(val);
+       }       
 
        boost::shared_ptr<QtView> view_ptr(new QtView(width, height));
        LyX::ref().addLyXView(view_ptr);
 
        QtView & view = *view_ptr.get();
+       
+       // if user wants to restore window position
+       if (lyxrc.geometry_xysaved) {
+               QPoint p = view.pos();
+               string val = LyX::ref().session().loadSessionInfo("WindowPosX");
+               if (val != "")
+                       p.setX(convert<unsigned int>(val));
+               val = LyX::ref().session().loadSessionInfo("WindowPosY");
+               if (val != "")
+                       p.setY(convert<unsigned int>(val));
+               view.move(p);
+       }       
        view.show();
        view.init();
 
index 5499c3c1c388a11c9081d07d4e1fbac3bc7b601a..5389b4ca027f9e4f501c8146717e9fd6a4163a56 100644 (file)
@@ -18,7 +18,6 @@
 #include "qt_helpers.h"
 
 #include "debug.h"
-#include "lastfiles.h"
 #include "LColor.h"
 #include "lyxfont.h"
 
index 6b7bfd01c1dd838504f292a843d8f7a0c418ebad..c7ef7a4b9aa96785f4f8da4c5ef4d2a595f1a3b5 100644 (file)
@@ -18,7 +18,7 @@
 #include "qt_helpers.h"
 
 #include "debug.h"
-#include "lastfiles.h"
+#include "session.h"
 #include "LColor.h"
 #include "lyxfont.h"
 
index ed8c628ec515e0a59218cfce872f0bef83de0981..def0043f138a01936a555d602de3f83b9906d871 100644 (file)
 
 #include "BufferView.h"
 #include "lyx_cb.h"
+#include "lyx_rc.h"
+#include "lyx_main.h"
+#include "session.h"
 #include "lyxfunc.h"
 #include "MenuBackend.h"
+#include "funcrequest.h"
+#include "funcrequest.h"
 
 #include "debug.h"
 
@@ -23,6 +28,7 @@
 
 #include "support/filetools.h"
 
+#include "support/convert.h"
 #include <boost/bind.hpp>
 
 #include "QtView.h"
@@ -173,7 +179,16 @@ bool QtView::hasFocus() const
 
 void QtView::closeEvent(QCloseEvent *)
 {
-       QuitLyX(false);
+       // save windows size and position
+       LyX::ref().session().saveSessionInfo("WindowWidth", convert<string>(width()));
+       LyX::ref().session().saveSessionInfo("WindowHeight", convert<string>(height()));
+       if (lyxrc.geometry_xysaved) {
+               LyX::ref().session().saveSessionInfo("WindowPosX", convert<string>(x()));
+               LyX::ref().session().saveSessionInfo("WindowPosY", convert<string>(y()));
+       }
+       // trigger LFUN_QUIT instead of quit directly
+       // since LFUN_QUIT may have more cleanup stuff
+       getLyXFunc().dispatch(FuncRequest(LFUN_QUIT));
 }
 
 
index 60084c5ffc0a9a617a4580366b3f81148c878321..c100257415c09db696090e203ce2aafb539280fc 100644 (file)
@@ -218,11 +218,37 @@ void start(string const & batch, vector<string> const & files)
        // initial geometry
        unsigned int width = 690;
        unsigned int height = 510;
+       // first try lyxrc
+       if (lyxrc.geometry_width != 0 && lyxrc.geometry_height != 0 ) {
+               width = lyxrc.geometry_width;
+               height = lyxrc.geometry_height;
+       }
+       // if lyxrc returns (0,0), then use session info
+       else {
+               string val = LyX::ref().session().loadSessionInfo("WindowWidth");
+               if (val != "")
+                       width = convert<unsigned int>(val);
+               val = LyX::ref().session().loadSessionInfo("WindowHeight");
+               if (val != "")
+                       height = convert<unsigned int>(val);
+       }       
 
        boost::shared_ptr<QtView> view_ptr(new QtView(width, height));
        LyX::ref().addLyXView(view_ptr);
 
        QtView & view = *view_ptr.get();
+       
+       // if user wants to restore window position
+       if (lyxrc.geometry_xysaved) {
+               QPoint p = view.pos();
+               string val = LyX::ref().session().loadSessionInfo("WindowPosX");
+               if (val != "")
+                       p.setX(convert<unsigned int>(val));
+               val = LyX::ref().session().loadSessionInfo("WindowPosY");
+               if (val != "")
+                       p.setY(convert<unsigned int>(val));
+               view.move(p);
+       }       
        view.show();
        view.init();
 
index 04f78aef1acad0b39862379ad1cc0f33fdf68ddf..715f0cc109df255d7c6f13be40bc7b915345852b 100644 (file)
@@ -24,7 +24,7 @@
 #include "controllers/helper_funcs.h" // getSecond
 
 #include "buffer.h"
-#include "lastfiles.h"
+#include "session.h"
 #include "LColor.h"
 #include "lyxfont.h"
 #include "frontends/lyx_gui.h"
@@ -2203,7 +2203,6 @@ void FormPreferences::Paths::apply(LyXRC & rc)
        if (!button) str.erase();
 
        rc.check_lastfiles = button;
-       rc.lastfiles = str;
        rc.num_lastfiles = static_cast<unsigned int>
                (fl_get_counter_value(dialog_->counter_lastfiles));
 
@@ -2261,8 +2260,6 @@ FormPreferences::Paths::feedback(FL_OBJECT const * const ob) const
                return LyXRC::getDescription(LyXRC::RC_TEMPDIRPATH);
        if (ob == dialog_->check_last_files)
                return LyXRC::getDescription(LyXRC::RC_CHECKLASTFILES);
-       if (ob == dialog_->input_lastfiles)
-               return LyXRC::getDescription(LyXRC::RC_LASTFILES);
        if (ob == dialog_->counter_lastfiles)
                return LyXRC::getDescription(LyXRC::RC_NUMLASTFILES);
        if (ob == dialog_->check_make_backups)
@@ -2410,13 +2407,8 @@ void FormPreferences::Paths::update(LyXRC const & rc)
        fl_set_input(dialog_->input_temp_dir, rc.tempdir_path.c_str());
        fl_set_input(dialog_->input_path_prefix, rc.path_prefix.c_str());
 
-       str.erase();
-       if (rc.check_lastfiles)
-               str = rc.lastfiles;
-
        fl_set_button(dialog_->check_last_files,
                      rc.check_lastfiles);
-       fl_set_input(dialog_->input_lastfiles, str.c_str());
        fl_set_counter_value(dialog_->counter_lastfiles,
                             rc.num_lastfiles);
 
index 43f70585160299f3bcb46b7cb02ea6d97b1d74e2..0206a6907b8eccf0e15a01e42770230423ca0cf9 100644 (file)
 
 #include "BufferView.h"
 #include "debug.h"
+#include "lyx_main.h"
+#include "session.h"
 #include "lyxfunc.h"
 #include "MenuBackend.h"
+#include "funcrequest.h"
 
 #include "frontends/Dialogs.h"
 #include "frontends/Toolbars.h"
 
 #include "support/filetools.h"        // OnlyFilename()
+#include "support/convert.h"
 
 #include <boost/bind.hpp>
 
@@ -45,9 +49,13 @@ namespace frontend {
 extern "C" {
 
 static
-int C_XFormsView_atCloseMainFormCB(FL_FORM * form, void * p)
+int C_XFormsView_atCloseMainFormCB(FL_FORM * /*form*/, void * arg)
 {
-       return XFormsView::atCloseMainFormCB(form, p);
+       // For some reason u_vdata does not contain the pointer
+       // to the XFormsView that we need. We get it through arg instead.
+       //XFormsView * view = static_cast<XFormsView*>(form->u_vdata);
+       XFormsView * view = static_cast<XFormsView*>(arg);
+       return view->atCloseMainFormCB();
 }
 
 }
@@ -93,7 +101,7 @@ XFormsView::XFormsView(int width, int height)
        // dimensions.
        form_ = fl_bgn_form(FL_NO_BOX, width, height);
        form_->u_vdata = this;
-       fl_set_form_atclose(form_, C_XFormsView_atCloseMainFormCB, 0);
+       fl_set_form_atclose(form_, C_XFormsView_atCloseMainFormCB, this);
 
        FL_OBJECT * obj = fl_add_box(FL_FLAT_BOX, 0, 0, width, height, "");
        fl_set_object_color(obj, FL_MCOL, FL_MCOL);
@@ -171,9 +179,15 @@ FL_FORM * XFormsView::getForm() const
 
 
 // Callback for close main form from window manager
-int XFormsView::atCloseMainFormCB(FL_FORM *, void *)
+int XFormsView::atCloseMainFormCB()
 {
-       QuitLyX(false);
+       // save windows size
+       LyX::ref().session().saveSessionInfo("WindowWidth", convert<string>(form_->w));
+       LyX::ref().session().saveSessionInfo("WindowHeight", convert<string>(form_->h));
+       // trigger LFUN_QUIT instead of quit directly
+       // since LFUN_QUIT may have more cleanup stuff
+       //
+       getLyXFunc().dispatch(FuncRequest(LFUN_QUIT));
        return FL_IGNORE;
 }
 
index 7f77b76937042aac6a1c4fe2df225767b85fed14..45e58ff870d738c9bfbc83f22508aeaa5068b01d 100644 (file)
@@ -66,7 +66,7 @@ public:
        virtual void busy(bool) const;
 
        /// callback for close event from window manager
-       static int atCloseMainFormCB(FL_FORM *, void *);
+       int atCloseMainFormCB();
 
        /// display a status message
        virtual void message(std::string const & str);
index bf562beded0aa6273111460cf8a5dca106f5dcfe..809e834693f16bba867e4288b3bf2681b5df0b50 100644 (file)
@@ -28,6 +28,7 @@
 #include "LyXAction.h"
 #include "lyxfunc.h"
 #include "lyxrc.h"
+#include "session.h"
 #include "lyxserver.h"
 #include "lyxsocket.h"
 
@@ -37,6 +38,7 @@
 #include "support/lyxlib.h"
 #include "support/os.h"
 #include "support/package.h"
+#include "support/convert.h"
 
 #include "lyx_forms.h"
 
@@ -259,6 +261,20 @@ void start(string const & batch, vector<string> const & files)
        int ypos = -1;
        unsigned int width = 690;
        unsigned int height = 510;
+       // first try lyxrc
+       if (lyxrc.geometry_width != 0 && lyxrc.geometry_height != 0 ) {
+               width = lyxrc.geometry_width;
+               height = lyxrc.geometry_height;
+       }
+       // if lyxrc returns (0,0), then use session info
+       else {
+               string val = LyX::ref().session().loadSessionInfo("WindowWidth");
+               if (val != "")
+                       width = convert<unsigned int>(val);
+               val = LyX::ref().session().loadSessionInfo("WindowHeight");
+               if (val != "")
+                       height = convert<unsigned int>(val);
+       }
 
        int const geometryBitmask =
                XParseGeometry(geometry,
diff --git a/src/lastfiles.C b/src/lastfiles.C
deleted file mode 100644 (file)
index 537d611..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * \file lastfiles.C
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author Lars Gullik Bjønnes
- *
- * Full author contact details are available in file CREDITS.
- */
-
-#include <config.h>
-
-#include "lastfiles.h"
-#include "debug.h"
-
-#include <boost/filesystem/operations.hpp>
-
-#include <algorithm>
-#include <fstream>
-#include <iterator>
-
-namespace fs = boost::filesystem;
-
-using std::copy;
-using std::endl;
-using std::find;
-using std::getline;
-using std::string;
-using std::ifstream;
-using std::ofstream;
-using std::ostream_iterator;
-
-
-LastFiles::LastFiles(string const & filename, bool st, unsigned int num)
-       : dostat(st)
-{
-       setNumberOfFiles(num);
-       readFile(filename);
-}
-
-
-void LastFiles::setNumberOfFiles(unsigned int no)
-{
-       if (0 < no && no <= ABSOLUTEMAXLASTFILES)
-               num_files = no;
-       else {
-               lyxerr << "LyX: lastfiles: too many files\n"
-                       "\tdefault (=" << int(DEFAULTFILES)
-                      << ") used." << endl;
-               num_files = DEFAULTFILES;
-       }
-}
-
-
-void LastFiles::readFile(string const & filename)
-{
-       // we will not complain if we can't find filename nor will
-       // we issue a warning. (Lgb)
-       ifstream ifs(filename.c_str());
-       string tmp;
-
-       while (getline(ifs, tmp) && files.size() < num_files) {
-               if (dostat && !fs::exists(tmp))
-                               continue;
-               files.push_back(tmp);
-       }
-}
-
-
-void LastFiles::writeFile(string const & filename) const
-{
-       ofstream ofs(filename.c_str());
-       if (ofs) {
-               copy(files.begin(), files.end(),
-                    ostream_iterator<string>(ofs, "\n"));
-       } else
-               lyxerr << "LyX: Warning: unable to save LastFiles: "
-                      << filename << endl;
-}
-
-
-void LastFiles::newFile(string const & file)
-{
-       // If file already exist, delete it and reinsert at front.
-       Files::iterator it = find(files.begin(), files.end(), file);
-       if (it != files.end())
-               files.erase(it);
-       files.push_front(file);
-       if (files.size() > num_files)
-               files.pop_back();
-}
-
-
-string const LastFiles::operator[](unsigned int i) const
-{
-       if (i < files.size())
-               return files[i];
-       return string();
-}
diff --git a/src/lastfiles.h b/src/lastfiles.h
deleted file mode 100644 (file)
index efe657e..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-// -*- C++ -*-
-/**
- * \file lastfiles.h
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author Lars Gullik Bjønnes
- *
- * Full author contact details are available in file CREDITS.
- */
-
-#ifndef LASTFILES_H
-#define LASTFILES_H
-
-#include <boost/utility.hpp>
-
-#include <deque>
-#include <string>
-
-const long maxlastfiles = 20;
-
-/** The latest documents loaded.
- *  This class takes care of the last .lyx files used by the LyX user. It
- *  both reads and writes this information to a file. The number of files
- *  kept are user defined, but defaults to four.
- */
-class LastFiles : boost::noncopyable {
-public:
-       ///
-       typedef std::deque<std::string> Files;
-
-       ///
-       typedef Files::const_iterator const_iterator;
-
-       /** Read the lastfiles file.
-           @param file The file to read the lastfiles form.
-           @param dostat Whether to check for file existance.
-           @param num number of files to remember.
-       */
-       explicit
-       LastFiles(std::string const & file,
-                 bool dostat = true, unsigned int num = 4);
-
-       /** Insert #file# into the list.
-           This funtion inserts #file# into the last files list. If the file
-           already exist 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 list.
-       */
-       void newFile(std::string const & file);
-       /** Writes the lastfiles table to disk.
-           Writes one file on each line, this way we can at least have
-           some special chars (e.g. space), but newline in filenames
-           are thus not allowed.
-           @param file the file we write the lastfiles list to.
-       */
-       void writeFile(std::string const & file) const;
-       /** Return file #n# in the lastfiles list.
-           @param n number in the list to get
-       */
-       std::string const operator[](unsigned int n) const;
-       /// Iterator to the beginning of the list.
-       Files::const_iterator begin() const { return files.begin(); }
-       /// Iterator to the end of the list.
-       Files::const_iterator end() const { return files.end(); }
-private:
-       /** Local constants.
-           It is more portable among different C++ compilers to use
-           an enum instead of #int const XXX#
-       */
-       enum local_constants {
-               /// Default number of lastfiles.
-               DEFAULTFILES = 4,
-               /** Max number of lastfiles.
-                   There is no point in keeping more than this number
-                   of files at the same time. However perhaps someday
-                   someone finds use for more files and wants to
-                   change it. Please do. But don't show the files in
-                   a menu...
-               */
-               ABSOLUTEMAXLASTFILES = 20
-       };
-
-       /// a list of lastfiles
-       Files files;
-       /// number of files in the lastfiles list.
-       unsigned int num_files;
-       /// check for file existance or not.
-       bool dostat;
-
-       /** Read the lastfiles file.
-           Reads the #.lyx_lastfiles# at the beginning of the LyX session.
-           This will read the lastfiles file (usually #.lyx_lastfiles#). It
-           will normally discard files that don't exist anymore, unless
-           LastFiles has been initialized with #dostat = false#.
-           @param file the file containing the lastfiles.
-       */
-       void readFile(std::string const & file);
-       /** Used by the constructor to set the number of stored last files.
-           @param num the number of lastfiles to set.
-       */
-       void setNumberOfFiles(unsigned int num);
-};
-#endif
index d69871edb723e2e0f879707fff0a3d05df4aba03..5445ef21c9a8307ede7c9756bcf2600041591dbe 100644 (file)
@@ -22,7 +22,7 @@
 #include "cursor.h"
 #include "debug.h"
 #include "gettext.h"
-#include "lastfiles.h"
+#include "session.h"
 #include "LaTeXFeatures.h"
 #include "lyx_main.h"
 #include "lyxlayout.h"
@@ -101,7 +101,7 @@ bool quitting;      // flag, that we are quitting the program
 bool MenuWrite(Buffer * buffer)
 {
        if (buffer->save()) {
-               LyX::ref().lastfiles().newFile(buffer->fileName());
+               LyX::ref().session().addLastFile(buffer->fileName());
                return true;
        }
 
@@ -196,7 +196,7 @@ void QuitLyX(bool noask)
                if (!noask && !bufferlist.quitWriteAll())
                        return;
 
-               LyX::cref().lastfiles().writeFile(lyxrc.lastfiles);
+               LyX::cref().session().writeFile();
        }
 
        // Set a flag that we do quitting from the program,
index b7f54fdb742f309faf0185ed1e56d60dd6cd9b8d..a7fc41b27778eb49a00bee211a846607a89e110e 100644 (file)
@@ -28,7 +28,7 @@
 #include "gettext.h"
 #include "kbmap.h"
 #include "language.h"
-#include "lastfiles.h"
+#include "session.h"
 #include "LColor.h"
 #include "lyxfunc.h"
 #include "lyxlex.h"
@@ -163,17 +163,17 @@ LyX::LyX()
 {}
 
 
-LastFiles & LyX::lastfiles()
+lyx::Session & LyX::session()
 {
-       BOOST_ASSERT(lastfiles_.get());
-       return *lastfiles_.get();
+       BOOST_ASSERT(session_.get());
+       return *session_.get();
 }
 
 
-LastFiles const & LyX::lastfiles() const
+lyx::Session const & LyX::session() const
 {
-       BOOST_ASSERT(lastfiles_.get());
-       return *lastfiles_.get();
+       BOOST_ASSERT(session_.get());
+       return *session_.get();
 }
 
 
@@ -238,6 +238,14 @@ void LyX::priv_exec(int & argc, char * argv[])
        if (first_start)
                files.push_back(i18nLibFileSearch("examples", "splash.lyx"));
 
+       // if a file is specified, I assume that user wants to edit *that* file
+       if (files.empty() && lyxrc.load_session) {
+               vector<string> const & lastopened = session_->lastOpenedFiles();
+               files.insert(files.end(), lastopened.begin(), lastopened.end()  );
+               // clear this list to save a few bytes of RAM
+               session_->clearLastOpenedFiles();
+       }
+       
        // Execute batch commands if available
        if (!batch_command.empty()) {
 
@@ -425,10 +433,6 @@ void LyX::init(bool gui)
                                              "templates");
        }
 
-       if (lyxrc.lastfiles.empty()) {
-               lyxrc.lastfiles = AddName(package().user_support(), "lastfiles");
-       }
-
        if (lyxrc.roman_font_name.empty())
                lyxrc.roman_font_name = lyx_gui::roman_font_name();
        if (lyxrc.sans_font_name.empty())
@@ -513,11 +517,8 @@ void LyX::init(bool gui)
                lyxerr << "LyX tmp dir: `" << package().temp_dir() << '\'' << endl;
        }
 
-       lyxerr[Debug::INIT] << "Reading lastfiles `"
-                           << lyxrc.lastfiles << "'..." << endl;
-       lastfiles_.reset(new LastFiles(lyxrc.lastfiles,
-                                      lyxrc.check_lastfiles,
-                                      lyxrc.num_lastfiles));
+       lyxerr[Debug::INIT] << "Reading session information '.lyx/session'..." << endl;
+       session_.reset(new lyx::Session(lyxrc.num_lastfiles));
 }
 
 
index a196e8909aec48bb56d916ac4a3fe5baf6973777..426a7810ee6e7355ac45623154ab0ef4a627cca2 100644 (file)
 class Buffer;
 class ErrorItem;
 class InsetBase;
-class LastFiles;
 class LyXView;
 class kb_keymap;
+namespace lyx {
+       class Session;
+}
 
 
 /// initial startup
@@ -39,8 +41,8 @@ public:
        /// in the case of failure
        void emergencyCleanup() const;
 
-       LastFiles & lastfiles();
-       LastFiles const & lastfiles() const;
+       lyx::Session & session();
+       lyx::Session const & session() const;
 
        void addLyXView(boost::shared_ptr<LyXView> const & lyxview);
 
@@ -86,8 +88,8 @@ private:
        /// the parsed command line batch command if any
        std::string batch_command;
 
-       /// last files loaded
-       boost::scoped_ptr<LastFiles> lastfiles_;
+       /// lyx session, containing lastfiles, lastfilepos, and lastopened
+       boost::scoped_ptr<lyx::Session> session_;
        ///
        typedef std::list<boost::shared_ptr<LyXView> > ViewList;
        ViewList views_;
index 0f858e819eb4dc134fb6681aa26204bf35ed42df..d59fd1a8db4e683623a6c4140ec739e71154711b 100644 (file)
@@ -43,6 +43,8 @@
 #include "kbmap.h"
 #include "language.h"
 #include "LColor.h"
+#include "session.h"
+#include "lyx_main.h"
 #include "lyx_cb.h"
 #include "LyXAction.h"
 #include "lyxfind.h"
@@ -996,6 +998,15 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
                        break;
 
                case LFUN_QUIT:
+                       if (view()->available()) {
+                               // save cursor Position for opened files to .lyx/session
+                               LyX::ref().session().saveFilePosition(owner->buffer()->fileName(),
+                                       boost::tie(view()->cursor().pit(), view()->cursor().pos()) );
+                               // save opened file name to .lyx/session 
+                               LyX::ref().session().setLastOpenedFiles( bufferlist.getFileNames());
+                               // save bookmarks to .lyx/session
+                               view()->saveSavedPositions();
+                       }
                        QuitLyX(argument == "force");
                        break;
 
@@ -1880,6 +1891,9 @@ void LyXFunc::doImport(string const & argument)
 
 void LyXFunc::closeBuffer()
 {
+       // save current cursor position 
+       LyX::ref().session().saveFilePosition(owner->buffer()->fileName(),
+               boost::tie(view()->cursor().pit(), view()->cursor().pos()) );
        if (bufferlist.close(owner->buffer(), true) && !quitting) {
                if (bufferlist.empty()) {
                        // need this otherwise SEGV may occur while
@@ -1966,6 +1980,8 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new)
        case LyXRC::RC_BIBTEX_COMMAND:
        case LyXRC::RC_BINDFILE:
        case LyXRC::RC_CHECKLASTFILES:
+       case LyXRC::RC_USELASTFILEPOS:
+       case LyXRC::RC_LOADSESSION:
        case LyXRC::RC_CHKTEX_COMMAND:
        case LyXRC::RC_CONVERTER:
        case LyXRC::RC_COPIER:
@@ -2007,7 +2023,6 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new)
        case LyXRC::RC_LANGUAGE_GLOBAL_OPTIONS:
        case LyXRC::RC_LANGUAGE_PACKAGE:
        case LyXRC::RC_LANGUAGE_USE_BABEL:
-       case LyXRC::RC_LASTFILES:
        case LyXRC::RC_MAKE_BACKUP:
        case LyXRC::RC_MARK_FOREIGN_LANGUAGE:
        case LyXRC::RC_NUMLASTFILES:
@@ -2052,6 +2067,9 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new)
        case LyXRC::RC_SCREEN_FONT_SIZES:
        case LyXRC::RC_SCREEN_FONT_TYPEWRITER:
        case LyXRC::RC_SCREEN_FONT_TYPEWRITER_FOUNDRY:
+       case LyXRC::RC_SCREEN_GEOMETRY_HEIGHT:
+       case LyXRC::RC_SCREEN_GEOMETRY_WIDTH:
+       case LyXRC::RC_SCREEN_GEOMETRY_XYSAVED:
        case LyXRC::RC_SCREEN_ZOOM:
        case LyXRC::RC_SERVERPIPE:
        case LyXRC::RC_SET_COLOR:
index 36bc4fc70fec61832c396ca8004973bfcab73a36..80ae63b770c1952349c7e53bf3d0aa689659a31b 100644 (file)
@@ -25,7 +25,7 @@
 #include "converter.h"
 #include "format.h"
 #include "gettext.h"
-#include "lastfiles.h"
+#include "session.h"
 #include "LColor.h"
 #include "lyxlex.h"
 #include "lyxfont.h"
@@ -104,7 +104,7 @@ keyword_item lyxrcTags[] = {
        { "\\language_global_options", LyXRC::RC_LANGUAGE_GLOBAL_OPTIONS },
        { "\\language_package", LyXRC::RC_LANGUAGE_PACKAGE },
        { "\\language_use_babel", LyXRC::RC_LANGUAGE_USE_BABEL },
-       { "\\lastfiles", LyXRC::RC_LASTFILES },
+       { "\\load_session", LyXRC::RC_LOADSESSION },
        { "\\make_backup", LyXRC::RC_MAKE_BACKUP },
        { "\\mark_foreign_language", LyXRC::RC_MARK_FOREIGN_LANGUAGE },
        { "\\num_lastfiles", LyXRC::RC_NUMLASTFILES },
@@ -152,6 +152,9 @@ keyword_item lyxrcTags[] = {
        { "\\screen_font_typewriter", LyXRC::RC_SCREEN_FONT_TYPEWRITER },
        { "\\screen_font_typewriter_foundry", LyXRC::RC_SCREEN_FONT_TYPEWRITER_FOUNDRY },
        { "\\screen_zoom", LyXRC::RC_SCREEN_ZOOM },
+       { "\\screen_geometry_height", LyXRC::RC_SCREEN_GEOMETRY_HEIGHT },
+       { "\\screen_geometry_width", LyXRC::RC_SCREEN_GEOMETRY_WIDTH },
+       { "\\screen_geometry_xysaved", LyXRC::RC_SCREEN_GEOMETRY_XYSAVED },
        { "\\serverpipe", LyXRC::RC_SERVERPIPE },
        { "\\set_color", LyXRC::RC_SET_COLOR },
        { "\\show_banner", LyXRC::RC_SHOW_BANNER },
@@ -163,6 +166,7 @@ keyword_item lyxrcTags[] = {
        { "\\use_alt_language", LyXRC::RC_USE_ALT_LANG },
        { "\\use_escape_chars", LyXRC::RC_USE_ESC_CHARS },
        { "\\use_input_encoding", LyXRC::RC_USE_INP_ENC },
+       { "\\use_lastfilepos", LyXRC::RC_USELASTFILEPOS },
        { "\\use_personal_dictionary", LyXRC::RC_USE_PERS_DICT },
        // compatibility with versions older than 1.4.0 only
        { "\\use_pspell", LyXRC::RC_USE_SPELL_LIB },
@@ -219,6 +223,9 @@ void LyXRC::setDefaults() {
        dpi = 75;
        // Because a screen typically is wider than a piece of paper:
        zoom = 150;
+       geometry_width = 0;
+       geometry_height = 0;
+       geometry_xysaved = true;
        wheel_jump = 5;
        // Default LaTeX font size:
        font_sizes[LyXFont::SIZE_TINY] = "5.0";
@@ -246,6 +253,8 @@ void LyXRC::setDefaults() {
        ascii_linelen = 65;
        num_lastfiles = maxlastfiles;
        check_lastfiles = true;
+       use_lastfilepos = true;
+       load_session = true;
        make_backup = true;
        backupdir_path.erase();
        display_graphics = lyx::graphics::ColorDisplay;
@@ -629,6 +638,24 @@ int LyXRC::read(LyXLex & lexrc)
                        }
                        break;
 
+               case RC_SCREEN_GEOMETRY_HEIGHT:
+                       if (lexrc.next()) {
+                               geometry_height = lexrc.getInteger();
+                       }
+                       break;
+
+               case RC_SCREEN_GEOMETRY_WIDTH:
+                       if (lexrc.next()) {
+                               geometry_width = lexrc.getInteger();
+                       }
+                       break;
+
+               case RC_SCREEN_GEOMETRY_XYSAVED:
+                       if (lexrc.next()) {
+                               geometry_xysaved = lexrc.getBool();
+                       }
+                       break;
+
                case RC_WHEEL_JUMP:
                        if (lexrc.next()) {
                                wheel_jump = lexrc.getInteger();
@@ -717,9 +744,15 @@ int LyXRC::read(LyXLex & lexrc)
                        }
                        break;
 
-               case RC_LASTFILES:
+               case RC_USELASTFILEPOS:
+                       if (lexrc.next()) {
+                               use_lastfilepos = lexrc.getBool();
+                       }
+                       break;
+
+               case RC_LOADSESSION:
                        if (lexrc.next()) {
-                               lastfiles = ExpandPath(os::internal_path(lexrc.getString()));
+                               load_session = lexrc.getBool();
                        }
                        break;
 
@@ -1427,7 +1460,7 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc) const
                        os << "\\preview_scale_factor "
                           << preview_scale_factor << '\n';
                }
-
+               
                os << "\n#\n"
                   << "# SCREEN & FONTS SECTION ############################\n"
                   << "#\n\n";
@@ -1460,6 +1493,24 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc) const
                    zoom != system_lyxrc.zoom) {
                        os << "\\screen_zoom " << zoom << '\n';
                }
+       case RC_SCREEN_GEOMETRY_HEIGHT:
+               if (ignore_system_lyxrc ||
+                   geometry_height != system_lyxrc.geometry_height) {
+                       os << "\\screen_geometry_height " << geometry_height
+                          << '\n';
+               }
+       case RC_SCREEN_GEOMETRY_WIDTH:
+               if (ignore_system_lyxrc ||
+                   geometry_width != system_lyxrc.geometry_width) {
+                       os << "\\screen_geometry_width " << geometry_width
+                          << '\n';
+               }
+       case RC_SCREEN_GEOMETRY_XYSAVED:
+               if (ignore_system_lyxrc ||
+                   geometry_xysaved != system_lyxrc.geometry_xysaved) {
+                       os << "\\screen_geometry_xysaved " << convert<string>(geometry_xysaved)
+                          << '\n';
+               }
        case RC_WHEEL_JUMP:
                if (ignore_system_lyxrc ||
                    wheel_jump != system_lyxrc.wheel_jump) {
@@ -1741,11 +1792,17 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc) const
                        string const path = os::external_path(document_path);
                        os << "\\document_path \"" << path << "\"\n";
                }
-       case RC_LASTFILES:
+       case RC_USELASTFILEPOS:
+               if (ignore_system_lyxrc ||
+                   use_lastfilepos != system_lyxrc.use_lastfilepos) {
+                       os << "\\use_session " << convert<string>(use_lastfilepos)
+                          << '\n';
+               }
+       case RC_LOADSESSION:
                if (ignore_system_lyxrc ||
-                   lastfiles != system_lyxrc.lastfiles) {
-                       string const path = os::external_path(lastfiles);
-                       os << "\\lastfiles \"" << path << "\"\n";
+                   load_session != system_lyxrc.load_session) {
+                       os << "\\load_session " << convert<string>(load_session) 
+                          << "\n";
                }
        case RC_NUMLASTFILES:
                if (ignore_system_lyxrc ||
@@ -2225,8 +2282,12 @@ string const LyXRC::getDescription(LyXRCTags tag)
                str = _("De-select if you don't want babel to be used when the language of the document is the default language.");
                break;
 
-       case RC_LASTFILES:
-               str = _("The file where the last-files information should be stored.");
+       case RC_USELASTFILEPOS:
+               str = _("De-select if you do not want LyX to scroll to saved position.");
+               break;
+
+       case RC_LOADSESSION:
+               str = _("De-select to prevent loading files opened from the last lyx session.");
                break;
 
        case RC_MAKE_BACKUP:
@@ -2384,6 +2445,15 @@ string const LyXRC::getDescription(LyXRCTags tag)
                str = _("The zoom percentage for screen fonts. A setting of 100% will make the fonts roughly the same size as on paper.");
                break;
 
+       case RC_SCREEN_GEOMETRY_HEIGHT:
+       case RC_SCREEN_GEOMETRY_WIDTH:
+               str = _("Specify geometry of the main view in width x height (values from last session will not be used if non-zero values are specified).");
+               break;  
+
+       case RC_SCREEN_GEOMETRY_XYSAVED:
+               str = _("Allow session manager to save and restore windows position.");
+               break;  
+
        case RC_SERVERPIPE:
                str = _("This starts the lyxserver. The pipes get an additional extension \".in\" and \".out\". Only for advanced users.");
                break;
index 2b88a84f35af96b2ed6ca95dc8931df70807aa56..d84438e23b288e56ece2932522c658a403a17c7f 100644 (file)
@@ -75,7 +75,8 @@ public:
                RC_LANGUAGE_GLOBAL_OPTIONS,
                RC_LANGUAGE_PACKAGE,
                RC_LANGUAGE_USE_BABEL,
-               RC_LASTFILES,
+               RC_USELASTFILEPOS,
+               RC_LOADSESSION,
                RC_MAKE_BACKUP,
                RC_MARK_FOREIGN_LANGUAGE,
                RC_NUMLASTFILES,
@@ -116,6 +117,9 @@ public:
                RC_SCREEN_FONT_SIZES,
                RC_SCREEN_FONT_TYPEWRITER,
                RC_SCREEN_FONT_TYPEWRITER_FOUNDRY,
+               RC_SCREEN_GEOMETRY_HEIGHT,
+               RC_SCREEN_GEOMETRY_WIDTH,
+               RC_SCREEN_GEOMETRY_XYSAVED,
                RC_SCREEN_ZOOM,
                RC_SERVERPIPE,
                RC_SET_COLOR,
@@ -227,14 +231,22 @@ public:
        bool auto_reset_options;
        ///
        bool check_lastfiles;
-       /// filename for lastfiles file
-       std::string lastfiles;
        /// maximal number of lastfiles
        unsigned int num_lastfiles;
+       /// whether or not go to saved position when opening a file
+       bool use_lastfilepos;
+       /// load files from last session automatically
+       bool load_session;
        /// shall a backup file be created
        bool make_backup;
        /// A directory for storing backup files
        std::string backupdir_path;
+       /// Width of MainWindow. if 0, value from last session will be used
+       int geometry_width;
+       /// Height of MainWindow, if 0, value from last session will be used
+       int geometry_height;
+       /// Whether or not save/restore windows position as session info
+       bool geometry_xysaved;
        /// Zoom factor for screen fonts
        unsigned int zoom;
        /// parameter for button_4 and button_5 (scrollwheel)
diff --git a/src/session.C b/src/session.C
new file mode 100644 (file)
index 0000000..a1781e4
--- /dev/null
@@ -0,0 +1,279 @@
+/**
+ * \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::endl;
+using std::istringstream;
+using std::copy;
+using std::find;
+using std::ostream_iterator;
+
+namespace lyx{
+
+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]";
+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
+
+
+Session::Session(unsigned int num) :
+       default_num_last_files(4),
+       absolute_max_last_files(100),
+       num_lastfilepos(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)
+{
+       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 Session::readFile()
+{
+       // 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] == ' ')
+                       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
+                       lyx::pit_type pit;
+                       lyx::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;
+                       lyx::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;
+               }
+       }
+}
+
+
+void Session::writeFile() 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;
+}
+
+
+void Session::addLastFile(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 Session::saveFilePosition(string const & fname, FilePos pos)
+{
+       lastfilepos[fname] = pos;
+}
+
+
+Session::FilePos Session::loadFilePosition(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 Session::clearLastOpenedFiles()
+{
+       lastopened.clear();
+}
+
+
+void Session::setLastOpenedFiles(vector<string> const & files)
+{
+       lastopened = files;
+}
+
+
+void Session::saveBookmark(Bookmark const & bookmark)
+{
+       bookmarks.push_back(bookmark);
+}
+
+
+void Session::saveSessionInfo(string const & key, string const & value)
+{
+       sessioninfo[key] = value;
+}
+
+
+string const Session::loadSessionInfo(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;
+}
+
+}
diff --git a/src/session.h b/src/session.h
new file mode 100644 (file)
index 0000000..e4654a0
--- /dev/null
@@ -0,0 +1,169 @@
+// -*- 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 Session : boost::noncopyable {
+
+public:
+       ///
+       typedef boost::tuple<lyx::pit_type, lyx::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, lyx::pos_type> Bookmark;
+       ///
+       typedef std::vector<Bookmark> BookmarkList;
+       ///
+       typedef std::map<std::string, std::string> MiscInfo;
+
+public:
+       /** Read the session file.
+           @param num length of lastfiles
+       */
+       explicit Session(unsigned int num = 4);
+
+       /** Write the session file.
+       */
+       void writeFile() const;
+       
+       /** 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 addLastFile(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.
+       */
+       void saveFilePosition(std::string const & fname, FilePos pos);
+       
+       /** clear lastopened file list
+        */
+       void clearLastOpenedFiles();
+       
+       /** set lastopened file list
+           @param files filenames of a list of opened files 
+       */
+       void setLastOpenedFiles(std::vector<std::string> const & files);
+       
+       /** 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;
+       
+       /// Return lastfiles container (deque)
+       LastFiles const lastFiles() const { return lastfiles; }
+       
+       /// Return lastopened container (vector)
+       LastOpened const lastOpenedFiles() const { return lastopened; }
+
+       /** save a bookmark
+               @bookmark bookmark to be saved
+       */
+       void saveBookmark(Bookmark const & bookmark);
+       
+       /** return bookmark list. Non-const container is used since 
+               bookmarks will be cleaned after use.
+       */
+       BookmarkList & loadBookmarks() { return bookmarks; }
+
+       /** 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);
+
+       /** 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);        
+private:
+       /// Default number of lastfiles.
+       unsigned int const default_num_last_files;
+
+       /// Max number of lastfiles.
+       unsigned int const absolute_max_last_files;
+
+       /// default number of lastfilepos to save */
+       unsigned int const num_lastfilepos;
+
+       /// file to save session, determined in the constructor.
+       std::string session_file;
+       
+       /// a list of lastfiles
+       LastFiles lastfiles;
+
+       /// a list of bookmarks
+       BookmarkList bookmarks;
+
+       /// a map to save session info
+       MiscInfo sessioninfo;
+       
+       /// number of files in the lastfiles list.
+       unsigned int num_lastfiles;
+       
+       /// a map of file positions
+       FilePosMap lastfilepos;
+       
+       /// a list of lastopened files
+       LastOpened lastopened;
+       
+       /** 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();
+
+       /** 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);
+};
+
+}
+
+#endif