]> git.lyx.org Git - lyx.git/blob - src/buffer.h
60cf303775c644c5dbc5e848083f6763999c8c25
[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         /** High-level interface to buffer functionality.
74             This function parses a command string and executes it
75         */
76         bool dispatch(string const & command);
77
78         /// Maybe we know the function already by number...
79         bool dispatch(int ac, string const & argument);
80
81         /// 
82         void resizeInsets(BufferView *);
83
84         /// Update window titles of all users.
85         void updateTitles() const;
86
87         /// Reset autosave timers for all users.
88         void resetAutosaveTimers() const;
89
90         /** Adds the BufferView to the users list.
91             Later this func will insert the \c BufferView into a real list,
92             not just setting a pointer.
93         */
94         void addUser(BufferView * u);
95
96         /** Removes the #BufferView# from the users list.
97             Since we only can have one at the moment, we just reset it.
98         */
99         void delUser(BufferView *);
100         
101         ///
102         void redraw();
103
104         /// Load the autosaved file.
105         void loadAutoSaveFile();
106         
107         /** Reads a file. 
108             \param par if != 0 insert the file.
109             \return \c false if method fails.
110         */
111         bool readFile(LyXLex &, Paragraph * par = 0);
112         
113         /** Reads a file without header.
114             \param par if != 0 insert the file.
115             \return \c false if file is not completely read.
116         */
117         bool readLyXformat2(LyXLex &, Paragraph * par = 0);
118
119         /// This parses a single LyXformat-Token.
120         bool parseSingleLyXformat2Token(LyXLex &, Paragraph *& par,
121                                         Paragraph *& return_par,
122                                         string const & token, int & pos,
123                                         Paragraph::depth_type & depth, 
124                                         LyXFont &);
125         ///
126         void insertStringAsLines(Paragraph *&, Paragraph::size_type &,
127                                  LyXFont const &, string const &) const;
128 #ifndef NO_COMPABILITY
129         ///
130         void insertErtContents(Paragraph * par, int & pos,
131                                LyXFont const & font,
132                                bool set_inactive = true);
133 #endif
134         ///
135         Paragraph * getParFromID(int id) const;
136 private:
137         /// Parse a single inset.
138         void readInset(LyXLex &, Paragraph *& par, int & pos, LyXFont &);
139 public:
140         /** Save file.
141             Takes care of auto-save files and backup file if requested.
142             Returns \c true if the save is successful, \c false otherwise.
143         */
144         bool save() const;
145         
146         /// Write file. Returns \c false if unsuccesful.
147         bool writeFile(string const &, bool) const;
148         
149         ///
150         void writeFileAscii(string const & , int);
151         ///
152         void writeFileAscii(std::ostream &, int);
153         ///
154         string const asciiParagraph(Paragraph const *,
155                                     unsigned int linelen) const;
156         ///
157         void makeLaTeXFile(string const & filename,
158                            string const & original_path,
159                            bool nice, bool only_body = false);
160         /** LaTeX all paragraphs from par to endpar.
161             \param \a endpar if == 0 then to the end
162         */
163         void latexParagraphs(std::ostream & os, Paragraph * par,
164                              Paragraph * endpar, TexRow & texrow) const;
165         ///
166         void simpleDocBookOnePar(std::ostream &,
167                                  Paragraph * par, int & desc_on,
168                                  Paragraph::depth_type depth) const ;
169         ///
170         void simpleLinuxDocOnePar(std::ostream & os, Paragraph * par, 
171                                   Paragraph::depth_type depth);
172         ///
173         void makeLinuxDocFile(string const & filename,
174                               bool nice, bool only_body = false);
175         ///
176         void makeDocBookFile(string const & filename,
177                              bool nice, bool only_body = false);
178         /// Open SGML/XML tag.
179         void sgmlOpenTag(std::ostream & os, Paragraph::depth_type depth,
180                 string const & latexname) const;
181         /// Closes SGML/XML tag.
182         void sgmlCloseTag(std::ostream & os, Paragraph::depth_type depth,
183                 string const & latexname) const;
184         ///
185         void sgmlError(Paragraph * par, int pos, string const & message) const;
186
187         /// returns the main language for the buffer (document)
188         Language const * getLanguage() const;
189         ///
190         int runChktex();
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         /// is save needed
328         mutable bool lyx_clean;
329         
330         /// is autosave needed
331         mutable bool bak_clean;
332         
333         /// is this a unnamed file (New...)
334         bool unnamed;
335
336         /// is regenerating #.tex# necessary
337         DEPCLEAN * dep_clean;
338
339         /// buffer is r/o
340         bool read_only;
341
342         /// name of the file the buffer is associated with.
343         string filename;
344
345         /// Format number of buffer
346         int file_format;
347         /** A list of views using this buffer.
348             Why not keep a list of the BufferViews that use this buffer?
349
350             At least then we don't have to do a lot of magic like:
351             #buffer->lyx_gui->bufferview->updateLayoutChoice#. Just ask each
352             of the buffers in the list of users to do a #updateLayoutChoice#.
353         */
354         BufferView * users;
355
356 public:
357         ///
358         class inset_iterator {
359         public:
360                 typedef std::input_iterator_tag iterator_category;
361                 typedef Inset value_type;
362                 typedef ptrdiff_t difference_type;
363                 typedef Inset * pointer;
364                 typedef Inset & reference;
365                 
366                 
367                 ///
368                 inset_iterator() : par(0) /*, it(0)*/ {}
369                 //
370                 inset_iterator(Paragraph * paragraph) : par(paragraph) {
371                         setParagraph();
372                 }
373                 ///
374                 inset_iterator(Paragraph * paragraph,
375                                Paragraph::size_type pos);
376                 ///
377                 inset_iterator & operator++() { // prefix ++
378                         if (par) {
379                                 ++it;
380                                 if (it == par->inset_iterator_end()) {
381                                         par = par->next();
382                                         setParagraph();
383                                 }
384                         }
385                         return *this;
386                 }
387                 ///
388                 inset_iterator operator++(int) { // postfix ++
389                         inset_iterator tmp(par, it.getPos());
390                         if (par) {
391                                 ++it;
392                                 if (it == par->inset_iterator_end()) {
393                                         par = par->next();
394                                         setParagraph();
395                                 }
396                         }
397                         return tmp;
398                 }
399                 ///
400                 Inset * operator*() { return *it; }
401                 
402                 ///
403                 Paragraph * getPar() { return par; }
404                 ///
405                 Paragraph::size_type getPos() const { return it.getPos(); }
406                 ///
407                 friend
408                 bool operator==(inset_iterator const & iter1,
409                                 inset_iterator const & iter2);
410         private:
411                 ///
412                 void setParagraph();
413                 ///
414                 Paragraph * par;
415                 ///
416                 Paragraph::inset_iterator it;
417         };
418
419         ///
420         inset_iterator inset_iterator_begin() {
421                 return inset_iterator(paragraph);
422         }
423         ///
424         inset_iterator inset_iterator_end() {
425                 return inset_iterator();
426         }
427         ///
428         inset_iterator inset_const_iterator_begin() const {
429                 return inset_iterator(paragraph);
430         }
431         ///
432         inset_iterator inset_const_iterator_end() const {
433                 return inset_iterator();
434         }
435
436         ///
437         ParIterator par_iterator_begin();
438         ///
439         ParIterator par_iterator_end();
440
441         ///
442         Inset * getInsetFromID(int id_arg) const;
443 };
444
445
446 inline
447 void Buffer::addUser(BufferView * u)
448 {
449         users = u;
450 }
451
452
453 inline
454 void Buffer::delUser(BufferView *)
455 {
456         users = 0;
457 }
458         
459
460 inline
461 Language const * Buffer::getLanguage() const
462 {
463         return params.language;
464 }
465         
466
467 inline
468 bool Buffer::isLyxClean() const
469 {
470         return lyx_clean;
471 }
472         
473
474 inline
475 bool Buffer::isBakClean() const
476 {
477         return bak_clean;
478 }
479
480
481 inline
482 void Buffer::markLyxClean() const
483
484         if (!lyx_clean) {
485                 lyx_clean = true; 
486                 updateTitles();
487         }
488         // if the .lyx file has been saved, we don't need an
489         // autosave 
490         bak_clean = true;
491 }
492
493
494 inline
495 void Buffer::markBakClean()
496 {
497         bak_clean = true;
498 }
499
500
501 inline
502 void Buffer::setUnnamed(bool flag)
503 {
504         unnamed = flag;
505 }
506
507
508 inline
509 bool Buffer::isUnnamed()
510 {
511         return unnamed;
512 }
513
514
515 inline
516 void Buffer::markDirty()
517 {
518         if (lyx_clean) {
519                 lyx_clean = false;
520                 updateTitles();
521         }
522         bak_clean = false;
523         DEPCLEAN * tmp = dep_clean;
524         while (tmp) {
525                 tmp->clean = false;
526                 tmp = tmp->next;
527         }
528 }
529
530
531 inline
532 string const & Buffer::fileName() const
533 {
534         return filename;
535 }
536
537
538 inline
539 bool Buffer::isReadonly() const
540 {
541         return read_only;
542 }
543
544
545 inline
546 BufferView * Buffer::getUser() const
547 {
548         return users;
549 }
550
551
552 inline  
553 void Buffer::setParentName(string const & name)
554 {
555         params.parentname = name;    
556 }
557
558
559 ///
560 inline
561 bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b)
562 {
563         return a.par == b.par && a.str == b.str;
564         // No need to compare depth.
565 }
566
567
568 ///
569 inline
570 bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b)
571 {
572         return !(a == b);
573         // No need to compare depth.
574 }
575
576
577 ///
578 inline
579 bool operator==(Buffer::inset_iterator const & iter1,
580                 Buffer::inset_iterator const & iter2)
581 {
582         return iter1.par == iter2.par
583                 && (iter1.par == 0 || iter1.it == iter2.it);
584 }
585
586
587 ///
588 inline
589 bool operator!=(Buffer::inset_iterator const & iter1,
590                 Buffer::inset_iterator const & iter2)
591 {
592         return !(iter1 == iter2);
593 }
594
595 #endif