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