]> git.lyx.org Git - lyx.git/blob - src/buffer.h
6a3117959f7fcbd9a956257501e2969414becaf5
[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         ///
191         bool isNwClean() const { return nw_clean; }
192        
193         ///
194         bool isBakClean() const { return bak_clean; }
195         
196         ///
197         bool isDepClean(string const & name) const;
198         
199         ///
200         void markLyxClean() const { 
201                 if (!lyx_clean) {
202                         lyx_clean = true; 
203                         updateTitles();
204                 }
205                 // if the .lyx file has been saved, we don't need an
206                 // autosave 
207                 bak_clean = true;
208         }
209
210         ///
211         void markNwClean() { nw_clean = true; }
212        
213         ///
214         void markBakClean() { bak_clean = true; }
215         
216         ///
217         void markDepClean(string const & name);
218         
219         ///
220         void markNwDirty() { nw_clean = false; }
221        
222         ///
223         void markDirty() {
224                 if (lyx_clean) {
225                         lyx_clean = false;
226                         updateTitles();
227                 }
228                 nw_clean = false;
229                 bak_clean = false;
230                 DEPCLEAN * tmp = dep_clean;
231                 while (tmp) {
232                         tmp->clean = false;
233                         tmp = tmp->next;
234                 }
235         }
236
237         ///
238         string const & fileName() const { return filename; }
239
240         /** A transformed version of the file name, adequate for LaTeX  
241             The path is stripped if no_path is true (default) */
242         string getLatexName(bool no_path = true) const;
243
244         /// Change name of buffer. Updates "read-only" flag.
245         void fileName(string const & newfile);
246
247         /// Name of the document's parent
248         void setParentName(string const &);
249
250         /// Is buffer read-only?
251         bool isReadonly() const { return read_only; }
252
253         /// Set buffer read-only flag
254         void setReadonly(bool flag = true);
255
256         /// returns true if the buffer contains a LaTeX document
257         bool isLatex() const;
258         /// returns true if the buffer contains a LinuxDoc document
259         bool isLinuxDoc() const;
260         /// returns true if the buffer contains a DocBook document
261         bool isDocBook() const;
262         /** returns true if the buffer contains either a LinuxDoc
263             or DocBook document */
264         bool isSGML() const;
265         /// returns true if the buffer contains a Wed document
266         bool isLiterate() const;
267
268         ///
269         void setPaperStuff();
270
271         /** Validate a buffer for LaTeX.
272             This validates the buffer, and returns a struct for use by
273             makeLaTeX and others. Its main use is to figure out what
274             commands and packages need to be included in the LaTeX file.
275             It (should) also check that the needed constructs are there
276             (i.e. that the \refs points to coresponding \labels). It
277             should perhaps inset "error" insets to help the user correct
278             obvious mistakes.
279         */
280         void validate(LaTeXFeatures &) const;
281
282         ///
283         string getIncludeonlyList(char delim = ',');
284         ///
285         std::vector<std::pair<string,string> > getBibkeyList();
286         ///
287         struct TocItem {
288                 LyXParagraph * par;
289                 int depth;
290                 string str;
291         };
292         ///
293         enum TocType {
294                 ///
295                 TOC_TOC = 0,
296                 ///
297                 TOC_LOF,
298                 ///
299                 TOC_LOT,
300                 ///
301                 TOC_LOA
302         };
303         ///
304         std::vector<std::vector<TocItem> > getTocList();
305         ///
306         std::vector<string> getLabelList();
307
308         /** This will clearly have to change later. Later we can have more
309             than one user per buffer. */
310         BufferView * getUser() const { return users; }
311
312         ///
313         void ChangeLanguage(Language const * from, Language const * to);
314         ///
315         bool isMultiLingual();
316
317         //@}
318
319         /// Does this mean that this is buffer local?
320         UndoStack undostack;
321         
322         /// Does this mean that this is buffer local? 
323         UndoStack redostack;
324         
325         ///
326         BufferParams params;
327         
328         /** is a list of paragraphs.
329          */
330         LyXParagraph * paragraph;
331
332         /// RCS object
333         LyXVC lyxvc;
334
335         /// where the temporaries go if we want them
336         string tmppath;
337
338         ///
339         string filepath;
340
341         /** While writing as LaTeX, tells whether we are
342             doing a 'nice' LaTeX file */
343         bool niceFile;
344
345         /// Used when typesetting to place errorboxes.
346         TexRow texrow;
347 private:
348         ///
349         void linuxDocHandleFootnote(std::ostream & os,
350                                     LyXParagraph * & par, int const depth);
351         ///
352         void DocBookHandleCaption(std::ostream & os, string & inner_tag,
353                                   int const depth, int desc_on,
354                                   LyXParagraph * & par);
355         ///
356         void DocBookHandleFootnote(std::ostream & os,
357                                    LyXParagraph * & par, int const depth);
358         ///
359         void sgmlOpenTag(std::ostream & os, int depth,
360                          string const & latexname) const;
361         ///
362         void sgmlCloseTag(std::ostream & os, int depth,
363                           string const & latexname) const;
364         ///
365         void LinuxDocError(LyXParagraph * par, int pos, char const * message);
366         ///
367         void SimpleLinuxDocOnePar(std::ostream & os, LyXParagraph * par,
368                                   int desc_on, int const depth);
369         ///
370         void SimpleDocBookOnePar(std::ostream &, string & extra,
371                                  LyXParagraph * par, int & desc_on,
372                                  int const depth);
373
374         /// LinuxDoc.
375         void push_tag(std::ostream & os, char const * tag,
376                       int & pos, char stack[5][3]);
377         
378         /// LinuxDoc.
379         void pop_tag(std::ostream & os, char const * tag,
380                      int & pos, char stack[5][3]);
381
382 #if 0
383         ///
384         void RoffAsciiTable(std::ostream &, LyXParagraph * par);
385 #endif
386         
387         /// is save needed
388         mutable bool lyx_clean;
389         
390         /// is autosave needed
391         mutable bool bak_clean;
392         
393         /// do we need to run weave/tangle
394         bool nw_clean;
395
396         /// is regenerating .tex necessary
397         DEPCLEAN * dep_clean;
398
399         /// buffer is r/o
400         bool read_only;
401
402         /// name of the file the buffer is associated with.
403         string filename;
404
405         /// Format number of buffer
406         float format;
407         
408         /** A list of views using this buffer.
409             Why not keep a list of the BufferViews that use this buffer?
410
411             At least then we don't have to do a lot of magic like:
412             buffer->lyx_gui->bufferview->updateLayoutChoice. Just ask each
413             of the buffers in the list of users to do a updateLayoutChoice.
414         */
415         BufferView * users;
416
417 public:
418         class inset_iterator {
419         public:
420                 inset_iterator() : par(0) /*, it(0)*/ {}
421                 inset_iterator(LyXParagraph * paragraph) : par(paragraph) {
422                         SetParagraph();
423                 }
424                 inset_iterator(LyXParagraph * paragraph, LyXParagraph::size_type pos);
425                 inset_iterator & operator++() {
426                         if (par) {
427                                 ++it;
428                                 if (it == par->inset_iterator_end()) {
429                                         par = par->next;
430                                         SetParagraph();
431                                 }
432                         }
433                         return *this;
434                 }
435                 Inset * operator*() {return *it; }
436                 LyXParagraph * getPar() { return par; }
437                 LyXParagraph::size_type getPos() {return it.getPos(); }
438                 friend
439                 bool operator==(inset_iterator const & iter1,
440                                 inset_iterator const & iter2) {
441                         return iter1.par == iter2.par
442                                 && (iter1.par == 0 || iter1.it == iter2.it);
443                 }
444                 friend
445                 bool operator!=(inset_iterator const & iter1,
446                                 inset_iterator const & iter2) {
447                         return !(iter1 == iter2);
448                 }
449         private:
450                 void SetParagraph();
451                 LyXParagraph * par;
452                 LyXParagraph::inset_iterator it;
453         };
454
455         ///
456         inset_iterator inset_iterator_begin() {
457                 return inset_iterator(paragraph);
458         }
459         ///
460         inset_iterator inset_iterator_end() {
461                 return inset_iterator();
462         }
463 };
464
465
466 inline  
467 void Buffer::setParentName(string const & name)
468 {
469         params.parentname = name;    
470 }
471
472 inline
473 bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b) {
474         return a.par == b.par && a.str == b.str;
475         // No need to compare depth.
476 }
477
478
479 inline
480 bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b) {
481         return !(a == b);
482         // No need to compare depth.
483 }
484
485 #endif