]> git.lyx.org Git - lyx.git/blob - src/buffer.h
Applied Angus patch to compile on DEC C++ and to avoid name clashes
[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 Language;
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   \author Lars Gullik Bjønnes
57   */
58 class Buffer {
59 public:
60         /// What type of log will \c getLogName() return?
61         enum LogType {
62                 latexlog, ///< LaTeX log
63                 buildlog  ///< Literate build log
64         };
65
66         /** Constructor
67             \param file
68             \param b  optional \c false by default
69         */
70         explicit Buffer(string const & file, bool b = false);
71         
72         /// Destrucotr
73         ~Buffer();
74
75         /** Save the buffer's parameters as user default.
76             This function saves a file \c user_lyxdir/templates/defaults.lyx
77             which parameters are those of the current buffer. This file
78             is used as a default template when creating a new
79             file. Returns \c true on success.
80         */
81         bool saveParamsAsDefaults();
82
83         /** High-level interface to buffer functionality.
84             This function parses a command string and executes it
85         */
86         bool Dispatch(string const & command);
87
88         /// Maybe we know the function already by number...
89         bool Dispatch(int ac, string const & argument);
90
91         /// Should be changed to work for a list.
92         void resize();
93         /// 
94         void resizeInsets(BufferView *);
95
96         /// Update window titles of all users.
97         void updateTitles() const;
98
99         /// Reset autosave timers for all users.
100         void resetAutosaveTimers() const;
101
102         /** Adds the BufferView to the users list.
103             Later this func will insert the \c BufferView into a real list,
104             not just setting a pointer.
105         */
106         void addUser(BufferView * u);
107
108         /** Removes the #BufferView# from the users list.
109             Since we only can have one at the moment, we just reset it.
110         */
111         void delUser(BufferView *);
112         
113         ///
114         void redraw();
115
116         /// Load the autosaved file.
117         void loadAutoSaveFile();
118         
119         /** Reads a file. 
120             \param par if != 0 insert the file.
121             \return \c false if method fails.
122         */
123         bool readFile(LyXLex &, LyXParagraph * par = 0);
124         
125         /** Reads a file without header.
126             \param par if != 0 insert the file.
127             \return \c false if file is not completely read.
128         */
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 \c true if the save is successful, \c false otherwise.
148         */
149         bool save() const;
150         
151         /// Write file. Returns \c false if unsuccesful.
152         bool writeFile(string const &, bool) const;
153         
154         ///
155         void writeFileAscii(string const & , int);
156         ///
157         void writeFileAscii(std::ostream &, int);
158         ///
159         string const asciiParagraph(LyXParagraph const *,
160                                     unsigned int linelen) const;
161         ///
162         void makeLaTeXFile(string const & filename,
163                            string const & original_path,
164                            bool nice, bool only_body = false);
165         /** LaTeX all paragraphs from par to endpar.
166             \param \a endpar if == 0 then to the end
167         */
168         void latexParagraphs(std::ostream & os, LyXParagraph * par,
169                              LyXParagraph * endpar, TexRow & texrow) const;
170
171         ///
172         void SimpleDocBookOnePar(std::ostream &, string & extra,
173                                  LyXParagraph * par, int & desc_on,
174                                  int depth) const ;
175
176         ///
177         int runChktex();
178
179         ///
180         void makeLinuxDocFile(string const & filename,
181                               bool nice, bool only_body = false);
182         ///
183         void makeDocBookFile(string const & filename,
184                              bool nice, bool only_body = false);
185
186         /// returns the main language for the buffer (document)
187         Language const * GetLanguage() const;
188         ///
189         bool isLyxClean() const;
190         ///
191         bool isBakClean() const;
192         ///
193         bool isDepClean(string const & name) const;
194         
195         ///
196         void markLyxClean() const;
197
198         ///
199         void markBakClean();
200         
201         ///
202         void markDepClean(string const & name);
203         
204         ///
205         void setUnnamed(bool flag=true);
206
207         ///
208         bool isUnnamed();
209
210         /// Mark this buffer as dirty.
211         void markDirty();
212
213         /// Returns the buffers filename.
214         string const & fileName() const;
215
216         /** A transformed version of the file name, adequate for LaTeX.
217             \param no_path optional if \c true then the path is stripped.
218         */
219         string const getLatexName(bool no_path = true) const;
220
221         /// Get the name and type of the log.
222         std::pair<LogType, string> const getLogName() const;
223  
224         /// Change name of buffer. Updates "read-only" flag.
225         void setFileName(string const & newfile);
226
227         /// Name of the document's parent
228         void setParentName(string const &);
229
230         /// Is buffer read-only?
231         bool isReadonly() const;
232
233         /// Set buffer read-only flag
234         void setReadonly(bool flag = true);
235
236         /// returns \c true if the buffer contains a LaTeX document
237         bool isLatex() const;
238         /// returns \c true if the buffer contains a LinuxDoc document
239         bool isLinuxDoc() const;
240         /// returns \c true if the buffer contains a DocBook document
241         bool isDocBook() const;
242         /** returns \c true if the buffer contains either a LinuxDoc
243             or DocBook document */
244         bool isSGML() const;
245         /// returns \c true if the buffer contains a Wed document
246         bool isLiterate() const;
247
248         ///
249         void setPaperStuff();
250
251         /** Validate a buffer for LaTeX.
252             This validates the buffer, and returns a struct for use by
253             #makeLaTeX# and others. Its main use is to figure out what
254             commands and packages need to be included in the LaTeX file.
255             It (should) also check that the needed constructs are there
256             (i.e. that the \refs points to coresponding \labels). It
257             should perhaps inset "error" insets to help the user correct
258             obvious mistakes.
259         */
260         void validate(LaTeXFeatures &) const;
261
262         ///
263         string const getIncludeonlyList(char delim = ',');
264         ///
265         std::vector<std::pair<string, string> > const getBibkeyList();
266         ///
267         struct TocItem {
268                 TocItem(LyXParagraph * p, int d, string const & s)
269                         : par(p), depth(d), str(s) {}
270                 ///
271                 LyXParagraph * par;
272                 ///
273                 int depth;
274                 ///
275                 string str;
276         };
277         ///
278         typedef std::vector<TocItem> SingleList;
279         ///
280         typedef std::map<string, SingleList> Lists;
281         ///
282         Lists const getLists() const;
283         ///
284         std::vector<string> const getLabelList();
285
286         /** This will clearly have to change later. Later we can have more
287             than one user per buffer. */
288         BufferView * getUser() const;
289
290         ///
291         void ChangeLanguage(Language const * from, Language const * to);
292         ///
293         bool isMultiLingual();
294
295         /// Does this mean that this is buffer local?
296         UndoStack undostack;
297         
298         /// Does this mean that this is buffer local? 
299         UndoStack redostack;
300         
301         ///
302         BufferParams params;
303         
304         /** The list of paragraphs.
305             This is a linked list of paragraph, this list holds the
306             whole contents of the document.
307          */
308         LyXParagraph * paragraph;
309
310         /// LyX version control object.
311         LyXVC lyxvc;
312
313         /// Where to put temporary files.
314         string tmppath;
315
316         /// The path to the document file.
317         string filepath;
318
319         /** If we are writing a nice LaTeX file or not.
320             While writing as LaTeX, tells whether we are
321             doing a 'nice' LaTeX file */
322         bool niceFile;
323
324         /// Used when typesetting to place errorboxes.
325         TexRow texrow;
326 private:
327 #ifndef NEW_INSETS
328         ///
329         void linuxDocHandleFootnote(std::ostream & os,
330                                     LyXParagraph * & par, int depth);
331 #endif
332         ///
333         void DocBookHandleCaption(std::ostream & os, string & inner_tag,
334                                   int depth, int desc_on,
335                                   LyXParagraph * & par);
336 #ifndef NEW_INSETS
337         ///
338         void DocBookHandleFootnote(std::ostream & os,
339                                    LyXParagraph * & par, int depth);
340 #endif
341         /// Open SGML/XML tag.
342         void sgmlOpenTag(std::ostream & os, int depth,
343                          string const & latexname) const;
344         /// Closes SGML/XML tag.
345         void sgmlCloseTag(std::ostream & os, int depth,
346                           string const & latexname) const;
347         ///
348         void LinuxDocError(LyXParagraph * par, int pos,
349                            string const & message);
350         ///
351         void SimpleLinuxDocOnePar(std::ostream & os, LyXParagraph * par, int depth);
352
353         /// is save needed
354         mutable bool lyx_clean;
355         
356         /// is autosave needed
357         mutable bool bak_clean;
358         
359         /// is this a unnamed file (New...)
360         bool unnamed;
361
362         /// is regenerating #.tex# necessary
363         DEPCLEAN * dep_clean;
364
365         /// buffer is r/o
366         bool read_only;
367
368         /// name of the file the buffer is associated with.
369         string filename;
370
371         /// Format number of buffer
372         int file_format;
373         /** A list of views using this buffer.
374             Why not keep a list of the BufferViews that use this buffer?
375
376             At least then we don't have to do a lot of magic like:
377             #buffer->lyx_gui->bufferview->updateLayoutChoice#. Just ask each
378             of the buffers in the list of users to do a #updateLayoutChoice#.
379         */
380         BufferView * users;
381
382 public:
383         ///
384         class inset_iterator {
385         public:
386                 typedef std::input_iterator_tag iterator_category;
387                 typedef Inset value_type;
388                 typedef ptrdiff_t difference_type;
389                 typedef Inset * pointer;
390                 typedef Inset & reference;
391                 
392                 
393                 ///
394                 inset_iterator() : par(0) /*, it(0)*/ {}
395                 //
396                 inset_iterator(LyXParagraph * paragraph) : par(paragraph) {
397                         SetParagraph();
398                 }
399                 ///
400                 inset_iterator(LyXParagraph * paragraph,
401                                LyXParagraph::size_type pos);
402                 ///
403                 inset_iterator & operator++() { // prefix ++
404                         if (par) {
405                                 ++it;
406                                 if (it == par->inset_iterator_end()) {
407 #ifndef NEW_INSETS
408                                         par = par->next_;
409 #else
410                                         par = par->next();
411 #endif
412                                         SetParagraph();
413                                 }
414                         }
415                         return *this;
416                 }
417                 ///
418                 inset_iterator operator++(int) { // postfix ++
419                         inset_iterator tmp(par, it.getPos());
420                         if (par) {
421                                 ++it;
422                                 if (it == par->inset_iterator_end()) {
423 #ifndef NEW_INSETS
424                                         par = par->next_;
425 #else
426                                         par = par->next();
427 #endif
428                                         SetParagraph();
429                                 }
430                         }
431                         return tmp;
432                 }
433                 ///
434                 Inset * operator*() { return *it; }
435                 
436                 ///
437                 LyXParagraph * getPar() { return par; }
438                 ///
439                 LyXParagraph::size_type getPos() const { return it.getPos(); }
440                 ///
441                 friend
442                 bool operator==(inset_iterator const & iter1,
443                                 inset_iterator const & iter2);
444         private:
445                 ///
446                 void SetParagraph();
447                 ///
448                 LyXParagraph * par;
449                 ///
450                 LyXParagraph::inset_iterator it;
451         };
452
453         ///
454         inset_iterator inset_iterator_begin() {
455                 return inset_iterator(paragraph);
456         }
457         ///
458         inset_iterator inset_iterator_end() {
459                 return inset_iterator();
460         }
461 };
462
463
464 inline
465 void Buffer::addUser(BufferView * u)
466 {
467         users = u;
468 }
469
470
471 inline
472 void Buffer::delUser(BufferView *)
473 {
474         users = 0;
475 }
476         
477
478 inline
479 void Buffer::redraw()
480 {
481         users->redraw(); 
482         users->fitCursor(users->text); 
483 }
484
485
486 inline
487 Language const * Buffer::GetLanguage() const
488 {
489         return params.language;
490 }
491         
492
493 inline
494 bool Buffer::isLyxClean() const
495 {
496         return lyx_clean;
497 }
498         
499
500 inline
501 bool Buffer::isBakClean() const
502 {
503         return bak_clean;
504 }
505
506
507 inline
508 void Buffer::markLyxClean() const
509
510         if (!lyx_clean) {
511                 lyx_clean = true; 
512                 updateTitles();
513         }
514         // if the .lyx file has been saved, we don't need an
515         // autosave 
516         bak_clean = true;
517 }
518
519
520 inline
521 void Buffer::markBakClean()
522 {
523         bak_clean = true;
524 }
525
526
527 inline
528 void Buffer::setUnnamed(bool flag)
529 {
530         unnamed = flag;
531 }
532
533
534 inline
535 bool Buffer::isUnnamed()
536 {
537         return unnamed;
538 }
539
540
541 inline
542 void Buffer::markDirty()
543 {
544         if (lyx_clean) {
545                 lyx_clean = false;
546                 updateTitles();
547         }
548         bak_clean = false;
549         DEPCLEAN * tmp = dep_clean;
550         while (tmp) {
551                 tmp->clean = false;
552                 tmp = tmp->next;
553         }
554 }
555
556
557 inline
558 string const & Buffer::fileName() const
559 {
560         return filename;
561 }
562
563
564 inline
565 bool Buffer::isReadonly() const
566 {
567         return read_only;
568 }
569
570
571 inline
572 BufferView * Buffer::getUser() const
573 {
574         return users;
575 }
576
577
578 inline  
579 void Buffer::setParentName(string const & name)
580 {
581         params.parentname = name;    
582 }
583
584
585 ///
586 inline
587 bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b) {
588         return a.par == b.par && a.str == b.str;
589         // No need to compare depth.
590 }
591
592
593 ///
594 inline
595 bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b) {
596         return !(a == b);
597         // No need to compare depth.
598 }
599
600 ///
601 inline
602 bool operator==(Buffer::inset_iterator const & iter1,
603                 Buffer::inset_iterator const & iter2) {
604         return iter1.par == iter2.par
605                 && (iter1.par == 0 || iter1.it == iter2.it);
606 }
607
608 ///
609 inline
610 bool operator!=(Buffer::inset_iterator const & iter1,
611                 Buffer::inset_iterator const & iter2) {
612         return !(iter1 == iter2);
613 }
614 #endif
615