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