]> git.lyx.org Git - lyx.git/blob - src/buffer.h
Fix crash when running lyx -dbg insets -e ...
[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 ///
35 struct DEPCLEAN {
36         ///
37         bool clean;
38         ///
39         string master;
40         ///
41         DEPCLEAN * next;
42 };
43
44 /** The buffer object.
45   This is the buffer object. It contains all the informations about
46   a document loaded into LyX. I am not sure if the class is complete or
47   minimal, probably not.
48   \author Lars Gullik Bjønnes
49   */
50 class Buffer {
51 public:
52         /// What type of log will \c getLogName() return?
53         enum LogType {
54                 latexlog, ///< LaTeX log
55                 buildlog  ///< Literate build log
56         };
57
58         /** Constructor
59             \param file
60             \param b  optional \c false by default
61         */
62         explicit Buffer(string const & file, bool b = false);
63         
64         /// Destructor
65         ~Buffer();
66
67         /** Save the buffer's parameters as user default.
68             This function saves a file \c user_lyxdir/templates/defaults.lyx
69             which parameters are those of the current buffer. This file
70             is used as a default template when creating a new
71             file. Returns \c true on success.
72         */
73         bool saveParamsAsDefaults();
74
75         /** High-level interface to buffer functionality.
76             This function parses a command string and executes it
77         */
78         bool dispatch(string const & command);
79
80         /// Maybe we know the function already by number...
81         bool dispatch(int ac, string const & argument);
82
83         /// 
84         void resizeInsets(BufferView *);
85
86         /// Update window titles of all users.
87         void updateTitles() const;
88
89         /// Reset autosave timers for all users.
90         void resetAutosaveTimers() const;
91
92         /** Adds the BufferView to the users list.
93             Later this func will insert the \c BufferView into a real list,
94             not just setting a pointer.
95         */
96         void addUser(BufferView * u);
97
98         /** Removes the #BufferView# from the users list.
99             Since we only can have one at the moment, we just reset it.
100         */
101         void delUser(BufferView *);
102         
103         ///
104         void redraw();
105
106         /// Load the autosaved file.
107         void loadAutoSaveFile();
108         
109         /** Reads a file. 
110             \param par if != 0 insert the file.
111             \return \c false if method fails.
112         */
113         bool readFile(LyXLex &, Paragraph * par = 0);
114         
115         /** Reads a file without header.
116             \param par if != 0 insert the file.
117             \return \c false if file is not completely read.
118         */
119         bool readLyXformat2(LyXLex &, Paragraph * par = 0);
120
121         /// This parses a single LyXformat-Token.
122         bool parseSingleLyXformat2Token(LyXLex &, Paragraph *& par,
123                                         Paragraph *& return_par,
124                                         string const & token, int & pos,
125                                         Paragraph::depth_type & depth, 
126                                         LyXFont &);
127         ///
128         void insertErtContents(Paragraph * par, int & pos,
129                                LyXFont const & font,
130                                bool set_inactive = true);
131         ///
132         Paragraph * getParFromID(int id) const;
133 private:
134         /// Parse a single inset.
135         void readInset(LyXLex &, Paragraph *& par, int & pos, LyXFont &);
136 public:
137         /** Save file.
138             Takes care of auto-save files and backup file if requested.
139             Returns \c true if the save is successful, \c false otherwise.
140         */
141         bool save() const;
142         
143         /// Write file. Returns \c false if unsuccesful.
144         bool writeFile(string const &, bool) const;
145         
146         ///
147         void writeFileAscii(string const & , int);
148         ///
149         void writeFileAscii(std::ostream &, int);
150         ///
151         string const asciiParagraph(Paragraph const *,
152                                     unsigned int linelen) const;
153         ///
154         void makeLaTeXFile(string const & filename,
155                            string const & original_path,
156                            bool nice, bool only_body = false);
157         /** LaTeX all paragraphs from par to endpar.
158             \param \a endpar if == 0 then to the end
159         */
160         void latexParagraphs(std::ostream & os, Paragraph * par,
161                              Paragraph * endpar, TexRow & texrow) const;
162
163         ///
164         void simpleDocBookOnePar(std::ostream &, string & extra,
165                                  Paragraph * par, int & desc_on,
166                                  Paragraph::depth_type depth) const ;
167
168         ///
169         int runChktex();
170
171         ///
172         void makeLinuxDocFile(string const & filename,
173                               bool nice, bool only_body = false);
174         ///
175         void makeDocBookFile(string const & filename,
176                              bool nice, bool only_body = false);
177
178         /// returns the main language for the buffer (document)
179         Language const * getLanguage() const;
180         ///
181         bool isLyxClean() const;
182         ///
183         bool isBakClean() const;
184         ///
185         bool isDepClean(string const & name) const;
186         
187         ///
188         void markLyxClean() const;
189
190         ///
191         void markBakClean();
192         
193         ///
194         void markDepClean(string const & name);
195         
196         ///
197         void setUnnamed(bool flag = true);
198
199         ///
200         bool isUnnamed();
201
202         /// Mark this buffer as dirty.
203         void markDirty();
204
205         /// Returns the buffers filename.
206         string const & fileName() const;
207
208         /** A transformed version of the file name, adequate for LaTeX.
209             \param no_path optional if \c true then the path is stripped.
210         */
211         string const getLatexName(bool no_path = true) const;
212
213         /// Get the name and type of the log.
214         std::pair<LogType, string> const getLogName() const;
215  
216         /// Change name of buffer. Updates "read-only" flag.
217         void setFileName(string const & newfile);
218
219         /// Name of the document's parent
220         void setParentName(string const &);
221
222         /// Is buffer read-only?
223         bool isReadonly() const;
224
225         /// Set buffer read-only flag
226         void setReadonly(bool flag = true);
227
228         /// returns \c true if the buffer contains a LaTeX document
229         bool isLatex() const;
230         /// returns \c true if the buffer contains a LinuxDoc document
231         bool isLinuxDoc() const;
232         /// returns \c true if the buffer contains a DocBook document
233         bool isDocBook() const;
234         /** returns \c true if the buffer contains either a LinuxDoc
235             or DocBook document */
236         bool isSGML() const;
237         /// returns \c true if the buffer contains a Wed document
238         bool isLiterate() const;
239
240         ///
241         void setPaperStuff();
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         ///
320         void docBookHandleCaption(std::ostream & os, string & inner_tag,
321                                   Paragraph::depth_type depth, int desc_on,
322                                   Paragraph * & par);
323         /// Open SGML/XML tag.
324         void sgmlOpenTag(std::ostream & os, Paragraph::depth_type depth,
325                          string const & latexname) const;
326         /// Closes SGML/XML tag.
327         void sgmlCloseTag(std::ostream & os, Paragraph::depth_type depth,
328                           string const & latexname) const;
329         ///
330         void linuxDocError(Paragraph * par, int pos,
331                            string const & message);
332         ///
333         void simpleLinuxDocOnePar(std::ostream & os, Paragraph * par, 
334                                   Paragraph::depth_type depth);
335
336         /// is save needed
337         mutable bool lyx_clean;
338         
339         /// is autosave needed
340         mutable bool bak_clean;
341         
342         /// is this a unnamed file (New...)
343         bool unnamed;
344
345         /// is regenerating #.tex# necessary
346         DEPCLEAN * dep_clean;
347
348         /// buffer is r/o
349         bool read_only;
350
351         /// name of the file the buffer is associated with.
352         string filename;
353
354         /// Format number of buffer
355         int file_format;
356         /** A list of views using this buffer.
357             Why not keep a list of the BufferViews that use this buffer?
358
359             At least then we don't have to do a lot of magic like:
360             #buffer->lyx_gui->bufferview->updateLayoutChoice#. Just ask each
361             of the buffers in the list of users to do a #updateLayoutChoice#.
362         */
363         BufferView * users;
364
365 public:
366         ///
367         class inset_iterator {
368         public:
369                 typedef std::input_iterator_tag iterator_category;
370                 typedef Inset value_type;
371                 typedef ptrdiff_t difference_type;
372                 typedef Inset * pointer;
373                 typedef Inset & reference;
374                 
375                 
376                 ///
377                 inset_iterator() : par(0) /*, it(0)*/ {}
378                 //
379                 inset_iterator(Paragraph * paragraph) : par(paragraph) {
380                         setParagraph();
381                 }
382                 ///
383                 inset_iterator(Paragraph * paragraph,
384                                Paragraph::size_type pos);
385                 ///
386                 inset_iterator & operator++() { // prefix ++
387                         if (par) {
388                                 ++it;
389                                 if (it == par->inset_iterator_end()) {
390                                         par = par->next();
391                                         setParagraph();
392                                 }
393                         }
394                         return *this;
395                 }
396                 ///
397                 inset_iterator operator++(int) { // postfix ++
398                         inset_iterator tmp(par, it.getPos());
399                         if (par) {
400                                 ++it;
401                                 if (it == par->inset_iterator_end()) {
402                                         par = par->next();
403                                         setParagraph();
404                                 }
405                         }
406                         return tmp;
407                 }
408                 ///
409                 Inset * operator*() { return *it; }
410                 
411                 ///
412                 Paragraph * getPar() { return par; }
413                 ///
414                 Paragraph::size_type getPos() const { return it.getPos(); }
415                 ///
416                 friend
417                 bool operator==(inset_iterator const & iter1,
418                                 inset_iterator const & iter2);
419         private:
420                 ///
421                 void setParagraph();
422                 ///
423                 Paragraph * par;
424                 ///
425                 Paragraph::inset_iterator it;
426         };
427
428         ///
429         inset_iterator inset_iterator_begin() {
430                 return inset_iterator(paragraph);
431         }
432         ///
433         inset_iterator inset_iterator_end() {
434                 return inset_iterator();
435         }
436         ///
437         inset_iterator inset_const_iterator_begin() const {
438                 return inset_iterator(paragraph);
439         }
440         ///
441         inset_iterator inset_const_iterator_end() const {
442                 return inset_iterator();
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 #endif