]> git.lyx.org Git - lyx.git/blob - src/buffer.h
106ed852be78cc4766b5cd32415d1cc3d76460a4
[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 fileName(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                 ///
417                 inset_iterator() : par(0) /*, it(0)*/ {}
418                 //
419                 inset_iterator(LyXParagraph * paragraph) : par(paragraph) {
420                         SetParagraph();
421                 }
422                 ///
423                 inset_iterator(LyXParagraph * paragraph,
424                                LyXParagraph::size_type pos);
425                 ///
426                 inset_iterator & operator++() {
427                         if (par) {
428                                 ++it;
429                                 if (it == par->inset_iterator_end()) {
430                                         par = par->next;
431                                         SetParagraph();
432                                 }
433                         }
434                         return *this;
435                 }
436                 ///
437                 Inset * operator*() {return *it; }
438                 ///
439                 LyXParagraph * getPar() { return par; }
440                 ///
441                 LyXParagraph::size_type getPos() {return it.getPos(); }
442                 ///
443                 friend
444                 bool operator==(inset_iterator const & iter1,
445                                 inset_iterator const & iter2);
446                 //
447                 //friend
448                 //bool operator!=(inset_iterator const & iter1,
449                 //              inset_iterator const & iter2);
450         private:
451                 ///
452                 void SetParagraph();
453                 ///
454                 LyXParagraph * par;
455                 ///
456                 LyXParagraph::inset_iterator it;
457         };
458
459         ///
460         inset_iterator inset_iterator_begin() {
461                 return inset_iterator(paragraph);
462         }
463         ///
464         inset_iterator inset_iterator_end() {
465                 return inset_iterator();
466         }
467 };
468
469
470 inline  
471 void Buffer::setParentName(string const & name)
472 {
473         params.parentname = name;    
474 }
475
476 ///
477 inline
478 bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b) {
479         return a.par == b.par && a.str == b.str;
480         // No need to compare depth.
481 }
482
483
484 ///
485 inline
486 bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b) {
487         return !(a == b);
488         // No need to compare depth.
489 }
490
491 ///
492 inline
493 bool operator==(Buffer::inset_iterator const & iter1,
494                 Buffer::inset_iterator const & iter2) {
495         return iter1.par == iter2.par
496                 && (iter1.par == 0 || iter1.it == iter2.it);
497 }
498
499 ///
500 inline
501 bool operator!=(Buffer::inset_iterator const & iter1,
502                 Buffer::inset_iterator const & iter2) {
503         return !(iter1 == iter2);
504 }
505 #endif
506