]> git.lyx.org Git - lyx.git/blob - src/Session.h
* restore lastfile feature.
[lyx.git] / src / Session.h
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 <boost/utility.hpp>
20 #include <boost/tuple/tuple.hpp>
21
22 #include <string>
23 #include <deque>
24 #include <vector>
25 #include <map>
26
27 // used by at least frontends/qt2/QPref.C
28 const long maxlastfiles = 20;
29
30 /** This session file maintains
31   1. the latest documents loaded (lastfiles)
32   2. cursor positions of files closed (lastfilepos)
33   3. opened files when a lyx session is closed (lastopened)
34   4. bookmarks
35   5. general purpose session info in the form of key/value pairs
36  */
37 namespace lyx {
38
39 /** base class for all sections in the session file
40 */
41 class SessionSection : boost::noncopyable {
42
43 public:
44         ///
45         virtual ~SessionSection() {}
46
47         /// read section from std::istream
48         virtual void read(std::istream & is) = 0;
49
50         /// write to std::ostream
51         virtual void write(std::ostream & os) const = 0;
52 };
53
54
55 class LastFilesSection : SessionSection
56 {
57 public:
58         ///
59         typedef std::deque<support::FileName> LastFiles;
60
61 public:
62         ///
63         explicit LastFilesSection(unsigned int num = 4);
64
65         ///
66         void read(std::istream & is);
67
68         ///
69         void write(std::ostream & os) const;
70
71         /// Return lastfiles container (deque)
72         LastFiles const lastFiles() const { return lastfiles; }
73
74         /** Insert #file# into the lastfile dequeue.
75             This funtion inserts #file# into the last files list. If the file
76             already exists it is moved to the top of the list, else exist it
77             is placed on the top of the list. If the list is full the last
78             file in the list is popped from the end.
79             @param file the file to insert in the lastfile list.
80         */
81         void add(support::FileName const & file);
82
83 private:
84         /// Default number of lastfiles.
85         unsigned int const default_num_last_files;
86
87         /// Max number of lastfiles.
88         unsigned int const absolute_max_last_files;
89
90         /// a list of lastfiles
91         LastFiles lastfiles;
92
93         /// number of files in the lastfiles list.
94         unsigned int num_lastfiles;
95
96         /** Used by the constructor to set the number of stored last files.
97             @param num the number of lastfiles to set.
98         */
99         void setNumberOfLastFiles(unsigned int num);
100 };
101
102
103 class LastOpenedSection : SessionSection
104 {
105 public:
106         ///
107         typedef std::vector<support::FileName> LastOpened;
108
109 public:
110         ///
111         void read(std::istream & is);
112
113         ///
114         void write(std::ostream & os) const;
115
116         /// Return lastopened container (vector)
117         LastOpened const getfiles() const { return lastopened; }
118
119         /** add file to lastopened file list
120             @param file filename to add
121         */
122         void add(support::FileName const & file);
123
124         /** clear lastopened file list
125          */
126         void clear();
127
128 private:
129         /// a list of lastopened files
130         LastOpened lastopened;
131 };
132
133
134 class LastFilePosSection : SessionSection
135 {
136 public:
137         ///
138         typedef boost::tuple<pit_type, pos_type> FilePos;
139
140         ///
141         typedef std::map<support::FileName, FilePos> FilePosMap;
142
143 public:
144         ///
145         LastFilePosSection() : num_lastfilepos(100) {}
146
147         ///
148         void read(std::istream & is);
149
150         ///
151         void write(std::ostream & os) const;
152
153         /** add cursor position to the fname entry in the filepos map
154             @param fname file entry for which to save position information
155             @param pos position of the cursor when the file is closed.
156         */
157         void save(support::FileName const & fname, FilePos pos);
158
159         /** load saved cursor position from the fname entry in the filepos map
160             @param fname file entry for which to load position information
161         */
162         FilePos load(support::FileName const & fname) const;
163
164 private:
165         /// default number of lastfilepos to save */
166         unsigned int const num_lastfilepos;
167
168
169         /// a map of file positions
170         FilePosMap lastfilepos;
171 };
172
173
174 class BookmarksSection : SessionSection
175 {
176 public:
177         /// A bookmark is composed of three parts
178         /// 1. filename
179         /// 2. bottom (whole document) level pit and pos, used to (inaccurately) save/restore a bookmark
180         /// 3. top level id and pos, used to accurately locate bookmark when lyx is running
181         /// top and bottom level information sometimes needs to be sync'ed. In particular,
182         /// top_id is determined when a bookmark is restored from session; and
183         /// bottom_pit and bottom_pos are determined from top_id when a bookmark
184         /// is save to session. (What a mess! :-)
185         ///
186         /// TODO: bottom level pit and pos will be replaced by StableDocIterator
187         class Bookmark {
188         public:
189                 /// Filename
190                 support::FileName filename;
191                 /// Bottom level cursor pit, will be saved/restored by .lyx/session
192                 pit_type bottom_pit;
193                 /// Bottom level cursor position, will be saved/restore by .lyx/session
194                 pos_type bottom_pos;
195                 /// Top level cursor id, used to lcoate bookmarks for opened files
196                 int top_id;
197                 /// Top level cursor position within a paragraph
198                 pos_type top_pos;
199                 ///
200                 Bookmark() : bottom_pit(0), bottom_pos(0), top_id(0), top_pos(0) {}
201                 ///
202                 Bookmark(support::FileName const & f, pit_type pit, pos_type pos, int id, pos_type tpos)
203                         : filename(f), bottom_pit(pit), bottom_pos(pos), top_id(id), top_pos(tpos) {}
204                 /// set bookmark top_id, this is because newly loaded bookmark
205                 /// may have zero par_id and par_pit can change during editing, see bug 3092
206                 void updatePos(pit_type pit, pos_type pos, int id) {
207                         bottom_pit = pit;
208                         bottom_pos = pos;
209                         top_id = id;
210                 }
211         };
212
213         ///
214         typedef std::vector<Bookmark> BookmarkList;
215
216 public:
217         /// constructor, set max_bookmarks
218         /// allow 9 regular bookmarks, bookmark 0 is temporary
219         BookmarksSection() : bookmarks(10), max_bookmarks(9) {}
220
221         /// Save the current position as bookmark
222         void save(support::FileName const & fname, pit_type bottom_pit, pos_type bottom_pos,
223                 int top_id, pos_type top_pos, unsigned int idx);
224
225         /// return bookmark 0-9, bookmark 0 is the temporary bookmark
226         Bookmark const & bookmark(unsigned int i) const;
227
228         /// does the given bookmark have a saved position ?
229         bool isValid(unsigned int i) const;
230
231         ///
232         unsigned int size() const { return max_bookmarks; }
233
234         /// clear all bookmarks
235         void clear();
236
237         ///
238         void read(std::istream & is);
239
240         ///
241         void write(std::ostream & os) const;
242
243         /** return bookmark list. Non-const container is used since
244                 bookmarks will be cleaned after use.
245         */
246         BookmarkList & load() { return bookmarks; }
247
248 private:
249
250         /// a list of bookmarks
251         BookmarkList bookmarks;
252
253         ///
254         unsigned int const max_bookmarks;
255 };
256
257
258 class ToolbarSection : SessionSection
259 {
260 public:
261         /// information about a toolbar, not all information can be
262         /// saved/restored by all frontends, but this class provides
263         /// a superset of things that can be managed by session.
264         class ToolbarInfo
265         {
266         public:
267                 ///
268                 ToolbarInfo() :
269                         state(ON), location(NOTSET), posx(0), posy(0) { }
270                 ///
271                 ToolbarInfo(int s, int loc, int x=0, int y=0) :
272                         state(static_cast<State>(s)),
273                         location(static_cast<Location>(loc)),
274                         posx(x),
275                         posy(y)
276                         { }
277
278         public:
279                 enum State {
280                         ON,
281                         OFF,
282                         AUTO
283                 };
284
285                 /// on/off/auto
286                 State state;
287
288                 /// location: this can be intepreted differently.
289                 enum Location {
290                         TOP,
291                         BOTTOM,
292                         LEFT,
293                         RIGHT,
294                         NOTSET
295                 };
296
297                 Location location;
298
299                 /// x-position of the toolbar
300                 int posx;
301
302                 /// y-position of the toolbar
303                 int posy;
304
305                 /// potentially, icons
306         };
307
308         typedef boost::tuple<std::string, ToolbarInfo> ToolbarItem;
309
310         /// info for each toolbar
311         typedef std::vector<ToolbarItem> ToolbarList;
312
313
314 public:
315         ///
316         void read(std::istream & is);
317
318         ///
319         void write(std::ostream & os) const;
320
321         /// return reference to toolbar info, create a new one if needed
322         ToolbarInfo & load(std::string const & name);
323
324         /// toolbar begin
325         ToolbarList::const_iterator begin() { return toolbars.begin(); }
326
327         /// toolbar end
328         ToolbarList::const_iterator end() { return toolbars.end(); }
329
330 private:
331         /// toolbar information
332         ToolbarList toolbars;
333 };
334
335 /// comparison operator to sort toolbars, the rules are:
336 ///         ON before OFF
337 ///     TOP < BOTTOM < LEFT < RIGHT
338 ///     Line at each side
339 ///     order in each line
340 bool operator< (ToolbarSection::ToolbarItem const & a, ToolbarSection::ToolbarItem const & b);
341
342
343 class SessionInfoSection : SessionSection
344 {
345 public:
346         ///
347         typedef std::map<std::string, std::string> MiscInfo;
348
349 public:
350         ///
351         void read(std::istream & is);
352
353         ///
354         void write(std::ostream & os) const;
355
356         /** set session info
357                 @param key key of the value to store
358                 @param value value, a string without newline ('\n')
359         */
360         void save(std::string const & key, std::string const & value);
361
362         /** load session info
363                 @param key a key to extract value from the session file
364                 @param release whether or not clear the value. Default to true
365                         since most of such values are supposed to be used only once.
366         */
367         std::string const load(std::string const & key, bool release = true);
368
369 private:
370         /// a map to save session info
371         MiscInfo sessioninfo;
372 };
373
374
375 class Session : boost::noncopyable {
376
377 public:
378         /** Read the session file.
379             @param num length of lastfiles
380         */
381         explicit Session(unsigned int num = 4);
382
383         /** Write the session file.
384         */
385         void writeFile() const;
386
387         ///
388         LastFilesSection & lastFiles() { return last_files; }
389
390         ///
391         LastFilesSection const & lastFiles() const { return last_files; }
392
393         ///
394         LastOpenedSection & lastOpened() { return last_opened; }
395
396         ///
397         LastOpenedSection const & lastOpened() const { return last_opened; }
398
399         ///
400         LastFilePosSection & lastFilePos() { return last_file_pos; }
401
402         ///
403         LastFilePosSection const & lastFilePos() const { return last_file_pos; }
404
405         ///
406         BookmarksSection & bookmarks() { return bookmarks_; }
407
408         ///
409         BookmarksSection const & bookmarks() const { return bookmarks_; }
410
411         ///
412         ToolbarSection & toolbars() { return toolbars_; }
413
414         ///
415         ToolbarSection const & toolbars() const { return toolbars_; }
416
417         ///
418         SessionInfoSection & sessionInfo() { return session_info; }
419
420         ///
421         SessionInfoSection const & sessionInfo() const { return session_info; }
422
423 private:
424         /// file to save session, determined in the constructor.
425         support::FileName session_file;
426
427         /** Read the session file.
428             Reads the #.lyx/session# at the beginning of the LyX session.
429             This will read the session file (usually #.lyx/session#).
430             @param file the file containing the session.
431         */
432         void readFile();
433
434         ///
435         LastFilesSection last_files;
436
437         ///
438         LastOpenedSection last_opened;
439
440         ///
441         LastFilePosSection last_file_pos;
442
443         ///
444         BookmarksSection bookmarks_;
445
446         ///
447         ToolbarSection toolbars_;
448
449         ///
450         SessionInfoSection session_info;
451 };
452
453 }
454
455 #endif