]> git.lyx.org Git - lyx.git/blob - src/buffer.h
Allow including of files with different class than the parent file
[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                 ///
269                 LyXParagraph * par;
270                 ///
271                 int depth;
272                 ///
273                 string str;
274         };
275         ///
276         typedef std::vector<TocItem> SingleList;
277         ///
278         typedef std::map<string, SingleList> Lists;
279         ///
280         Lists const getLists() const;
281         ///
282         std::vector<string> const getLabelList();
283
284         /** This will clearly have to change later. Later we can have more
285             than one user per buffer. */
286         BufferView * getUser() const;
287
288         ///
289         void ChangeLanguage(Language const * from, Language const * to);
290         ///
291         bool isMultiLingual();
292
293         /// Does this mean that this is buffer local?
294         UndoStack undostack;
295         
296         /// Does this mean that this is buffer local? 
297         UndoStack redostack;
298         
299         ///
300         BufferParams params;
301         
302         /** The list of paragraphs.
303             This is a linked list of paragraph, this list holds the
304             whole contents of the document.
305          */
306         LyXParagraph * paragraph;
307
308         /// LyX version control object.
309         LyXVC lyxvc;
310
311         /// Where to put temporary files.
312         string tmppath;
313
314         /// The path to the document file.
315         string filepath;
316
317         /** If we are writing a nice LaTeX file or not.
318             While writing as LaTeX, tells whether we are
319             doing a 'nice' LaTeX file */
320         bool niceFile;
321
322         /// Used when typesetting to place errorboxes.
323         TexRow texrow;
324 private:
325 #ifndef NEW_INSETS
326         ///
327         void linuxDocHandleFootnote(std::ostream & os,
328                                     LyXParagraph * & par, int depth);
329 #endif
330         ///
331         void DocBookHandleCaption(std::ostream & os, string & inner_tag,
332                                   int depth, int desc_on,
333                                   LyXParagraph * & par);
334 #ifndef NEW_INSETS
335         ///
336         void DocBookHandleFootnote(std::ostream & os,
337                                    LyXParagraph * & par, int depth);
338 #endif
339         ///
340         void sgmlOpenTag(std::ostream & os, int depth,
341                          string const & latexname) const;
342         ///
343         void sgmlCloseTag(std::ostream & os, int depth,
344                           string const & latexname) const;
345         ///
346         void LinuxDocError(LyXParagraph * par, int pos,
347                            string const & message);
348         ///
349         void SimpleLinuxDocOnePar(std::ostream & os, LyXParagraph * par,
350                                   int desc_on, int depth);
351
352         /// LinuxDoc.
353         void push_tag(std::ostream & os, string const & tag,
354                       int & pos, char stack[5][3]);
355         
356         /// LinuxDoc.
357         void pop_tag(std::ostream & os, string const & tag,
358                      int & pos, char stack[5][3]);
359
360         /// is save needed
361         mutable bool lyx_clean;
362         
363         /// is autosave needed
364         mutable bool bak_clean;
365         
366         /// is this a unnamed file (New...)
367         bool unnamed;
368
369         /// is regenerating #.tex# necessary
370         DEPCLEAN * dep_clean;
371
372         /// buffer is r/o
373         bool read_only;
374
375         /// name of the file the buffer is associated with.
376         string filename;
377
378         /// Format number of buffer
379         int file_format;
380         /** A list of views using this buffer.
381             Why not keep a list of the BufferViews that use this buffer?
382
383             At least then we don't have to do a lot of magic like:
384             #buffer->lyx_gui->bufferview->updateLayoutChoice#. Just ask each
385             of the buffers in the list of users to do a #updateLayoutChoice#.
386         */
387         BufferView * users;
388
389 public:
390         ///
391         class inset_iterator {
392         public:
393                 typedef std::input_iterator_tag iterator_category;
394                 typedef Inset value_type;
395                 typedef ptrdiff_t difference_type;
396                 typedef Inset * pointer;
397                 typedef Inset & reference;
398                 
399                 
400                 ///
401                 inset_iterator() : par(0) /*, it(0)*/ {}
402                 //
403                 inset_iterator(LyXParagraph * paragraph) : par(paragraph) {
404                         SetParagraph();
405                 }
406                 ///
407                 inset_iterator(LyXParagraph * paragraph,
408                                LyXParagraph::size_type pos);
409                 ///
410                 inset_iterator & operator++() { // prefix ++
411                         if (par) {
412                                 ++it;
413                                 if (it == par->inset_iterator_end()) {
414 #ifndef NEW_INSETS
415                                         par = par->next_;
416 #else
417                                         par = par->next();
418 #endif
419                                         SetParagraph();
420                                 }
421                         }
422                         return *this;
423                 }
424                 ///
425                 inset_iterator operator++(int) { // postfix ++
426                         inset_iterator tmp(par, it.getPos());
427                         if (par) {
428                                 ++it;
429                                 if (it == par->inset_iterator_end()) {
430 #ifndef NEW_INSETS
431                                         par = par->next_;
432 #else
433                                         par = par->next();
434 #endif
435                                         SetParagraph();
436                                 }
437                         }
438                         return tmp;
439                 }
440                 ///
441                 Inset * operator*() { return *it; }
442                 
443                 ///
444                 LyXParagraph * getPar() { return par; }
445                 ///
446                 LyXParagraph::size_type getPos() const { return it.getPos(); }
447                 ///
448                 friend
449                 bool operator==(inset_iterator const & iter1,
450                                 inset_iterator const & iter2);
451         private:
452                 ///
453                 void SetParagraph();
454                 ///
455                 LyXParagraph * par;
456                 ///
457                 LyXParagraph::inset_iterator it;
458         };
459
460         ///
461         inset_iterator inset_iterator_begin() {
462                 return inset_iterator(paragraph);
463         }
464         ///
465         inset_iterator inset_iterator_end() {
466                 return inset_iterator();
467         }
468 };
469
470
471 inline
472 void Buffer::addUser(BufferView * u)
473 {
474         users = u;
475 }
476
477
478 inline
479 void Buffer::delUser(BufferView *)
480 {
481         users = 0;
482 }
483         
484
485 inline
486 void Buffer::redraw()
487 {
488         users->redraw(); 
489         users->fitCursor(users->text); 
490 }
491
492
493 inline
494 Language const * Buffer::GetLanguage() const
495 {
496         return params.language;
497 }
498         
499
500 inline
501 bool Buffer::isLyxClean() const
502 {
503         return lyx_clean;
504 }
505         
506
507 inline
508 bool Buffer::isBakClean() const
509 {
510         return bak_clean;
511 }
512
513
514 inline
515 void Buffer::markLyxClean() const
516
517         if (!lyx_clean) {
518                 lyx_clean = true; 
519                 updateTitles();
520         }
521         // if the .lyx file has been saved, we don't need an
522         // autosave 
523         bak_clean = true;
524 }
525
526
527 inline
528 void Buffer::markBakClean()
529 {
530         bak_clean = true;
531 }
532
533
534 inline
535 void Buffer::setUnnamed(bool flag)
536 {
537         unnamed = flag;
538 }
539
540
541 inline
542 bool Buffer::isUnnamed()
543 {
544         return unnamed;
545 }
546
547
548 inline
549 void Buffer::markDirty()
550 {
551         if (lyx_clean) {
552                 lyx_clean = false;
553                 updateTitles();
554         }
555         bak_clean = false;
556         DEPCLEAN * tmp = dep_clean;
557         while (tmp) {
558                 tmp->clean = false;
559                 tmp = tmp->next;
560         }
561 }
562
563
564 inline
565 string const & Buffer::fileName() const
566 {
567         return filename;
568 }
569
570
571 inline
572 bool Buffer::isReadonly() const
573 {
574         return read_only;
575 }
576
577
578 inline
579 BufferView * Buffer::getUser() const
580 {
581         return users;
582 }
583
584
585 inline  
586 void Buffer::setParentName(string const & name)
587 {
588         params.parentname = name;    
589 }
590
591
592 ///
593 inline
594 bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b) {
595         return a.par == b.par && a.str == b.str;
596         // No need to compare depth.
597 }
598
599
600 ///
601 inline
602 bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b) {
603         return !(a == b);
604         // No need to compare depth.
605 }
606
607 ///
608 inline
609 bool operator==(Buffer::inset_iterator const & iter1,
610                 Buffer::inset_iterator const & iter2) {
611         return iter1.par == iter2.par
612                 && (iter1.par == 0 || iter1.it == iter2.it);
613 }
614
615 ///
616 inline
617 bool operator!=(Buffer::inset_iterator const & iter1,
618                 Buffer::inset_iterator const & iter2) {
619         return !(iter1 == iter2);
620 }
621 #endif
622