]> git.lyx.org Git - lyx.git/blob - src/buffer.h
0e8bc1efad07cd91d33a07dac201ad2d62d3ddb0
[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         ///
167         void simpleDocBookOnePar(std::ostream &, string & extra,
168                                  Paragraph * par, int & desc_on,
169                                  Paragraph::depth_type depth) const ;
170         ///
171         void simpleLinuxDocOnePar(std::ostream & os, Paragraph * par, 
172                                   Paragraph::depth_type depth);
173
174         ///
175         void makeLinuxDocFile(string const & filename,
176                               bool nice, bool only_body = false);
177         ///
178         void makeDocBookFile(string const & filename,
179                              bool nice, bool only_body = false);
180         /// Open SGML/XML tag.
181         void sgmlOpenTag(std::ostream & os, Paragraph::depth_type depth,
182                          string const & latexname) const;
183         /// Closes SGML/XML tag.
184         void sgmlCloseTag(std::ostream & os, Paragraph::depth_type depth,
185                           string const & latexname) const;
186         ///
187         void sgmlError(Paragraph * par, int pos,
188                        string const & message) const;
189
190         /// returns the main language for the buffer (document)
191         Language const * getLanguage() const;
192         ///
193         int runChktex();
194         ///
195         bool isLyxClean() const;
196         ///
197         bool isBakClean() const;
198         ///
199         bool isDepClean(string const & name) const;
200         
201         ///
202         void markLyxClean() const;
203
204         ///
205         void markBakClean();
206         
207         ///
208         void markDepClean(string const & name);
209         
210         ///
211         void setUnnamed(bool flag = true);
212
213         ///
214         bool isUnnamed();
215
216         /// Mark this buffer as dirty.
217         void markDirty();
218
219         /// Returns the buffers filename.
220         string const & fileName() const;
221
222         /** A transformed version of the file name, adequate for LaTeX.
223             \param no_path optional if \c true then the path is stripped.
224         */
225         string const getLatexName(bool no_path = true) const;
226
227         /// Get the name and type of the log.
228         std::pair<LogType, string> const getLogName() const;
229  
230         /// Change name of buffer. Updates "read-only" flag.
231         void setFileName(string const & newfile);
232
233         /// Name of the document's parent
234         void setParentName(string const &);
235
236         /// Is buffer read-only?
237         bool isReadonly() const;
238
239         /// Set buffer read-only flag
240         void setReadonly(bool flag = true);
241
242         /// returns \c true if the buffer contains a LaTeX document
243         bool isLatex() const;
244         /// returns \c true if the buffer contains a LinuxDoc document
245         bool isLinuxDoc() const;
246         /// returns \c true if the buffer contains a DocBook document
247         bool isDocBook() const;
248         /** returns \c true if the buffer contains either a LinuxDoc
249             or DocBook document */
250         bool isSGML() const;
251         /// returns \c true if the buffer contains a Wed document
252         bool isLiterate() const;
253
254         /** Validate a buffer for LaTeX.
255             This validates the buffer, and returns a struct for use by
256             #makeLaTeX# and others. Its main use is to figure out what
257             commands and packages need to be included in the LaTeX file.
258             It (should) also check that the needed constructs are there
259             (i.e. that the \refs points to coresponding \labels). It
260             should perhaps inset "error" insets to help the user correct
261             obvious mistakes.
262         */
263         void validate(LaTeXFeatures &) const;
264
265         ///
266         string const getIncludeonlyList(char delim = ',');
267         ///
268         std::vector<std::pair<string, string> > const getBibkeyList();
269         ///
270         struct TocItem {
271                 TocItem(Paragraph * p, int d, string const & s)
272                         : par(p), depth(d), str(s) {}
273                 ///
274                 Paragraph * par;
275                 ///
276                 int depth;
277                 ///
278                 string str;
279         };
280         ///
281         typedef std::vector<TocItem> SingleList;
282         ///
283         typedef std::map<string, SingleList> Lists;
284         ///
285         Lists const getLists() const;
286         ///
287         std::vector<string> const getLabelList();
288
289         /** This will clearly have to change later. Later we can have more
290             than one user per buffer. */
291         BufferView * getUser() const;
292
293         ///
294         void changeLanguage(Language const * from, Language const * to);
295         ///
296         bool isMultiLingual();
297
298         /// Does this mean that this is buffer local?
299         UndoStack undostack;
300         
301         /// Does this mean that this is buffer local? 
302         UndoStack redostack;
303         
304         ///
305         BufferParams params;
306         
307         /** The list of paragraphs.
308             This is a linked list of paragraph, this list holds the
309             whole contents of the document.
310          */
311         Paragraph * paragraph;
312
313         /// LyX version control object.
314         LyXVC lyxvc;
315
316         /// Where to put temporary files.
317         string tmppath;
318
319         /// The path to the document file.
320         string filepath;
321
322         /** If we are writing a nice LaTeX file or not.
323             While writing as LaTeX, tells whether we are
324             doing a 'nice' LaTeX file */
325         bool niceFile;
326
327         /// Used when typesetting to place errorboxes.
328         TexRow texrow;
329 private:
330         /// is save needed
331         mutable bool lyx_clean;
332         
333         /// is autosave needed
334         mutable bool bak_clean;
335         
336         /// is this a unnamed file (New...)
337         bool unnamed;
338
339         /// is regenerating #.tex# necessary
340         DEPCLEAN * dep_clean;
341
342         /// buffer is r/o
343         bool read_only;
344
345         /// name of the file the buffer is associated with.
346         string filename;
347
348         /// Format number of buffer
349         int file_format;
350         /** A list of views using this buffer.
351             Why not keep a list of the BufferViews that use this buffer?
352
353             At least then we don't have to do a lot of magic like:
354             #buffer->lyx_gui->bufferview->updateLayoutChoice#. Just ask each
355             of the buffers in the list of users to do a #updateLayoutChoice#.
356         */
357         BufferView * users;
358
359 public:
360         ///
361         class inset_iterator {
362         public:
363                 typedef std::input_iterator_tag iterator_category;
364                 typedef Inset value_type;
365                 typedef ptrdiff_t difference_type;
366                 typedef Inset * pointer;
367                 typedef Inset & reference;
368                 
369                 
370                 ///
371                 inset_iterator() : par(0) /*, it(0)*/ {}
372                 //
373                 inset_iterator(Paragraph * paragraph) : par(paragraph) {
374                         setParagraph();
375                 }
376                 ///
377                 inset_iterator(Paragraph * paragraph,
378                                Paragraph::size_type pos);
379                 ///
380                 inset_iterator & operator++() { // prefix ++
381                         if (par) {
382                                 ++it;
383                                 if (it == par->inset_iterator_end()) {
384                                         par = par->next();
385                                         setParagraph();
386                                 }
387                         }
388                         return *this;
389                 }
390                 ///
391                 inset_iterator operator++(int) { // postfix ++
392                         inset_iterator tmp(par, it.getPos());
393                         if (par) {
394                                 ++it;
395                                 if (it == par->inset_iterator_end()) {
396                                         par = par->next();
397                                         setParagraph();
398                                 }
399                         }
400                         return tmp;
401                 }
402                 ///
403                 Inset * operator*() { return *it; }
404                 
405                 ///
406                 Paragraph * getPar() { return par; }
407                 ///
408                 Paragraph::size_type getPos() const { return it.getPos(); }
409                 ///
410                 friend
411                 bool operator==(inset_iterator const & iter1,
412                                 inset_iterator const & iter2);
413         private:
414                 ///
415                 void setParagraph();
416                 ///
417                 Paragraph * par;
418                 ///
419                 Paragraph::inset_iterator it;
420         };
421
422         ///
423         inset_iterator inset_iterator_begin() {
424                 return inset_iterator(paragraph);
425         }
426         ///
427         inset_iterator inset_iterator_end() {
428                 return inset_iterator();
429         }
430         ///
431         inset_iterator inset_const_iterator_begin() const {
432                 return inset_iterator(paragraph);
433         }
434         ///
435         inset_iterator inset_const_iterator_end() const {
436                 return inset_iterator();
437         }
438
439         ///
440         ParIterator par_iterator_begin();
441         ///
442         ParIterator par_iterator_end();
443
444         ///
445         Inset * getInsetFromID(int id_arg) const;
446 };
447
448
449 inline
450 void Buffer::addUser(BufferView * u)
451 {
452         users = u;
453 }
454
455
456 inline
457 void Buffer::delUser(BufferView *)
458 {
459         users = 0;
460 }
461         
462
463 inline
464 Language const * Buffer::getLanguage() const
465 {
466         return params.language;
467 }
468         
469
470 inline
471 bool Buffer::isLyxClean() const
472 {
473         return lyx_clean;
474 }
475         
476
477 inline
478 bool Buffer::isBakClean() const
479 {
480         return bak_clean;
481 }
482
483
484 inline
485 void Buffer::markLyxClean() const
486
487         if (!lyx_clean) {
488                 lyx_clean = true; 
489                 updateTitles();
490         }
491         // if the .lyx file has been saved, we don't need an
492         // autosave 
493         bak_clean = true;
494 }
495
496
497 inline
498 void Buffer::markBakClean()
499 {
500         bak_clean = true;
501 }
502
503
504 inline
505 void Buffer::setUnnamed(bool flag)
506 {
507         unnamed = flag;
508 }
509
510
511 inline
512 bool Buffer::isUnnamed()
513 {
514         return unnamed;
515 }
516
517
518 inline
519 void Buffer::markDirty()
520 {
521         if (lyx_clean) {
522                 lyx_clean = false;
523                 updateTitles();
524         }
525         bak_clean = false;
526         DEPCLEAN * tmp = dep_clean;
527         while (tmp) {
528                 tmp->clean = false;
529                 tmp = tmp->next;
530         }
531 }
532
533
534 inline
535 string const & Buffer::fileName() const
536 {
537         return filename;
538 }
539
540
541 inline
542 bool Buffer::isReadonly() const
543 {
544         return read_only;
545 }
546
547
548 inline
549 BufferView * Buffer::getUser() const
550 {
551         return users;
552 }
553
554
555 inline  
556 void Buffer::setParentName(string const & name)
557 {
558         params.parentname = name;    
559 }
560
561
562 ///
563 inline
564 bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b) {
565         return a.par == b.par && a.str == b.str;
566         // No need to compare depth.
567 }
568
569
570 ///
571 inline
572 bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b) {
573         return !(a == b);
574         // No need to compare depth.
575 }
576
577
578 ///
579 inline
580 bool operator==(Buffer::inset_iterator const & iter1,
581                 Buffer::inset_iterator const & iter2) {
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         return !(iter1 == iter2);
592 }
593
594 #endif