]> git.lyx.org Git - lyx.git/blob - src/buffer.h
Added splash for qt2 frontend, Edwin
[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 // Change Log:
14 // =========== 
15 // 23/03/98   Heinrich Bauer (heinrich.bauer@t-mobil.de)
16 // Spots marked "changed Heinrich Bauer, 23/03/98" modified due to the
17 // following bug: dvi file export did not work after printing (or previewing)
18 // and vice versa as long as the same file was concerned. This happened
19 // every time the LyX-file was left unchanged between the two actions mentioned
20 // above.
21
22 #ifndef BUFFER_H
23 #define BUFFER_H
24
25 #ifdef __GNUG__
26 #pragma interface
27 #endif
28
29 #include "LString.h"
30
31 #include "BufferView.h"
32 #include "lyxvc.h"
33 #include "bufferparams.h"
34 #include "texrow.h"
35
36
37 class LyXRC;
38 class TeXErrors;
39 class LaTeXFeatures;
40 class Language;
41
42 ///
43 struct DEPCLEAN {
44         ///
45         bool clean;
46         ///
47         string master;
48         ///
49         DEPCLEAN * next;
50 };
51
52 /** The buffer object.
53   The is is the buffer object. It contains all the informations about
54   a document loaded into LyX. I am not sure if the class is complete or
55   minimal, probably not.
56   \author Lars Gullik Bjønnes
57   */
58 class Buffer {
59 public:
60         /// What type of log will \c getLogName() return?
61         enum LogType {
62                 latexlog, ///< LaTeX log
63                 buildlog  ///< Literate build log
64         };
65
66         /** Constructor
67             \param file
68             \param b  optional \c false by default
69         */
70         explicit Buffer(string const & file, bool b = false);
71         
72         /// Destrucotr
73         ~Buffer();
74
75         /** Save the buffer's parameters as user default.
76             This function saves a file \c user_lyxdir/templates/defaults.lyx
77             which parameters are those of the current buffer. This file
78             is used as a default template when creating a new
79             file. Returns \c true on success.
80         */
81         bool saveParamsAsDefaults();
82
83         /** High-level interface to buffer functionality.
84             This function parses a command string and executes it
85         */
86         bool Dispatch(string const & command);
87
88         /// Maybe we know the function already by number...
89         bool Dispatch(int ac, string const & argument);
90
91         /// Should be changed to work for a list.
92         void resize();
93         /// 
94         void resizeInsets(BufferView *);
95
96         /// Update window titles of all users.
97         void updateTitles() const;
98
99         /// Reset autosave timers for all users.
100         void resetAutosaveTimers() const;
101
102         /** Adds the BufferView to the users list.
103             Later this func will insert the \c BufferView into a real list,
104             not just setting a pointer.
105         */
106         void addUser(BufferView * u);
107
108         /** Removes the #BufferView# from the users list.
109             Since we only can have one at the moment, we just reset it.
110         */
111         void delUser(BufferView *);
112         
113         ///
114         void redraw();
115
116         /// Load the autosaved file.
117         void loadAutoSaveFile();
118         
119         /** Reads a file. 
120             \param par if != 0 insert the file.
121             \return \c false if method fails.
122         */
123         bool readFile(LyXLex &, LyXParagraph * par = 0);
124         
125         /** Reads a file without header.
126             \param par if != 0 insert the file.
127             \return \c false if file is not completely read.
128         */
129         bool readLyXformat2(LyXLex &, LyXParagraph * par = 0);
130
131         /// This parses a single LyXformat-Token.
132         bool parseSingleLyXformat2Token(LyXLex &, LyXParagraph *& par,
133                                         LyXParagraph *& return_par,
134                                         string const & token, int & pos,
135                                         char & depth, LyXFont &
136 #ifndef NEW_INSETS
137                                         ,LyXParagraph::footnote_flag &,
138                                         LyXParagraph::footnote_kind &
139 #endif
140                 );
141 private:
142         /// Parse a single inset.
143         void readInset(LyXLex &, LyXParagraph *& par, int & pos, LyXFont &);
144 public:
145         /** Save file.
146             Takes care of auto-save files and backup file if requested.
147             Returns \c true if the save is successful, \c false otherwise.
148         */
149         bool save() const;
150         
151         /// Write file. Returns \c false if unsuccesful.
152         bool writeFile(string const &, bool) const;
153         
154         ///
155         void writeFileAscii(string const & , int);
156         ///
157         void writeFileAscii(std::ostream &, int);
158         ///
159         string const asciiParagraph(LyXParagraph const *,
160                                     unsigned int linelen) const;
161         ///
162         void makeLaTeXFile(string const & filename,
163                            string const & original_path,
164                            bool nice, bool only_body = false);
165         /** LaTeX all paragraphs from par to endpar.
166             \param \a endpar if == 0 then to the end
167         */
168         void latexParagraphs(std::ostream & os, LyXParagraph * par,
169                              LyXParagraph * endpar, TexRow & texrow) const;
170
171         ///
172         void SimpleDocBookOnePar(std::ostream &, string & extra,
173                                  LyXParagraph * par, int & desc_on,
174                                  int depth) const ;
175
176         ///
177         int runChktex();
178
179         ///
180         void makeLinuxDocFile(string const & filename,
181                               bool nice, bool only_body = false);
182         ///
183         void makeDocBookFile(string const & filename,
184                              bool nice, bool only_body = false);
185
186         /// returns the main language for the buffer (document)
187         Language const * GetLanguage() const;
188         ///
189         bool isLyxClean() const;
190         ///
191         bool isBakClean() const;
192         ///
193         bool isDepClean(string const & name) const;
194         
195         ///
196         void markLyxClean() const;
197
198         ///
199         void markBakClean();
200         
201         ///
202         void markDepClean(string const & name);
203         
204         ///
205         void setUnnamed(bool flag=true);
206
207         ///
208         bool isUnnamed();
209
210         /// Mark this buffer as dirty.
211         void markDirty();
212
213         /// Returns the buffers filename.
214         string const & fileName() const;
215
216         /** A transformed version of the file name, adequate for LaTeX.
217             \param no_path optional if \c true then the path is stripped.
218         */
219         string const getLatexName(bool no_path = true) const;
220
221         /// Get the name and type of the log.
222         std::pair<LogType, string> const getLogName() const;
223  
224         /// Change name of buffer. Updates "read-only" flag.
225         void setFileName(string const & newfile);
226
227         /// Name of the document's parent
228         void setParentName(string const &);
229
230         /// Is buffer read-only?
231         bool isReadonly() const;
232
233         /// Set buffer read-only flag
234         void setReadonly(bool flag = true);
235
236         /// returns \c true if the buffer contains a LaTeX document
237         bool isLatex() const;
238         /// returns \c true if the buffer contains a LinuxDoc document
239         bool isLinuxDoc() const;
240         /// returns \c true if the buffer contains a DocBook document
241         bool isDocBook() const;
242         /** returns \c true if the buffer contains either a LinuxDoc
243             or DocBook document */
244         bool isSGML() const;
245         /// returns \c true if the buffer contains a Wed document
246         bool isLiterate() const;
247
248         ///
249         void setPaperStuff();
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(LyXParagraph * p, int d, string const & s)
269                         : par(p), depth(d), str(s) {}
270                 ///
271                 LyXParagraph * 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         LyXParagraph * 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 #ifndef NEW_INSETS
328         ///
329         void linuxDocHandleFootnote(std::ostream & os,
330                                     LyXParagraph * & par, int depth);
331 #endif
332         ///
333         void DocBookHandleCaption(std::ostream & os, string & inner_tag,
334                                   int depth, int desc_on,
335                                   LyXParagraph * & par);
336 #ifndef NEW_INSETS
337         ///
338         void DocBookHandleFootnote(std::ostream & os,
339                                    LyXParagraph * & par, int depth);
340 #endif
341         ///
342         void sgmlOpenTag(std::ostream & os, int depth,
343                          string const & latexname) const;
344         ///
345         void sgmlCloseTag(std::ostream & os, int depth,
346                           string const & latexname) const;
347         ///
348         void LinuxDocError(LyXParagraph * par, int pos,
349                            string const & message);
350         ///
351         void SimpleLinuxDocOnePar(std::ostream & os, LyXParagraph * par,
352                                   int desc_on, int depth);
353
354         /// LinuxDoc.
355         void push_tag(std::ostream & os, string const & tag,
356                       int & pos, char stack[5][3]);
357         
358         /// LinuxDoc.
359         void pop_tag(std::ostream & os, string const & tag,
360                      int & pos, char stack[5][3]);
361
362         /// is save needed
363         mutable bool lyx_clean;
364         
365         /// is autosave needed
366         mutable bool bak_clean;
367         
368         /// is this a unnamed file (New...)
369         bool unnamed;
370
371         /// is regenerating #.tex# necessary
372         DEPCLEAN * dep_clean;
373
374         /// buffer is r/o
375         bool read_only;
376
377         /// name of the file the buffer is associated with.
378         string filename;
379
380         /// Format number of buffer
381         int file_format;
382         /** A list of views using this buffer.
383             Why not keep a list of the BufferViews that use this buffer?
384
385             At least then we don't have to do a lot of magic like:
386             #buffer->lyx_gui->bufferview->updateLayoutChoice#. Just ask each
387             of the buffers in the list of users to do a #updateLayoutChoice#.
388         */
389         BufferView * users;
390
391 public:
392         ///
393         class inset_iterator {
394         public:
395                 typedef std::input_iterator_tag iterator_category;
396                 typedef Inset value_type;
397                 typedef ptrdiff_t difference_type;
398                 typedef Inset * pointer;
399                 typedef Inset & reference;
400                 
401                 
402                 ///
403                 inset_iterator() : par(0) /*, it(0)*/ {}
404                 //
405                 inset_iterator(LyXParagraph * paragraph) : par(paragraph) {
406                         SetParagraph();
407                 }
408                 ///
409                 inset_iterator(LyXParagraph * paragraph,
410                                LyXParagraph::size_type pos);
411                 ///
412                 inset_iterator & operator++() { // prefix ++
413                         if (par) {
414                                 ++it;
415                                 if (it == par->inset_iterator_end()) {
416 #ifndef NEW_INSETS
417                                         par = par->next_;
418 #else
419                                         par = par->next();
420 #endif
421                                         SetParagraph();
422                                 }
423                         }
424                         return *this;
425                 }
426                 ///
427                 inset_iterator operator++(int) { // postfix ++
428                         inset_iterator tmp(par, it.getPos());
429                         if (par) {
430                                 ++it;
431                                 if (it == par->inset_iterator_end()) {
432 #ifndef NEW_INSETS
433                                         par = par->next_;
434 #else
435                                         par = par->next();
436 #endif
437                                         SetParagraph();
438                                 }
439                         }
440                         return tmp;
441                 }
442                 ///
443                 Inset * operator*() { return *it; }
444                 
445                 ///
446                 LyXParagraph * getPar() { return par; }
447                 ///
448                 LyXParagraph::size_type getPos() const { return it.getPos(); }
449                 ///
450                 friend
451                 bool operator==(inset_iterator const & iter1,
452                                 inset_iterator const & iter2);
453         private:
454                 ///
455                 void SetParagraph();
456                 ///
457                 LyXParagraph * par;
458                 ///
459                 LyXParagraph::inset_iterator it;
460         };
461
462         ///
463         inset_iterator inset_iterator_begin() {
464                 return inset_iterator(paragraph);
465         }
466         ///
467         inset_iterator inset_iterator_end() {
468                 return inset_iterator();
469         }
470 };
471
472
473 inline
474 void Buffer::addUser(BufferView * u)
475 {
476         users = u;
477 }
478
479
480 inline
481 void Buffer::delUser(BufferView *)
482 {
483         users = 0;
484 }
485         
486
487 inline
488 void Buffer::redraw()
489 {
490         users->redraw(); 
491         users->fitCursor(users->text); 
492 }
493
494
495 inline
496 Language const * Buffer::GetLanguage() const
497 {
498         return params.language;
499 }
500         
501
502 inline
503 bool Buffer::isLyxClean() const
504 {
505         return lyx_clean;
506 }
507         
508
509 inline
510 bool Buffer::isBakClean() const
511 {
512         return bak_clean;
513 }
514
515
516 inline
517 void Buffer::markLyxClean() const
518
519         if (!lyx_clean) {
520                 lyx_clean = true; 
521                 updateTitles();
522         }
523         // if the .lyx file has been saved, we don't need an
524         // autosave 
525         bak_clean = true;
526 }
527
528
529 inline
530 void Buffer::markBakClean()
531 {
532         bak_clean = true;
533 }
534
535
536 inline
537 void Buffer::setUnnamed(bool flag)
538 {
539         unnamed = flag;
540 }
541
542
543 inline
544 bool Buffer::isUnnamed()
545 {
546         return unnamed;
547 }
548
549
550 inline
551 void Buffer::markDirty()
552 {
553         if (lyx_clean) {
554                 lyx_clean = false;
555                 updateTitles();
556         }
557         bak_clean = false;
558         DEPCLEAN * tmp = dep_clean;
559         while (tmp) {
560                 tmp->clean = false;
561                 tmp = tmp->next;
562         }
563 }
564
565
566 inline
567 string const & Buffer::fileName() const
568 {
569         return filename;
570 }
571
572
573 inline
574 bool Buffer::isReadonly() const
575 {
576         return read_only;
577 }
578
579
580 inline
581 BufferView * Buffer::getUser() const
582 {
583         return users;
584 }
585
586
587 inline  
588 void Buffer::setParentName(string const & name)
589 {
590         params.parentname = name;    
591 }
592
593
594 ///
595 inline
596 bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b) {
597         return a.par == b.par && a.str == b.str;
598         // No need to compare depth.
599 }
600
601
602 ///
603 inline
604 bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b) {
605         return !(a == b);
606         // No need to compare depth.
607 }
608
609 ///
610 inline
611 bool operator==(Buffer::inset_iterator const & iter1,
612                 Buffer::inset_iterator const & iter2) {
613         return iter1.par == iter2.par
614                 && (iter1.par == 0 || iter1.it == iter2.it);
615 }
616
617 ///
618 inline
619 bool operator!=(Buffer::inset_iterator const & iter1,
620                 Buffer::inset_iterator const & iter2) {
621         return !(iter1 == iter2);
622 }
623 #endif
624