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