> No. We need to have the "last position" feature in addition, not mixed
> with lastfile.

OK, since you insist, here comes a much larger patch.

The patch works on my system. However, there are two problems that
make this feature almost useless. Please help me resolve them.

1. Alt-F4 and close-button do not trigger LDUNC_QUIT or bufferClose()
so position will not be saved. Note that Alt-F4 is marked as a
shortcut for File->Exit but it behaves differently than File->Exit.

2. If a filename is passed to lyx as 'lyx file.lyx', the cursor will
be moved by my patch, but then moved back by some unknown mechanism
(seems to be some GUI stuff). This is a big drawback since this is the
main way I start lyx.

Cheers,
Bo
Index: src/lyx_cb.C
===================================================================
--- src/lyx_cb.C	(revision 13470)
+++ src/lyx_cb.C	(working copy)
@@ -23,6 +23,7 @@
 #include "debug.h"
 #include "gettext.h"
 #include "lastfiles.h"
+#include "filepositions.h"
 #include "LaTeXFeatures.h"
 #include "lyx_main.h"
 #include "lyxlayout.h"
@@ -197,6 +198,7 @@
 			return;
 
 		LyX::cref().lastfiles().writeFile(lyxrc.lastfiles);
+		LyX::cref().filepositions().writeFile(lyxrc.filepositions);
 	}
 
 	// Set a flag that we do quitting from the program,
Index: src/BufferView_pimpl.C
===================================================================
--- src/BufferView_pimpl.C	(revision 13470)
+++ src/BufferView_pimpl.C	(working copy)
@@ -43,6 +43,7 @@
 #include "lyxtext.h"
 #include "lyxrc.h"
 #include "lastfiles.h"
+#include "filepositions.h"
 #include "metricsinfo.h"
 #include "paragraph.h"
 #include "paragraph_funcs.h"
@@ -293,6 +294,23 @@
 
 	setBuffer(b);
 	bv_->showErrorList(_("Parse"));
+        
+	// scroll to the position when the file was last closed
+	if (lyxrc.use_filepos) {
+		lyx::pit_type pit = LyX::ref().filepositions().loadFilePosition(s);
+		// move to the beginning of that paragraph
+		// be careful since the file may have been externally changed ...
+		if ( static_cast<size_t>(pit) < b->paragraphs().size() ) {
+			cursor_.clearSelection();
+			ParIterator it = b->par_iterator_begin();
+			ParIterator const end = b->par_iterator_end();
+			for (; it != end; ++it)
+				if (it.pit() == pit)
+					break;
+			if (it != end)		
+				bv_->setCursor(makeDocIterator(it, 0));
+		}
+	}
 
 	if (tolastfiles)
 		LyX::ref().lastfiles().newFile(b->fileName());
@@ -767,7 +785,12 @@
 	saved_positions[i] = Position(buffer_->fileName(),
 				      cursor_.paragraph().id(),
 				      cursor_.pos());
-	if (i > 0)
+	// if i == 0, (called when this buffer is closed), 
+	// save current paragraph pit to filepositions
+	if (i == 0)
+		LyX::ref().filepositions().saveFilePosition(buffer_->fileName(),
+				cursor_.pit() );
+	else
 		owner_->message(bformat(_("Saved bookmark %1$d"), i));
 }
 
Index: src/lyxfunc.C
===================================================================
--- src/lyxfunc.C	(revision 13470)
+++ src/lyxfunc.C	(working copy)
@@ -996,6 +996,11 @@
 			break;
 
 		case LFUN_QUIT:
+			// with this, File->exit will save Position,
+			// however, Alt-F4 and close-button do not go 
+			// through here ...
+			if (view()->available())
+				view()->savePosition(0);
 			QuitLyX(argument == "force");
 			break;
 
@@ -1880,6 +1885,8 @@
 
 void LyXFunc::closeBuffer()
 {
+	// save current position to lastfile
+	view()->savePosition(0);
 	if (bufferlist.close(owner->buffer(), true) && !quitting) {
 		if (bufferlist.empty()) {
 			// need this otherwise SEGV may occur while
@@ -2008,6 +2015,7 @@
 	case LyXRC::RC_LANGUAGE_PACKAGE:
 	case LyXRC::RC_LANGUAGE_USE_BABEL:
 	case LyXRC::RC_LASTFILES:
+	case LyXRC::RC_FILEPOSITIONS:
 	case LyXRC::RC_MAKE_BACKUP:
 	case LyXRC::RC_MARK_FOREIGN_LANGUAGE:
 	case LyXRC::RC_NUMLASTFILES:
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 13470)
+++ src/Makefile.am	(working copy)
@@ -191,6 +191,8 @@
 	language.h \
 	lastfiles.C \
 	lastfiles.h \
+	filepositions.C \
+	filepositions.h \
 	layout.h \
 	lengthcommon.C \
 	lengthcommon.h \
Index: src/lyxrc.C
===================================================================
--- src/lyxrc.C	(revision 13470)
+++ src/lyxrc.C	(working copy)
@@ -26,6 +26,7 @@
 #include "format.h"
 #include "gettext.h"
 #include "lastfiles.h"
+#include "filepositions.h"
 #include "LColor.h"
 #include "lyxlex.h"
 #include "lyxfont.h"
@@ -105,6 +106,8 @@
 	{ "\\language_package", LyXRC::RC_LANGUAGE_PACKAGE },
 	{ "\\language_use_babel", LyXRC::RC_LANGUAGE_USE_BABEL },
 	{ "\\lastfiles", LyXRC::RC_LASTFILES },
+	{ "\\use_filepos", LyXRC::RC_USEFILEPOS },
+	{ "\\filepositions", LyXRC::RC_FILEPOSITIONS },
 	{ "\\make_backup", LyXRC::RC_MAKE_BACKUP },
 	{ "\\mark_foreign_language", LyXRC::RC_MARK_FOREIGN_LANGUAGE },
 	{ "\\num_lastfiles", LyXRC::RC_NUMLASTFILES },
@@ -246,6 +249,7 @@
 	ascii_linelen = 65;
 	num_lastfiles = maxlastfiles;
 	check_lastfiles = true;
+	use_filepos = true;
 	make_backup = true;
 	backupdir_path.erase();
 	display_graphics = lyx::graphics::ColorDisplay;
@@ -723,6 +727,18 @@
 			}
 			break;
 
+		case RC_USEFILEPOS:
+			if (lexrc.next()) {
+				use_filepos = lexrc.getBool();
+			}
+			break;
+
+		case RC_FILEPOSITIONS:
+			if (lexrc.next()) {
+				filepositions = ExpandPath(os::internal_path(lexrc.getString()));
+			}
+			break;
+
 		case RC_NUMLASTFILES:
 			if (lexrc.next()) {
 				num_lastfiles = lexrc.getInteger();
@@ -1747,6 +1763,18 @@
 			string const path = os::external_path(lastfiles);
 			os << "\\lastfiles \"" << path << "\"\n";
 		}
+	case RC_USEFILEPOS:
+		if (ignore_system_lyxrc ||
+		    use_filepos != system_lyxrc.use_filepos) {
+			os << "\\use_filepos " << convert<string>(use_filepos)
+			   << '\n';
+		}
+	case RC_FILEPOSITIONS:
+		if (ignore_system_lyxrc ||
+		    filepositions != system_lyxrc.filepositions) {
+			string const path = os::external_path(filepositions);
+			os << "\\filepositions \"" << path << "\"\n";
+		}
 	case RC_NUMLASTFILES:
 		if (ignore_system_lyxrc ||
 		    num_lastfiles != system_lyxrc.num_lastfiles) {
@@ -2229,6 +2257,14 @@
 		str = _("The file where the last-files information should be stored.");
 		break;
 
+	case RC_USEFILEPOS:
+		str = _("De-select if you do not want LyX to scroll to saved position.");
+		break;
+
+	case RC_FILEPOSITIONS:
+		str = _("The file where the file positions when last closed should be stored.");
+		break;
+
 	case RC_MAKE_BACKUP:
 		str = _("De-select if you don't want LyX to create backup files.");
 		break;
Index: src/filepositions.C
===================================================================
--- src/filepositions.C	(revision 0)
+++ src/filepositions.C	(revision 0)
@@ -0,0 +1,86 @@
+/**
+ * \file filespositions.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Bo Peng
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "filepositions.h"
+#include "debug.h"
+
+#include <boost/filesystem/operations.hpp>
+
+#include <fstream>
+#include <sstream>
+
+using std::getline;
+using std::string;
+using std::ifstream;
+using std::ofstream;
+using std::endl;
+using std::istringstream;
+
+FilePositions::FilePositions(string const & filename)
+	: num_positions(100)
+{
+	readFile(filename);
+}
+
+void FilePositions::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) && file_positions.size() < num_positions ) {
+		// pos, filename\n
+		FilePos pos;
+		string fname;
+		istringstream itmp(tmp);
+		itmp >> pos;
+		itmp.ignore(2);  // ingore ","
+		itmp >> fname;
+		if (!boost::filesystem::exists(fname))
+			continue;
+		file_positions[fname] = pos;
+	}
+	ifs.close();
+}
+
+void FilePositions::writeFile(string const & filename) const
+{
+	ofstream ofs(filename.c_str());
+	if (ofs) {
+		for (FilePosMap::const_iterator file = file_positions.begin(); 
+			file != file_positions.end(); ++file) {
+			ofs << file->second << ", " << file->first << endl;
+		}
+		ofs.close();
+	} else
+		lyxerr << "LyX: Warning: unable to save FilePositions: "
+		       << filename << endl;
+	ofs.close();		   
+}
+
+void FilePositions::saveFilePosition(string const& fname, FilePos pos )
+{
+	file_positions[fname] = pos;
+}
+
+FilePositions::FilePos FilePositions::loadFilePosition(string const& fname ) const
+{
+	FilePosMap::const_iterator entry = file_positions.find(fname);
+	// has position information, return it.
+	if( entry != file_positions.end() )
+		return entry->second;
+	// not found, return the first paragraph
+	else 
+		return 0;
+}
+
Index: src/lyxrc.h
===================================================================
--- src/lyxrc.h	(revision 13470)
+++ src/lyxrc.h	(working copy)
@@ -76,6 +76,8 @@
 		RC_LANGUAGE_PACKAGE,
 		RC_LANGUAGE_USE_BABEL,
 		RC_LASTFILES,
+		RC_USEFILEPOS,
+		RC_FILEPOSITIONS,
 		RC_MAKE_BACKUP,
 		RC_MARK_FOREIGN_LANGUAGE,
 		RC_NUMLASTFILES,
@@ -231,6 +233,10 @@
 	std::string lastfiles;
 	/// maximal number of lastfiles
 	unsigned int num_lastfiles;
+	/// whether or not go to saved position when open a file
+	bool use_filepos;
+	/// filename for filepositions file
+	std::string filepositions;
 	/// shall a backup file be created
 	bool make_backup;
 	/// A directory for storing backup files
Index: src/filepositions.h
===================================================================
--- src/filepositions.h	(revision 0)
+++ src/filepositions.h	(revision 0)
@@ -0,0 +1,68 @@
+// -*- C++ -*-
+/**
+ * \file filepositions.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Bo Peng
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef FILEPOSITIONS_H
+#define FILEPOSITIONS_H
+
+// for pit_type
+#include <support/types.h>
+#include <boost/utility.hpp>
+
+#include <string>
+#include <map>
+
+/** The cursor positions of files closed
+ */
+class FilePositions : boost::noncopyable {
+public:
+	///
+	typedef lyx::pit_type FilePos;
+	///
+	typedef std::map<std::string, FilePos > FilePosMap;
+
+	/** Read the filepos file.
+	    @param file The file to read the filepos form.
+	*/
+	explicit FilePositions(std::string const & file);
+
+	/** Write the filepos file.
+	    @param file The file to save the filepos map.
+	*/
+	void writeFile(std::string const & file) const;
+	
+	/** add cursor position to the fname entry in the file pos 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);
+	
+	/** 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;
+	
+private:
+
+	/// a map of file positions
+	FilePosMap file_positions;
+	
+	/// number of files with position stored in the filepos file
+	/// Will be initialized as 100.
+	const unsigned int num_positions;
+
+	/** Read the filepos file.
+	    Reads the #.lyx/filepos# at the beginning of the LyX session.
+	    This will read the filepos file (usually #.lyx/filepos#). 
+	    @param file the file containing the filepos.
+	*/
+	void readFile(std::string const & file);
+};
+#endif
Index: src/lyx_main.C
===================================================================
--- src/lyx_main.C	(revision 13470)
+++ src/lyx_main.C	(working copy)
@@ -29,6 +29,7 @@
 #include "kbmap.h"
 #include "language.h"
 #include "lastfiles.h"
+#include "filepositions.h"
 #include "LColor.h"
 #include "lyxfunc.h"
 #include "lyxlex.h"
@@ -176,7 +177,19 @@
 	return *lastfiles_.get();
 }
 
+FilePositions & LyX::filepositions()
+{
+	BOOST_ASSERT(filepositions_.get());
+	return *filepositions_.get();
+}
 
+
+FilePositions const & LyX::filepositions() const
+{
+	BOOST_ASSERT(filepositions_.get());
+	return *filepositions_.get();
+}
+
 void LyX::addLyXView(boost::shared_ptr<LyXView> const & lyxview)
 {
 	views_.push_back(lyxview);
@@ -275,7 +288,6 @@
 		}
 		files.clear(); // the files are already loaded
 	}
-
 	if (want_gui)
 		lyx_gui::start(batch_command, files);
 	else {
@@ -428,6 +440,10 @@
 	if (lyxrc.lastfiles.empty()) {
 		lyxrc.lastfiles = AddName(package().user_support(), "lastfiles");
 	}
+	
+	if (lyxrc.filepositions.empty()) {
+		lyxrc.filepositions = AddName(package().user_support(), "filepos");
+	}
 
 	if (lyxrc.roman_font_name.empty())
 		lyxrc.roman_font_name = lyx_gui::roman_font_name();
@@ -518,6 +534,9 @@
 	lastfiles_.reset(new LastFiles(lyxrc.lastfiles,
 				       lyxrc.check_lastfiles,
 				       lyxrc.num_lastfiles));
+	lyxerr[Debug::INIT] << "Reading filepositions `"
+			    << lyxrc.filepositions << "'..." << endl;
+	filepositions_.reset(new FilePositions(lyxrc.filepositions));
 }
 
 
Index: src/lyx_main.h
===================================================================
--- src/lyx_main.h	(revision 13470)
+++ src/lyx_main.h	(working copy)
@@ -25,6 +25,7 @@
 class ErrorItem;
 class InsetBase;
 class LastFiles;
+class FilePositions;
 class LyXView;
 class kb_keymap;
 
@@ -42,6 +43,9 @@
 	LastFiles & lastfiles();
 	LastFiles const & lastfiles() const;
 
+	FilePositions & filepositions();
+	FilePositions const & filepositions() const;
+
 	void addLyXView(boost::shared_ptr<LyXView> const & lyxview);
 
 	/** redraw \c inset in all the BufferViews in which it is currently
@@ -88,6 +92,8 @@
 
 	/// last files loaded
 	boost::scoped_ptr<LastFiles> lastfiles_;
+	/// file positions when saved
+	boost::scoped_ptr<FilePositions> filepositions_;
 	///
 	typedef std::list<boost::shared_ptr<LyXView> > ViewList;
 	ViewList views_;




Reply via email to