1 // -*- C++ -*-
2 /**
3  * \file Session.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Lars Gullik Bjønnes
8  * \author Bo Peng
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12 
13 #ifndef SESSION_H
14 #define SESSION_H
15 
16 #include "support/FileName.h"
17 #include "support/types.h"
18 
19 #include <list>
20 #include <string>
21 #include <vector>
22 
23 /** This session file maintains
24   1. the latest documents loaded (lastfiles)
25   2. cursor positions of files closed (lastfilepos)
26   3. opened files when a lyx session is closed (lastopened)
27   4. bookmarks
28   5. general purpose session info in the form of key/value pairs
29   6. the latest commands entered in the command buffer (lastcommands)
30  */
31 namespace lyx {
32 
33 /* base class for all sections in the session file
34 */
35 class SessionSection
36 {
37 public:
38 	///
SessionSection()39 	SessionSection() {}
40 	///
~SessionSection()41 	virtual ~SessionSection() {}
42 
43 	/// read section from std::istream
44 	virtual void read(std::istream & is) = 0;
45 
46 	/// write to std::ostream
47 	virtual void write(std::ostream & os) const = 0;
48 
49 private:
50 	/// uncopiable
51 	SessionSection(SessionSection const &);
52 	void operator=(SessionSection const &);
53 };
54 
55 
56 class LastFilesSection : SessionSection
57 {
58 public:
59 	///
60 	typedef std::vector<support::FileName> LastFiles;
61 
62 public:
63 	///
64 	explicit LastFilesSection(unsigned int num = 4);
65 
66 	///
67 	void read(std::istream & is);
68 
69 	///
70 	void write(std::ostream & os) const;
71 
72 	/// Return lastfiles container (vector)
lastFiles()73 	LastFiles const lastFiles() const { return lastfiles; }
74 
75 	/** Insert #file# into the lastfile vector.
76 	    This funtion inserts #file# into the last files list. If the file
77 	    already exists it is moved to the top of the list, else exist it
78 	    is placed on the top of the list. If the list is full the last
79 	    file in the list is popped from the end.
80 	    @param file the file to insert in the lastfile list.
81 	*/
82 	void add(support::FileName const & file);
83 
84 private:
85 	/// Default number of lastfiles.
86 	unsigned int const default_num_last_files;
87 
88 	/// Max number of lastfiles.
89 	unsigned int const absolute_max_last_files;
90 
91 	/// a list of lastfiles
92 	LastFiles lastfiles;
93 
94 	/// number of files in the lastfiles list.
95 	unsigned int num_lastfiles;
96 
97 	/** Used by the constructor to set the number of stored last files.
98 	    @param num the number of lastfiles to set.
99 	*/
100 	void setNumberOfLastFiles(unsigned int num);
101 };
102 
103 
104 class LastOpenedSection : SessionSection
105 {
106 public:
107 	///
108 	struct LastOpenedFile {
LastOpenedFileLastOpenedFile109 		LastOpenedFile() : file_name(), active(false) {}
110 
LastOpenedFileLastOpenedFile111 		LastOpenedFile(support::FileName file_name_, bool active_)
112 			: file_name(file_name_), active(active_) {}
113 
114 		support::FileName file_name;
115 		bool active;
116 	};
117 	///
118 	typedef std::vector<LastOpenedFile> LastOpened;
119 
120 public:
121 	///
122 	void read(std::istream & is);
123 
124 	///
125 	void write(std::ostream & os) const;
126 
127 	/// Return lastopened container (vector)
getfiles()128 	LastOpened const getfiles() const { return lastopened; }
129 
130 	/** add file to lastopened file list
131 	    @param file filename to add
132 	*/
133 	void add(support::FileName const & file, bool active = false);
134 
135 	/** clear lastopened file list
136 	 */
137 	void clear();
138 
139 private:
140 	/// a list of lastopened files
141 	LastOpened lastopened;
142 };
143 
144 
145 class LastFilePosSection : SessionSection
146 {
147 public:
148 	///
149 	struct FilePos {
FilePosFilePos150 		FilePos() : pit(0), pos(0) {}
151 		support::FileName file;
152 		pit_type pit;
153 		pos_type pos;
154 	};
155 
156 	///
157 	typedef std::list<FilePos> FilePosList;
158 
159 public:
160 	///
LastFilePosSection()161 	LastFilePosSection() : num_lastfilepos(100) {}
162 
163 	///
164 	void read(std::istream & is);
165 
166 	///
167 	void write(std::ostream & os) const;
168 
169 	/** add cursor position to the fname entry in the filepos list
170 	    @param pos file name and position of the cursor when the BufferView is closed.
171 	*/
172 	void save(FilePos const & pos);
173 
174 	/** load saved cursor position from the fname entry in the filepos list
175 	    @param fname file entry for which to load position information
176 	*/
177 	FilePos load(support::FileName const & fname) const;
178 
179 private:
180 	/// default number of lastfilepos to save */
181 	unsigned int const num_lastfilepos;
182 
183 
184 	/// a list of file positions
185 	FilePosList lastfilepos;
186 };
187 
188 
189 class BookmarksSection : SessionSection
190 {
191 public:
192 	/// A bookmark is composed of three parts
193 	/// 1. filename
194 	/// 2. bottom (whole document) level pit and pos, used to (inaccurately) save/restore a bookmark
195 	/// 3. top level id and pos, used to accurately locate bookmark when lyx is running
196 	/// top and bottom level information sometimes needs to be sync'ed. In particular,
197 	/// top_id is determined when a bookmark is restored from session; and
198 	/// bottom_pit and bottom_pos are determined from top_id when a bookmark
199 	/// is save to session. (What a mess! :-)
200 	///
201 	/// TODO: bottom level pit and pos will be replaced by StableDocIterator
202 	class Bookmark {
203 	public:
204 		/// Filename
205 		support::FileName filename;
206 		/// Bottom level cursor pit, will be saved/restored by .lyx/session
207 		pit_type bottom_pit;
208 		/// Bottom level cursor position, will be saved/restore by .lyx/session
209 		pos_type bottom_pos;
210 		/// Top level cursor id, used to lcoate bookmarks for opened files
211 		int top_id;
212 		/// Top level cursor position within a paragraph
213 		pos_type top_pos;
214 		///
Bookmark()215 		Bookmark() : bottom_pit(0), bottom_pos(0), top_id(0), top_pos(0) {}
216 		///
Bookmark(support::FileName const & f,pit_type pit,pos_type pos,int id,pos_type tpos)217 		Bookmark(support::FileName const & f, pit_type pit, pos_type pos, int id, pos_type tpos)
218 			: filename(f), bottom_pit(pit), bottom_pos(pos), top_id(id), top_pos(tpos) {}
219 		/// set bookmark top_id, this is because newly loaded bookmark
220 		/// may have zero par_id and par_pit can change during editing, see bug 3092
updatePos(pit_type pit,pos_type pos,int id)221 		void updatePos(pit_type pit, pos_type pos, int id) {
222 			bottom_pit = pit;
223 			bottom_pos = pos;
224 			top_id = id;
225 		}
226 	};
227 
228 	///
229 	typedef std::vector<Bookmark> BookmarkList;
230 
231 public:
232 	/// constructor, set max_bookmarks
233 	/// allow 9 regular bookmarks, bookmark 0 is temporary
BookmarksSection()234 	BookmarksSection() : bookmarks(10), max_bookmarks(9) {}
235 
236 	/// Save the current position as bookmark
237 	void save(support::FileName const & fname, pit_type bottom_pit, pos_type bottom_pos,
238 		int top_id, pos_type top_pos, unsigned int idx);
239 
240 	/// return bookmark 0-9, bookmark 0 is the temporary bookmark
241 	Bookmark const & bookmark(unsigned int i) const;
242 
243 	/// does the given bookmark have a saved position ?
244 	bool isValid(unsigned int i) const;
245 
246 	/// is there at least one bookmark that has a saved position ?
247 	bool hasValid() const;
248 
249 	///
size()250 	unsigned int size() const { return max_bookmarks; }
251 
252 	/// clear all bookmarks
253 	void clear();
254 
255 	///
256 	void read(std::istream & is);
257 
258 	///
259 	void write(std::ostream & os) const;
260 
261 	/** return bookmark list. Non-const container is used since
262 		bookmarks will be cleaned after use.
263 	*/
load()264 	BookmarkList & load() { return bookmarks; }
265 
266 private:
267 
268 	/// a list of bookmarks
269 	BookmarkList bookmarks;
270 
271 	///
272 	unsigned int const max_bookmarks;
273 };
274 
275 
276 class LastCommandsSection : SessionSection
277 {
278 public:
279 	///
280 	typedef std::vector<std::string> LastCommands;
281 
282 public:
283 	///
284 	LastCommandsSection(unsigned int num);
285 	///
286 	void read(std::istream & is);
287 
288 	///
289 	void write(std::ostream & os) const;
290 
291 	/// Return lastcommands container (vector)
getcommands()292 	LastCommands const getcommands() const { return lastcommands; }
293 
294 	/** add command to lastcommands list
295 	    @param command command to add
296 	*/
297 	void add(std::string const & command);
298 
299 	/** clear lastcommands list
300 	 */
301 	void clear();
302 
303 private:
304 	/// number of commands in the lastcommands list.
305 	unsigned int num_lastcommands;
306 
307 	/** Used by the constructor to set the number of stored last commands.
308 	    @param num the number of lastcommands to set.
309 	*/
310 	void setNumberOfLastCommands(unsigned int num);
311 
312 	/// a list of lastopened commands
313 	LastCommands lastcommands;
314 
315 	/// Default number of lastcommands.
316 	unsigned int const default_num_last_commands;
317 
318 	/// Max number of lastcommands.
319 	unsigned int const absolute_max_last_commands;
320 };
321 
322 
323 class AuthFilesSection : SessionSection
324 {
325 public:
326 	///
327 	explicit AuthFilesSection();
328 
329 	///
330 	void read(std::istream & is);
331 
332 	///
333 	void write(std::ostream & os) const;
334 
335 	///
336 	bool find(std::string const & name) const;
337 
338 	///
339 	void insert(std::string const & name);
340 
341 private:
342 	/// set of document files authorized for external conversion
343 	std::set<std::string> auth_files_;
344 };
345 
346 
347 class ShellEscapeSection : SessionSection
348 {
349 public:
350 	///
ShellEscapeSection()351 	explicit ShellEscapeSection() {};
352 
353 	///
354 	void read(std::istream & is);
355 
356 	///
357 	void write(std::ostream & os) const;
358 
359 	///
360 	bool find(std::string const & name) const;
361 
362 	///
363 	bool findAuth(std::string const & name) const;
364 
365 	///
366 	void insert(std::string const & name, bool auth = false);
367 
368 	///
369 	void remove(std::string const & name);
370 
371 private:
372 	/// set of document files authorized for external conversion
373 	std::set<std::string> shellescape_files_;
374 };
375 
376 
377 class Session
378 {
379 public:
380 	/// Read the session file.  @param num length of lastfiles
381 	explicit Session(unsigned int num_last_files = 4,
382 		unsigned int num_last_commands = 30);
383 	/// Write the session file.
384 	void writeFile() const;
385 	///
lastFiles()386 	LastFilesSection & lastFiles() { return last_files; }
387 	///
lastFiles()388 	LastFilesSection const & lastFiles() const { return last_files; }
389 	///
lastOpened()390 	LastOpenedSection & lastOpened() { return last_opened; }
391 	///
lastOpened()392 	LastOpenedSection const & lastOpened() const { return last_opened; }
393 	///
lastFilePos()394 	LastFilePosSection & lastFilePos() { return last_file_pos; }
395 	///
lastFilePos()396 	LastFilePosSection const & lastFilePos() const { return last_file_pos; }
397 	///
bookmarks()398 	BookmarksSection & bookmarks() { return bookmarks_; }
399 	///
bookmarks()400 	BookmarksSection const & bookmarks() const { return bookmarks_; }
401 	///
lastCommands()402 	LastCommandsSection & lastCommands() { return last_commands; }
403 	///
lastCommands()404 	LastCommandsSection const & lastCommands() const { return last_commands; }
405 	///
authFiles()406 	AuthFilesSection & authFiles() { return auth_files; }
407 	///
authFiles()408 	AuthFilesSection const & authFiles() const { return auth_files; }
409 	///
shellescapeFiles()410 	ShellEscapeSection & shellescapeFiles() { return shellescape_files; }
411 	///
shellescapeFiles()412 	ShellEscapeSection const & shellescapeFiles() const { return shellescape_files; }
413 
414 private:
415 	friend class LyX;
416 	/// uncopiable
417 	Session(Session const &);
418 	void operator=(Session const &);
419 
420 	/// file to save session, determined in the constructor.
421 	support::FileName session_file;
422 
423 	/** Read the session file.
424 	    Reads the #.lyx/session# at the beginning of the LyX session.
425 	    This will read the session file (usually #.lyx/session#).
426 	    @param file the file containing the session.
427 	*/
428 	void readFile();
429 
430 	///
431 	LastFilesSection last_files;
432 	///
433 	LastOpenedSection last_opened;
434 	///
435 	LastFilePosSection last_file_pos;
436 	///
437 	BookmarksSection bookmarks_;
438 	///
439 	LastCommandsSection last_commands;
440 	///
441 	AuthFilesSection auth_files;
442 	///
443 	ShellEscapeSection shellescape_files;
444 };
445 
446 /// This is a singleton class. Get the instance.
447 /// Implemented in LyX.cpp.
448 Session & theSession();
449 
450 } // namespace lyx
451 
452 #endif
453