]> git.lyx.org Git - lyx.git/blob - src/buffer.h
1fb0bbff59cff8cc8753e3b331a06c3da4ab3824
[lyx.git] / src / buffer.h
1 // -*- C++ -*-
2 /* This file is part of
3  * ====================================================== 
4  * 
5  *           LyX, The Document Processor         
6  *           Copyright 1995 Matthias Ettrich
7  *
8  *           This file is Copyleft 1996
9  *           Lars Gullik Bjønnes
10  *
11  * ====================================================== */
12  
13 // Change Log:
14 // =========== 
15 // 23/03/98   Heinrich Bauer (heinrich.bauer@t-mobil.de)
16 // Spots marked "changed Heinrich Bauer, 23/03/98" modified due to the
17 // following bug: dvi file export did not work after printing (or previewing)
18 // and vice versa as long as the same file was concerned. This happened
19 // every time the LyX-file was left unchanged between the two actions mentioned
20 // above.
21
22 #ifndef BUFFER_H
23 #define BUFFER_H
24
25 #ifdef __GNUG__
26 #pragma interface
27 #endif
28
29 #include "LString.h"
30
31 #include "BufferView.h"
32 #include "lyxvc.h"
33 #include "bufferparams.h"
34 #include "texrow.h"
35
36
37 class LyXRC;
38 class TeXErrors;
39 class LaTeXFeatures;
40 class auto_mem_buffer;
41 class Language;
42
43 ///
44 struct DEPCLEAN {
45         ///
46         bool clean;
47         ///
48         string master;
49         ///
50         DEPCLEAN * next;
51 };
52
53 /** The buffer object.
54   The is is the buffer object. It contains all the informations about
55   a document loaded into LyX. I am not sure if the class is complete or
56   minimal, probably not.
57   */
58 class Buffer {
59 public:
60         ///
61         explicit Buffer(string const & file, bool b = false);
62         
63         ///
64         ~Buffer();
65
66         /** save the buffer's parameters as user default
67             This function saves a file #user_lyxdir/templates/defaults.lyx# 
68             which parameters are those of the current buffer. This file
69             is used as a default template when creating a new
70             file. Returns #true# on success.
71         */
72         bool saveParamsAsDefaults();
73
74         /** High-level interface to buffer functionality.
75             This function parses a command string and executes it
76         */
77         bool Dispatch(string const & command);
78
79         /// Maybe we know the function already by number...
80         bool Dispatch(int ac, string const & argument);
81
82         /// and have an xtl buffer to work with.
83         bool Dispatch(int, auto_mem_buffer &);
84
85         /// should be changed to work for a list.
86         void resize();
87         ///
88         void resizeInsets(BufferView *);
89
90         /// Update window titles of all users
91         void updateTitles() const;
92
93         /// Reset autosave timers for all users
94         void resetAutosaveTimers() const;
95
96         /** Adds the BufferView to the users list.
97             Later this func will insert the #BufferView# into a real list,
98             not just setting a pointer.
99         */
100         void addUser(BufferView * u) { users = u; }
101
102         /** Removes the #BufferView# from the users list.
103             Since we only can have one at the moment, we just reset it.
104         */
105         void delUser(BufferView *) { users = 0; }
106         
107         ///
108         void redraw() {
109                 users->redraw(); 
110                 users->fitCursor(users->text); 
111                 //users->updateScrollbar();
112         }
113
114         ///
115         void loadAutoSaveFile();
116         
117         /** Reads a file. 
118             @param par if != 0 insert the file.
119             @return #false# if method fails.
120         */
121         bool readFile(LyXLex &, LyXParagraph * par = 0);
122         
123         /** Reads a file without header.
124             @param par if != 0 insert the file.
125             @return false if file is not completely read.
126         */
127         bool readLyXformat2(LyXLex &, LyXParagraph * par = 0);
128
129         /// This parses a single LyXformat-Token.
130         bool parseSingleLyXformat2Token(LyXLex &, LyXParagraph *& par,
131                                         LyXParagraph *& return_par,
132                                         string const & token, int & pos,
133                                         char & depth, LyXFont &
134 #ifndef NEW_INSETS
135                                         ,LyXParagraph::footnote_flag &,
136                                         LyXParagraph::footnote_kind &
137 #endif
138                 );
139 private:
140         /// Parse a single inset.
141         void readInset(LyXLex &, LyXParagraph *& par, int & pos, LyXFont &);
142 public:
143         /** Save file
144             Takes care of auto-save files and backup file if requested.
145             Returns #true# if the save is successful, #false# otherwise.
146         */
147         bool save() const;
148         
149         /// Write file. Returns #false# if unsuccesful.
150         bool writeFile(string const &, bool) const;
151         
152         ///
153         void writeFileAscii(string const & , int);
154         ///
155         void writeFileAscii(std::ostream &, int);
156         ///
157         string const asciiParagraph(LyXParagraph const *,
158                                     unsigned int linelen) const;
159         ///
160         void makeLaTeXFile(string const & filename,
161                            string const & original_path,
162                            bool nice, bool only_body = false);
163         /** LaTeX all paragraphs from par to endpar.
164             @param endpar if == 0 then to the end
165         */
166         void latexParagraphs(std::ostream & os, LyXParagraph * par,
167                              LyXParagraph * endpar, TexRow & texrow) const;
168
169         ///
170         int runChktex();
171
172         ///
173         void makeLinuxDocFile(string const & filename,
174                               bool nice, bool only_body = false);
175         ///
176         void makeDocBookFile(string const & filename,
177                              bool nice, bool only_body = false);
178
179         /// returns the main language for the buffer (document)
180         Language const * GetLanguage() const {
181                 return params.language;
182         }
183         
184         ///
185         bool isLyxClean() const { return lyx_clean; }
186         
187         ///
188         bool isBakClean() const { return bak_clean; }
189         
190         ///
191         bool isDepClean(string const & name) const;
192         
193         ///
194         void markLyxClean() const { 
195                 if (!lyx_clean) {
196                         lyx_clean = true; 
197                         updateTitles();
198                 }
199                 // if the .lyx file has been saved, we don't need an
200                 // autosave 
201                 bak_clean = true;
202         }
203
204         ///
205         void markBakClean() { bak_clean = true; }
206         
207         ///
208         void markDepClean(string const & name);
209         
210         ///
211         void setUnnamed(bool flag=true) { unnamed = flag; }
212
213         ///
214         bool isUnnamed() { return unnamed; }
215
216         ///
217         void markDirty() {
218                 if (lyx_clean) {
219                         lyx_clean = false;
220                         updateTitles();
221                 }
222                 bak_clean = false;
223                 DEPCLEAN * tmp = dep_clean;
224                 while (tmp) {
225                         tmp->clean = false;
226                         tmp = tmp->next;
227                 }
228         }
229
230         ///
231         string const & fileName() const { return filename; }
232
233         /** A transformed version of the file name, adequate for LaTeX  
234             The path is stripped if no_path is true (default)
235         */
236         string const getLatexName(bool no_path = true) const;
237
238         /// Change name of buffer. Updates "read-only" flag.
239         void setFileName(string const & newfile);
240
241         /// Name of the document's parent
242         void setParentName(string const &);
243
244         /// Is buffer read-only?
245         bool isReadonly() const { return read_only; }
246
247         /// Set buffer read-only flag
248         void setReadonly(bool flag = true);
249
250         /// returns #true# if the buffer contains a LaTeX document
251         bool isLatex() const;
252         /// returns #true# if the buffer contains a LinuxDoc document
253         bool isLinuxDoc() const;
254         /// returns #true# if the buffer contains a DocBook document
255         bool isDocBook() const;
256         /** returns #true# if the buffer contains either a LinuxDoc
257             or DocBook document */
258         bool isSGML() const;
259         /// returns #true# if the buffer contains a Wed document
260         bool isLiterate() const;
261
262         ///
263         void setPaperStuff();
264
265         /** Validate a buffer for LaTeX.
266             This validates the buffer, and returns a struct for use by
267             #makeLaTeX# and others. Its main use is to figure out what
268             commands and packages need to be included in the LaTeX file.
269             It (should) also check that the needed constructs are there
270             (i.e. that the \refs points to coresponding \labels). It
271             should perhaps inset "error" insets to help the user correct
272             obvious mistakes.
273         */
274         void validate(LaTeXFeatures &) const;
275
276         ///
277         string const getIncludeonlyList(char delim = ',');
278         ///
279         std::vector<std::pair<string,string> > const getBibkeyList();
280         ///
281         struct TocItem {
282                 ///
283                 LyXParagraph * par;
284                 ///
285                 int depth;
286                 ///
287                 string str;
288         };
289         ///
290         enum TocType {
291                 ///
292                 TOC_TOC = 0,
293                 ///
294                 TOC_LOF,
295                 ///
296                 TOC_LOT,
297                 ///
298                 TOC_LOA
299         };
300         ///
301         std::vector<std::vector<TocItem> > const getTocList();
302         ///
303         std::vector<string> const getLabelList();
304
305         /** This will clearly have to change later. Later we can have more
306             than one user per buffer. */
307         BufferView * getUser() const { return users; }
308
309         ///
310         void ChangeLanguage(Language const * from, Language const * to);
311         ///
312         bool isMultiLingual();
313
314         /// Does this mean that this is buffer local?
315         UndoStack undostack;
316         
317         /// Does this mean that this is buffer local? 
318         UndoStack redostack;
319         
320         ///
321         BufferParams params;
322         
323         /** is a list of paragraphs.
324          */
325         LyXParagraph * paragraph;
326
327         /// RCS object
328         LyXVC lyxvc;
329
330         /// where the temporaries go if we want them
331         string tmppath;
332
333         ///
334         string filepath;
335
336         /** While writing as LaTeX, tells whether we are
337             doing a 'nice' LaTeX file */
338         bool niceFile;
339
340         /// Used when typesetting to place errorboxes.
341         TexRow texrow;
342 private:
343 #ifndef NEW_INSETS
344         ///
345         void linuxDocHandleFootnote(std::ostream & os,
346                                     LyXParagraph * & par, int depth);
347 #endif
348         ///
349         void DocBookHandleCaption(std::ostream & os, string & inner_tag,
350                                   int depth, int desc_on,
351                                   LyXParagraph * & par);
352 #ifndef NEW_INSETS
353         ///
354         void DocBookHandleFootnote(std::ostream & os,
355                                    LyXParagraph * & par, int depth);
356 #endif
357         ///
358         void sgmlOpenTag(std::ostream & os, int depth,
359                          string const & latexname) const;
360         ///
361         void sgmlCloseTag(std::ostream & os, int depth,
362                           string const & latexname) const;
363         ///
364         void LinuxDocError(LyXParagraph * par, int pos,
365                            string const & message);
366         ///
367         void SimpleLinuxDocOnePar(std::ostream & os, LyXParagraph * par,
368                                   int desc_on, int depth);
369         ///
370         void SimpleDocBookOnePar(std::ostream &, string & extra,
371                                  LyXParagraph * par, int & desc_on,
372                                  int depth);
373
374         /// LinuxDoc.
375         void push_tag(std::ostream & os, string const & tag,
376                       int & pos, char stack[5][3]);
377         
378         /// LinuxDoc.
379         void pop_tag(std::ostream & os, string const & tag,
380                      int & pos, char stack[5][3]);
381
382         /// is save needed
383         mutable bool lyx_clean;
384         
385         /// is autosave needed
386         mutable bool bak_clean;
387         
388         /// is this a unnamed file (New...)
389         bool unnamed;
390
391         /// is regenerating #.tex# necessary
392         DEPCLEAN * dep_clean;
393
394         /// buffer is r/o
395         bool read_only;
396
397         /// name of the file the buffer is associated with.
398         string filename;
399
400         /// Format number of buffer
401         float format;
402         
403         /** A list of views using this buffer.
404             Why not keep a list of the BufferViews that use this buffer?
405
406             At least then we don't have to do a lot of magic like:
407             #buffer->lyx_gui->bufferview->updateLayoutChoice#. Just ask each
408             of the buffers in the list of users to do a #updateLayoutChoice#.
409         */
410         BufferView * users;
411
412 public:
413         ///
414         class inset_iterator {
415         public:
416                 typedef input_iterator_tag iterator_category;
417                 typedef Inset value_type;
418                 typedef ptrdiff_t difference_type;
419                 typedef Inset * pointer;
420                 typedef Inset & reference;
421                 
422                 
423                 ///
424                 inset_iterator() : par(0) /*, it(0)*/ {}
425                 //
426                 inset_iterator(LyXParagraph * paragraph) : par(paragraph) {
427                         SetParagraph();
428                 }
429                 ///
430                 inset_iterator(LyXParagraph * paragraph,
431                                LyXParagraph::size_type pos);
432                 ///
433                 inset_iterator & operator++() { // prefix ++
434                         if (par) {
435                                 ++it;
436                                 if (it == par->inset_iterator_end()) {
437                                         par = par->next;
438                                         SetParagraph();
439                                 }
440                         }
441                         return *this;
442                 }
443                 ///
444                 inset_iterator operator++(int) { // postfix ++
445                         inset_iterator tmp(par, it.getPos());
446                         if (par) {
447                                 ++it;
448                                 if (it == par->inset_iterator_end()) {
449                                         par = par->next;
450                                         SetParagraph();
451                                 }
452                         }
453                         return tmp;
454                 }
455                 ///
456                 Inset * operator*() { return *it; }
457                 
458                 ///
459                 LyXParagraph * getPar() { return par; }
460                 ///
461                 LyXParagraph::size_type getPos() const { return it.getPos(); }
462                 ///
463                 friend
464                 bool operator==(inset_iterator const & iter1,
465                                 inset_iterator const & iter2);
466                 //
467                 //friend
468                 //bool operator!=(inset_iterator const & iter1,
469                 //              inset_iterator const & iter2);
470         private:
471                 ///
472                 void SetParagraph();
473                 ///
474                 LyXParagraph * par;
475                 ///
476                 LyXParagraph::inset_iterator it;
477         };
478
479         ///
480         inset_iterator inset_iterator_begin() {
481                 return inset_iterator(paragraph);
482         }
483         ///
484         inset_iterator inset_iterator_end() {
485                 return inset_iterator();
486         }
487 };
488
489
490 inline  
491 void Buffer::setParentName(string const & name)
492 {
493         params.parentname = name;    
494 }
495
496 ///
497 inline
498 bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b) {
499         return a.par == b.par && a.str == b.str;
500         // No need to compare depth.
501 }
502
503
504 ///
505 inline
506 bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b) {
507         return !(a == b);
508         // No need to compare depth.
509 }
510
511 ///
512 inline
513 bool operator==(Buffer::inset_iterator const & iter1,
514                 Buffer::inset_iterator const & iter2) {
515         return iter1.par == iter2.par
516                 && (iter1.par == 0 || iter1.it == iter2.it);
517 }
518
519 ///
520 inline
521 bool operator!=(Buffer::inset_iterator const & iter1,
522                 Buffer::inset_iterator const & iter2) {
523         return !(iter1 == iter2);
524 }
525 #endif
526