]> git.lyx.org Git - lyx.git/blob - src/buffer.h
59beaa1ac8344a2b8632f4deb76a5b9833d6bcb2
[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 #ifndef BUFFER_H
14 #define BUFFER_H
15
16 #ifdef __GNUG__
17 #pragma interface
18 #endif
19
20 #include "LString.h"
21 #include "undo.h"
22 #include "undostack.h"
23 #include "lyxvc.h"
24 #include "bufferparams.h"
25 #include "texrow.h"
26 #include "paragraph.h"
27
28 class BufferView;
29 class LyXRC;
30 class TeXErrors;
31 class LaTeXFeatures;
32 class Language;
33 class ParIterator;
34
35 // When lyx 1.3.x starts we should enable this
36 // btw. we should also test this with 1.2 so that we
37 // do not get any surprises. (Lgb)
38 //#define NO_COMPABILITY 1
39
40 ///
41 struct DEPCLEAN {
42         ///
43         bool clean;
44         ///
45         string master;
46         ///
47         DEPCLEAN * next;
48 };
49
50 /** The buffer object.
51   This is the buffer object. It contains all the informations about
52   a document loaded into LyX. I am not sure if the class is complete or
53   minimal, probably not.
54   \author Lars Gullik Bjønnes
55   */
56 class Buffer {
57 public:
58         /// What type of log will \c getLogName() return?
59         enum LogType {
60                 latexlog, ///< LaTeX log
61                 buildlog  ///< Literate build log
62         };
63
64         /** Constructor
65             \param file
66             \param b  optional \c false by default
67         */
68         explicit Buffer(string const & file, bool b = false);
69         
70         /// Destructor
71         ~Buffer();
72
73         /** Save the buffer's parameters as user default.
74             This function saves a file \c user_lyxdir/templates/defaults.lyx
75             which parameters are those of the current buffer. This file
76             is used as a default template when creating a new
77             file. Returns \c true on success.
78         */
79         bool saveParamsAsDefaults();
80
81         /** High-level interface to buffer functionality.
82             This function parses a command string and executes it
83         */
84         bool dispatch(string const & command);
85
86         /// Maybe we know the function already by number...
87         bool dispatch(int ac, string const & argument);
88
89         /// 
90         void resizeInsets(BufferView *);
91
92         /// Update window titles of all users.
93         void updateTitles() const;
94
95         /// Reset autosave timers for all users.
96         void resetAutosaveTimers() const;
97
98         /** Adds the BufferView to the users list.
99             Later this func will insert the \c BufferView into a real list,
100             not just setting a pointer.
101         */
102         void addUser(BufferView * u);
103
104         /** Removes the #BufferView# from the users list.
105             Since we only can have one at the moment, we just reset it.
106         */
107         void delUser(BufferView *);
108         
109         ///
110         void redraw();
111
112         /// Load the autosaved file.
113         void loadAutoSaveFile();
114         
115         /** Reads a file. 
116             \param par if != 0 insert the file.
117             \return \c false if method fails.
118         */
119         bool readFile(LyXLex &, Paragraph * par = 0);
120         
121         /** Reads a file without header.
122             \param par if != 0 insert the file.
123             \return \c false if file is not completely read.
124         */
125         bool readLyXformat2(LyXLex &, Paragraph * par = 0);
126
127         /// This parses a single LyXformat-Token.
128         bool parseSingleLyXformat2Token(LyXLex &, Paragraph *& par,
129                                         Paragraph *& return_par,
130                                         string const & token, int & pos,
131                                         Paragraph::depth_type & depth, 
132                                         LyXFont &);
133         ///
134         void insertStringAsLines(Paragraph *&, Paragraph::size_type &,
135                                  LyXFont const &, string const &) const;
136 #ifndef NO_COMPABILITY
137         ///
138         void insertErtContents(Paragraph * par, int & pos,
139                                LyXFont const & font,
140                                bool set_inactive = true);
141 #endif
142         ///
143         Paragraph * getParFromID(int id) const;
144 private:
145         /// Parse a single inset.
146         void readInset(LyXLex &, Paragraph *& par, int & pos, LyXFont &);
147 public:
148         /** Save file.
149             Takes care of auto-save files and backup file if requested.
150             Returns \c true if the save is successful, \c false otherwise.
151         */
152         bool save() const;
153         
154         /// Write file. Returns \c false if unsuccesful.
155         bool writeFile(string const &, bool) const;
156         
157         ///
158         void writeFileAscii(string const & , int);
159         ///
160         void writeFileAscii(std::ostream &, int);
161         ///
162         string const asciiParagraph(Paragraph const *,
163                                     unsigned int linelen) const;
164         ///
165         void makeLaTeXFile(string const & filename,
166                            string const & original_path,
167                            bool nice, bool only_body = false);
168         /** LaTeX all paragraphs from par to endpar.
169             \param \a endpar if == 0 then to the end
170         */
171         void latexParagraphs(std::ostream & os, Paragraph * par,
172                              Paragraph * endpar, TexRow & texrow) const;
173
174         ///
175         void simpleDocBookOnePar(std::ostream &, string & extra,
176                                  Paragraph * par, int & desc_on,
177                                  Paragraph::depth_type depth) const ;
178
179         ///
180         int runChktex();
181
182         ///
183         void makeLinuxDocFile(string const & filename,
184                               bool nice, bool only_body = false);
185         ///
186         void makeDocBookFile(string const & filename,
187                              bool nice, bool only_body = false);
188
189         /// returns the main language for the buffer (document)
190         Language const * getLanguage() const;
191         ///
192         bool isLyxClean() const;
193         ///
194         bool isBakClean() const;
195         ///
196         bool isDepClean(string const & name) const;
197         
198         ///
199         void markLyxClean() const;
200
201         ///
202         void markBakClean();
203         
204         ///
205         void markDepClean(string const & name);
206         
207         ///
208         void setUnnamed(bool flag = true);
209
210         ///
211         bool isUnnamed();
212
213         /// Mark this buffer as dirty.
214         void markDirty();
215
216         /// Returns the buffers filename.
217         string const & fileName() const;
218
219         /** A transformed version of the file name, adequate for LaTeX.
220             \param no_path optional if \c true then the path is stripped.
221         */
222         string const getLatexName(bool no_path = true) const;
223
224         /// Get the name and type of the log.
225         std::pair<LogType, string> const getLogName() const;
226  
227         /// Change name of buffer. Updates "read-only" flag.
228         void setFileName(string const & newfile);
229
230         /// Name of the document's parent
231         void setParentName(string const &);
232
233         /// Is buffer read-only?
234         bool isReadonly() const;
235
236         /// Set buffer read-only flag
237         void setReadonly(bool flag = true);
238
239         /// returns \c true if the buffer contains a LaTeX document
240         bool isLatex() const;
241         /// returns \c true if the buffer contains a LinuxDoc document
242         bool isLinuxDoc() const;
243         /// returns \c true if the buffer contains a DocBook document
244         bool isDocBook() const;
245         /** returns \c true if the buffer contains either a LinuxDoc
246             or DocBook document */
247         bool isSGML() const;
248         /// returns \c true if the buffer contains a Wed document
249         bool isLiterate() const;
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(Paragraph * p, int d, string const & s)
269                         : par(p), depth(d), str(s) {}
270                 ///
271                 Paragraph * 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         Paragraph * 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         /// Open SGML/XML tag.
328         void sgmlOpenTag(std::ostream & os, Paragraph::depth_type depth,
329                          string const & latexname) const;
330         /// Closes SGML/XML tag.
331         void sgmlCloseTag(std::ostream & os, Paragraph::depth_type depth,
332                           string const & latexname) const;
333         ///
334         void linuxDocError(Paragraph * par, int pos,
335                            string const & message);
336         ///
337         void simpleLinuxDocOnePar(std::ostream & os, Paragraph * par, 
338                                   Paragraph::depth_type depth);
339
340         /// is save needed
341         mutable bool lyx_clean;
342         
343         /// is autosave needed
344         mutable bool bak_clean;
345         
346         /// is this a unnamed file (New...)
347         bool unnamed;
348
349         /// is regenerating #.tex# necessary
350         DEPCLEAN * dep_clean;
351
352         /// buffer is r/o
353         bool read_only;
354
355         /// name of the file the buffer is associated with.
356         string filename;
357
358         /// Format number of buffer
359         int file_format;
360         /** A list of views using this buffer.
361             Why not keep a list of the BufferViews that use this buffer?
362
363             At least then we don't have to do a lot of magic like:
364             #buffer->lyx_gui->bufferview->updateLayoutChoice#. Just ask each
365             of the buffers in the list of users to do a #updateLayoutChoice#.
366         */
367         BufferView * users;
368
369 public:
370         ///
371         class inset_iterator {
372         public:
373                 typedef std::input_iterator_tag iterator_category;
374                 typedef Inset value_type;
375                 typedef ptrdiff_t difference_type;
376                 typedef Inset * pointer;
377                 typedef Inset & reference;
378                 
379                 
380                 ///
381                 inset_iterator() : par(0) /*, it(0)*/ {}
382                 //
383                 inset_iterator(Paragraph * paragraph) : par(paragraph) {
384                         setParagraph();
385                 }
386                 ///
387                 inset_iterator(Paragraph * paragraph,
388                                Paragraph::size_type pos);
389                 ///
390                 inset_iterator & operator++() { // prefix ++
391                         if (par) {
392                                 ++it;
393                                 if (it == par->inset_iterator_end()) {
394                                         par = par->next();
395                                         setParagraph();
396                                 }
397                         }
398                         return *this;
399                 }
400                 ///
401                 inset_iterator operator++(int) { // postfix ++
402                         inset_iterator tmp(par, it.getPos());
403                         if (par) {
404                                 ++it;
405                                 if (it == par->inset_iterator_end()) {
406                                         par = par->next();
407                                         setParagraph();
408                                 }
409                         }
410                         return tmp;
411                 }
412                 ///
413                 Inset * operator*() { return *it; }
414                 
415                 ///
416                 Paragraph * getPar() { return par; }
417                 ///
418                 Paragraph::size_type getPos() const { return it.getPos(); }
419                 ///
420                 friend
421                 bool operator==(inset_iterator const & iter1,
422                                 inset_iterator const & iter2);
423         private:
424                 ///
425                 void setParagraph();
426                 ///
427                 Paragraph * par;
428                 ///
429                 Paragraph::inset_iterator it;
430         };
431
432         ///
433         inset_iterator inset_iterator_begin() {
434                 return inset_iterator(paragraph);
435         }
436         ///
437         inset_iterator inset_iterator_end() {
438                 return inset_iterator();
439         }
440         ///
441         inset_iterator inset_const_iterator_begin() const {
442                 return inset_iterator(paragraph);
443         }
444         ///
445         inset_iterator inset_const_iterator_end() const {
446                 return inset_iterator();
447         }
448
449         ///
450         ParIterator par_iterator_begin();
451         ///
452         ParIterator par_iterator_end();
453
454         ///
455         Inset * getInsetFromID(int id_arg) const;
456 };
457
458
459 inline
460 void Buffer::addUser(BufferView * u)
461 {
462         users = u;
463 }
464
465
466 inline
467 void Buffer::delUser(BufferView *)
468 {
469         users = 0;
470 }
471         
472
473 inline
474 Language const * Buffer::getLanguage() const
475 {
476         return params.language;
477 }
478         
479
480 inline
481 bool Buffer::isLyxClean() const
482 {
483         return lyx_clean;
484 }
485         
486
487 inline
488 bool Buffer::isBakClean() const
489 {
490         return bak_clean;
491 }
492
493
494 inline
495 void Buffer::markLyxClean() const
496
497         if (!lyx_clean) {
498                 lyx_clean = true; 
499                 updateTitles();
500         }
501         // if the .lyx file has been saved, we don't need an
502         // autosave 
503         bak_clean = true;
504 }
505
506
507 inline
508 void Buffer::markBakClean()
509 {
510         bak_clean = true;
511 }
512
513
514 inline
515 void Buffer::setUnnamed(bool flag)
516 {
517         unnamed = flag;
518 }
519
520
521 inline
522 bool Buffer::isUnnamed()
523 {
524         return unnamed;
525 }
526
527
528 inline
529 void Buffer::markDirty()
530 {
531         if (lyx_clean) {
532                 lyx_clean = false;
533                 updateTitles();
534         }
535         bak_clean = false;
536         DEPCLEAN * tmp = dep_clean;
537         while (tmp) {
538                 tmp->clean = false;
539                 tmp = tmp->next;
540         }
541 }
542
543
544 inline
545 string const & Buffer::fileName() const
546 {
547         return filename;
548 }
549
550
551 inline
552 bool Buffer::isReadonly() const
553 {
554         return read_only;
555 }
556
557
558 inline
559 BufferView * Buffer::getUser() const
560 {
561         return users;
562 }
563
564
565 inline  
566 void Buffer::setParentName(string const & name)
567 {
568         params.parentname = name;    
569 }
570
571
572 ///
573 inline
574 bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b) {
575         return a.par == b.par && a.str == b.str;
576         // No need to compare depth.
577 }
578
579
580 ///
581 inline
582 bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b) {
583         return !(a == b);
584         // No need to compare depth.
585 }
586
587
588 ///
589 inline
590 bool operator==(Buffer::inset_iterator const & iter1,
591                 Buffer::inset_iterator const & iter2) {
592         return iter1.par == iter2.par
593                 && (iter1.par == 0 || iter1.it == iter2.it);
594 }
595
596
597 ///
598 inline
599 bool operator!=(Buffer::inset_iterator const & iter1,
600                 Buffer::inset_iterator const & iter2) {
601         return !(iter1 == iter2);
602 }
603
604 #endif