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