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