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