]> git.lyx.org Git - lyx.git/blob - src/buffer.h
last fix *NOT*
[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                 if (users) {
93                         users->resize();
94                 }
95         }
96
97         /// Update window titles of all users
98         void updateTitles() const;
99
100         /// Reset autosave timers for all users
101         void resetAutosaveTimers() const;
102
103         /** Adds the BufferView to the users list.
104             Later this func will insert the BufferView into a real list,
105             not just setting a pointer.
106         */
107         void addUser(BufferView * u) { users = u; }
108
109         /** Removes the BufferView from the users list.
110             Since we only can have one at the moment, we just reset it.
111         */
112         void delUser(BufferView *) { users = 0; }
113         
114         ///
115         void redraw() {
116                 users->redraw(); 
117                 users->fitCursor(); 
118                 //users->updateScrollbar();
119         }
120
121         ///
122         void loadAutoSaveFile();
123         
124         /** Reads a file. 
125             Returns false if it fails.
126             If par is given, the file is inserted. */
127         bool readFile(LyXLex &, LyXParagraph * par = 0);
128         
129         /** Reads a file without header.
130             Returns false, if file is not completely read.
131             If par is given, the file is inserted. */
132         bool readLyXformat2(LyXLex &, LyXParagraph * par = 0);
133
134         /* This parses a single LyXformat-Token */
135         bool parseSingleLyXformat2Token(LyXLex &, LyXParagraph *& par,
136                                         LyXParagraph *& return_par,
137                                         string const & token, int & pos,
138                                         char & depth, LyXFont &,
139                                         LyXParagraph::footnote_flag &,
140                                         LyXParagraph::footnote_kind &);
141
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         //
159         // LaTeX all paragraphs from par to endpar,
160         // if endpar == 0 then to the end
161         //
162         void latexParagraphs(std::ostream & os, LyXParagraph *par,
163                              LyXParagraph *endpar, TexRow & texrow) const;
164
165         ///
166         int runLaTeX();
167
168         ///
169         int runLiterate();
170
171         ///
172         int buildProgram();
173
174         ///
175         int runChktex();
176
177         ///
178         void makeLinuxDocFile(string const & filename, int column);
179         ///
180         void makeDocBookFile(string const & filename, int column);
181
182         /// returns the main language for the buffer (document)
183         string GetLanguage() const {
184                 return params.language;
185         }
186         
187         ///
188         bool isLyxClean() const { return lyx_clean; }
189         
190         /// changed Heinrich Bauer, 23/03/98
191         bool isDviClean() const;
192         
193         ///
194         bool isNwClean() const { return nw_clean; }
195        
196         ///
197         bool isBakClean() const { return bak_clean; }
198         
199         ///
200         bool isDepClean(string const & name) const;
201         
202         ///
203         void markLyxClean() const { 
204                 if (!lyx_clean) {
205                         lyx_clean = true; 
206                         updateTitles();
207                 }
208                 // if the .lyx file has been saved, we don't need an
209                 // autosave 
210                 bak_clean = true;
211         }
212
213         /// changed Heinrich Bauer, 23/03/98
214         void markDviClean();
215         
216         ///
217         void markNwClean() { nw_clean = true; }
218        
219         ///
220         void markBakClean() { bak_clean = true; }
221         
222         ///
223         void markDepClean(string const & name);
224         
225         ///
226         void markDviDirty();
227         
228         ///
229         void markNwDirty() { nw_clean = false; }
230        
231         ///
232         void markDirty() {
233                 if (lyx_clean) {
234                         lyx_clean = false;
235                         updateTitles();
236                 }
237                 dvi_clean_tmpd = false;
238                 dvi_clean_orgd = false;
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         ///
360         void linuxDocHandleFootnote(std::ostream & os,
361                                     LyXParagraph * & par, int const depth);
362         ///
363         void DocBookHandleCaption(std::ostream & os, string & inner_tag,
364                                   int const depth, int desc_on,
365                                   LyXParagraph * & par);
366         ///
367         void DocBookHandleFootnote(std::ostream & os,
368                                    LyXParagraph * & par, int const depth);
369         ///
370         void sgmlOpenTag(std::ostream & os, int depth,
371                          string const & latexname) const;
372         ///
373         void sgmlCloseTag(std::ostream & os, int depth,
374                           string const & latexname) const;
375         ///
376         void LinuxDocError(LyXParagraph * par, int pos, char const * message);
377         ///
378         void SimpleLinuxDocOnePar(std::ostream & os, LyXParagraph * par,
379                                   int desc_on, int const depth);
380         ///
381         void SimpleDocBookOnePar(std::ostream &, string & extra,
382                                  LyXParagraph * par, int & desc_on,
383                                  int const depth);
384
385         /// LinuxDoc.
386         void push_tag(std::ostream & os, char const * tag,
387                       int & pos, char stack[5][3]);
388         
389         /// LinuxDoc.
390         void pop_tag(std::ostream & os, char const * tag,
391                      int & pos, char stack[5][3]);
392
393 #if 0
394         ///
395         void RoffAsciiTable(std::ostream &, LyXParagraph * par);
396 #endif
397         
398         /// is save needed
399         mutable bool lyx_clean;
400         
401         /// is autosave needed
402         mutable bool bak_clean;
403         
404         /** do we need to run LaTeX, changed 23/03/98, Heinrich Bauer
405             We have to distinguish between TeX-runs executed in the original
406             directory (in which the original LyX-file resides) and TeX-runs
407             executed in a temporary directory. The first situation is valid
408             for a dvi-export, the latter one for printing or previewing. */
409         bool dvi_clean_orgd;
410         bool dvi_clean_tmpd;
411
412         /// do we need to run weave/tangle
413         bool nw_clean;
414
415         /// is regenerating .tex necessary
416         DEPCLEAN * dep_clean;
417
418         /// buffer is r/o
419         bool read_only;
420
421         /// name of the file the buffer is associated with.
422         string filename;
423
424         /// Format number of buffer
425         float format;
426         
427         /** A list of views using this buffer.
428             Why not keep a list of the BufferViews that use this buffer?
429
430             At least then we don't have to do a lot of magic like:
431             buffer->lyx_gui->bufferview->updateLayoutChoice. Just ask each
432             of the buffers in the list of users to do a updateLayoutChoice.
433         */
434         BufferView * users;
435
436 public:
437         class inset_iterator {
438         public:
439                 inset_iterator() : par(0) /*, it(0)*/ {}
440                 inset_iterator(LyXParagraph * paragraph) : par(paragraph) {
441                         SetParagraph();
442                 }
443                 inset_iterator(LyXParagraph * paragraph, LyXParagraph::size_type pos);
444                 inset_iterator & operator++() {
445                         if (par) {
446                                 ++it;
447                                 if (it == par->inset_iterator_end()) {
448                                         par = par->next;
449                                         SetParagraph();
450                                 }
451                         }
452                         return *this;
453                 }
454                 Inset * operator*() {return *it; }
455                 LyXParagraph * getPar() { return par; }
456                 LyXParagraph::size_type getPos() {return it.getPos(); }
457                 friend
458                 bool operator==(inset_iterator const & iter1,
459                                 inset_iterator const & iter2) {
460                         return iter1.par == iter2.par
461                                 && (iter1.par == 0 || iter1.it == iter2.it);
462                 }
463                 friend
464                 bool operator!=(inset_iterator const & iter1,
465                                 inset_iterator const & iter2) {
466                         return !(iter1 == iter2);
467                 }
468         private:
469                 void SetParagraph();
470                 LyXParagraph * par;
471                 LyXParagraph::inset_iterator it;
472         };
473
474         ///
475         inset_iterator inset_iterator_begin() {
476                 return inset_iterator(paragraph);
477         }
478         ///
479         inset_iterator inset_iterator_end() {
480                 return inset_iterator();
481         }
482 };
483
484
485 inline  
486 void Buffer::setParentName(string const & name)
487 {
488         params.parentname = name;    
489 }
490
491 inline
492 bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b) {
493         return a.par == b.par && a.str == b.str;
494         // No need to compare depth.
495 }
496
497
498 inline
499 bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b) {
500         return !(a == b);
501         // No need to compare depth.
502 }
503
504 #endif