]> git.lyx.org Git - lyx.git/blob - src/buffer.h
a68acbc26399c9a7a2a019ccae6e6ca67f4640d5
[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
34 // When lyx 1.3.x starts we should enable this
35 // btw. we should also test this with 1.2 so that we
36 // do not get any surprises. (Lgb)
37 //#define NO_COMPABILITY 1
38
39 ///
40 struct DEPCLEAN {
41         ///
42         bool clean;
43         ///
44         string master;
45         ///
46         DEPCLEAN * next;
47 };
48
49 /** The buffer object.
50   This is the buffer object. It contains all the informations about
51   a document loaded into LyX. I am not sure if the class is complete or
52   minimal, probably not.
53   \author Lars Gullik Bjønnes
54   */
55 class Buffer {
56 public:
57         /// What type of log will \c getLogName() return?
58         enum LogType {
59                 latexlog, ///< LaTeX log
60                 buildlog  ///< Literate build log
61         };
62
63         /** Constructor
64             \param file
65             \param b  optional \c false by default
66         */
67         explicit Buffer(string const & file, bool b = false);
68         
69         /// Destructor
70         ~Buffer();
71
72         /** Save the buffer's parameters as user default.
73             This function saves a file \c user_lyxdir/templates/defaults.lyx
74             which parameters are those of the current buffer. This file
75             is used as a default template when creating a new
76             file. Returns \c true on success.
77         */
78         bool saveParamsAsDefaults();
79
80         /** High-level interface to buffer functionality.
81             This function parses a command string and executes it
82         */
83         bool dispatch(string const & command);
84
85         /// Maybe we know the function already by number...
86         bool dispatch(int ac, string const & argument);
87
88         /// 
89         void resizeInsets(BufferView *);
90
91         /// Update window titles of all users.
92         void updateTitles() const;
93
94         /// Reset autosave timers for all users.
95         void resetAutosaveTimers() const;
96
97         /** Adds the BufferView to the users list.
98             Later this func will insert the \c BufferView into a real list,
99             not just setting a pointer.
100         */
101         void addUser(BufferView * u);
102
103         /** Removes the #BufferView# from the users list.
104             Since we only can have one at the moment, we just reset it.
105         */
106         void delUser(BufferView *);
107         
108         ///
109         void redraw();
110
111         /// Load the autosaved file.
112         void loadAutoSaveFile();
113         
114         /** Reads a file. 
115             \param par if != 0 insert the file.
116             \return \c false if method fails.
117         */
118         bool readFile(LyXLex &, Paragraph * par = 0);
119         
120         /** Reads a file without header.
121             \param par if != 0 insert the file.
122             \return \c false if file is not completely read.
123         */
124         bool readLyXformat2(LyXLex &, Paragraph * par = 0);
125
126         /// This parses a single LyXformat-Token.
127         bool parseSingleLyXformat2Token(LyXLex &, Paragraph *& par,
128                                         Paragraph *& return_par,
129                                         string const & token, int & pos,
130                                         Paragraph::depth_type & depth, 
131                                         LyXFont &);
132         ///
133         void insertStringAsLines(Paragraph *&, Paragraph::size_type &,
134                                  LyXFont const &, string const &) const;
135 #ifndef NO_COMPABILITY
136         ///
137         void insertErtContents(Paragraph * par, int & pos,
138                                LyXFont const & font,
139                                bool set_inactive = true);
140 #endif
141         ///
142         Paragraph * getParFromID(int id) const;
143 private:
144         /// Parse a single inset.
145         void readInset(LyXLex &, Paragraph *& par, int & pos, LyXFont &);
146 public:
147         /** Save file.
148             Takes care of auto-save files and backup file if requested.
149             Returns \c true if the save is successful, \c false otherwise.
150         */
151         bool save() const;
152         
153         /// Write file. Returns \c false if unsuccesful.
154         bool writeFile(string const &, bool) const;
155         
156         ///
157         void writeFileAscii(string const & , int);
158         ///
159         void writeFileAscii(std::ostream &, int);
160         ///
161         string const asciiParagraph(Paragraph const *,
162                                     unsigned int linelen) const;
163         ///
164         void makeLaTeXFile(string const & filename,
165                            string const & original_path,
166                            bool nice, bool only_body = false);
167         /** LaTeX all paragraphs from par to endpar.
168             \param \a endpar if == 0 then to the end
169         */
170         void latexParagraphs(std::ostream & os, Paragraph * par,
171                              Paragraph * endpar, TexRow & texrow) const;
172
173         ///
174         void simpleDocBookOnePar(std::ostream &, string & extra,
175                                  Paragraph * par, int & desc_on,
176                                  Paragraph::depth_type depth) const ;
177
178         ///
179         int runChktex();
180
181         ///
182         void makeLinuxDocFile(string const & filename,
183                               bool nice, bool only_body = false);
184         ///
185         void makeDocBookFile(string const & filename,
186                              bool nice, bool only_body = false);
187
188         /// returns the main language for the buffer (document)
189         Language const * getLanguage() const;
190         ///
191         bool isLyxClean() const;
192         ///
193         bool isBakClean() const;
194         ///
195         bool isDepClean(string const & name) const;
196         
197         ///
198         void markLyxClean() const;
199
200         ///
201         void markBakClean();
202         
203         ///
204         void markDepClean(string const & name);
205         
206         ///
207         void setUnnamed(bool flag = true);
208
209         ///
210         bool isUnnamed();
211
212         /// Mark this buffer as dirty.
213         void markDirty();
214
215         /// Returns the buffers filename.
216         string const & fileName() const;
217
218         /** A transformed version of the file name, adequate for LaTeX.
219             \param no_path optional if \c true then the path is stripped.
220         */
221         string const getLatexName(bool no_path = true) const;
222
223         /// Get the name and type of the log.
224         std::pair<LogType, string> const getLogName() const;
225  
226         /// Change name of buffer. Updates "read-only" flag.
227         void setFileName(string const & newfile);
228
229         /// Name of the document's parent
230         void setParentName(string const &);
231
232         /// Is buffer read-only?
233         bool isReadonly() const;
234
235         /// Set buffer read-only flag
236         void setReadonly(bool flag = true);
237
238         /// returns \c true if the buffer contains a LaTeX document
239         bool isLatex() const;
240         /// returns \c true if the buffer contains a LinuxDoc document
241         bool isLinuxDoc() const;
242         /// returns \c true if the buffer contains a DocBook document
243         bool isDocBook() const;
244         /** returns \c true if the buffer contains either a LinuxDoc
245             or DocBook document */
246         bool isSGML() const;
247         /// returns \c true if the buffer contains a Wed document
248         bool isLiterate() const;
249
250         ///
251         void setPaperStuff();
252
253         /** Validate a buffer for LaTeX.
254             This validates the buffer, and returns a struct for use by
255             #makeLaTeX# and others. Its main use is to figure out what
256             commands and packages need to be included in the LaTeX file.
257             It (should) also check that the needed constructs are there
258             (i.e. that the \refs points to coresponding \labels). It
259             should perhaps inset "error" insets to help the user correct
260             obvious mistakes.
261         */
262         void validate(LaTeXFeatures &) const;
263
264         ///
265         string const getIncludeonlyList(char delim = ',');
266         ///
267         std::vector<std::pair<string, string> > const getBibkeyList();
268         ///
269         struct TocItem {
270                 TocItem(Paragraph * p, int d, string const & s)
271                         : par(p), depth(d), str(s) {}
272                 ///
273                 Paragraph * par;
274                 ///
275                 int depth;
276                 ///
277                 string str;
278         };
279         ///
280         typedef std::vector<TocItem> SingleList;
281         ///
282         typedef std::map<string, SingleList> Lists;
283         ///
284         Lists const getLists() const;
285         ///
286         std::vector<string> const getLabelList();
287
288         /** This will clearly have to change later. Later we can have more
289             than one user per buffer. */
290         BufferView * getUser() const;
291
292         ///
293         void changeLanguage(Language const * from, Language const * to);
294         ///
295         bool isMultiLingual();
296
297         /// Does this mean that this is buffer local?
298         UndoStack undostack;
299         
300         /// Does this mean that this is buffer local? 
301         UndoStack redostack;
302         
303         ///
304         BufferParams params;
305         
306         /** The list of paragraphs.
307             This is a linked list of paragraph, this list holds the
308             whole contents of the document.
309          */
310         Paragraph * paragraph;
311
312         /// LyX version control object.
313         LyXVC lyxvc;
314
315         /// Where to put temporary files.
316         string tmppath;
317
318         /// The path to the document file.
319         string filepath;
320
321         /** If we are writing a nice LaTeX file or not.
322             While writing as LaTeX, tells whether we are
323             doing a 'nice' LaTeX file */
324         bool niceFile;
325
326         /// Used when typesetting to place errorboxes.
327         TexRow texrow;
328 private:
329         ///
330         void docBookHandleCaption(std::ostream & os, string & inner_tag,
331                                   Paragraph::depth_type depth, int desc_on,
332                                   Paragraph * & par);
333         /// Open SGML/XML tag.
334         void sgmlOpenTag(std::ostream & os, Paragraph::depth_type depth,
335                          string const & latexname) const;
336         /// Closes SGML/XML tag.
337         void sgmlCloseTag(std::ostream & os, Paragraph::depth_type depth,
338                           string const & latexname) const;
339         ///
340         void linuxDocError(Paragraph * par, int pos,
341                            string const & message);
342         ///
343         void simpleLinuxDocOnePar(std::ostream & os, Paragraph * par, 
344                                   Paragraph::depth_type depth);
345
346         /// is save needed
347         mutable bool lyx_clean;
348         
349         /// is autosave needed
350         mutable bool bak_clean;
351         
352         /// is this a unnamed file (New...)
353         bool unnamed;
354
355         /// is regenerating #.tex# necessary
356         DEPCLEAN * dep_clean;
357
358         /// buffer is r/o
359         bool read_only;
360
361         /// name of the file the buffer is associated with.
362         string filename;
363
364         /// Format number of buffer
365         int file_format;
366         /** A list of views using this buffer.
367             Why not keep a list of the BufferViews that use this buffer?
368
369             At least then we don't have to do a lot of magic like:
370             #buffer->lyx_gui->bufferview->updateLayoutChoice#. Just ask each
371             of the buffers in the list of users to do a #updateLayoutChoice#.
372         */
373         BufferView * users;
374
375 public:
376         ///
377         class inset_iterator {
378         public:
379                 typedef std::input_iterator_tag iterator_category;
380                 typedef Inset value_type;
381                 typedef ptrdiff_t difference_type;
382                 typedef Inset * pointer;
383                 typedef Inset & reference;
384                 
385                 
386                 ///
387                 inset_iterator() : par(0) /*, it(0)*/ {}
388                 //
389                 inset_iterator(Paragraph * paragraph) : par(paragraph) {
390                         setParagraph();
391                 }
392                 ///
393                 inset_iterator(Paragraph * paragraph,
394                                Paragraph::size_type pos);
395                 ///
396                 inset_iterator & operator++() { // prefix ++
397                         if (par) {
398                                 ++it;
399                                 if (it == par->inset_iterator_end()) {
400                                         par = par->next();
401                                         setParagraph();
402                                 }
403                         }
404                         return *this;
405                 }
406                 ///
407                 inset_iterator operator++(int) { // postfix ++
408                         inset_iterator tmp(par, it.getPos());
409                         if (par) {
410                                 ++it;
411                                 if (it == par->inset_iterator_end()) {
412                                         par = par->next();
413                                         setParagraph();
414                                 }
415                         }
416                         return tmp;
417                 }
418                 ///
419                 Inset * operator*() { return *it; }
420                 
421                 ///
422                 Paragraph * getPar() { return par; }
423                 ///
424                 Paragraph::size_type getPos() const { return it.getPos(); }
425                 ///
426                 friend
427                 bool operator==(inset_iterator const & iter1,
428                                 inset_iterator const & iter2);
429         private:
430                 ///
431                 void setParagraph();
432                 ///
433                 Paragraph * par;
434                 ///
435                 Paragraph::inset_iterator it;
436         };
437
438         ///
439         inset_iterator inset_iterator_begin() {
440                 return inset_iterator(paragraph);
441         }
442         ///
443         inset_iterator inset_iterator_end() {
444                 return inset_iterator();
445         }
446         ///
447         inset_iterator inset_const_iterator_begin() const {
448                 return inset_iterator(paragraph);
449         }
450         ///
451         inset_iterator inset_const_iterator_end() const {
452                 return inset_iterator();
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 #endif