]> git.lyx.org Git - lyx.git/blob - src/buffer.h
mathed53.diff
[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 #ifndef NEW_INSETS
418                                         par = par->next_;
419 #else
420                                         par = par->next();
421 #endif
422                                         SetParagraph();
423                                 }
424                         }
425                         return *this;
426                 }
427                 ///
428                 inset_iterator operator++(int) { // postfix ++
429                         inset_iterator tmp(par, it.getPos());
430                         if (par) {
431                                 ++it;
432                                 if (it == par->inset_iterator_end()) {
433 #ifndef NEW_INSETS
434                                         par = par->next_;
435 #else
436                                         par = par->next();
437 #endif
438                                         SetParagraph();
439                                 }
440                         }
441                         return tmp;
442                 }
443                 ///
444                 Inset * operator*() { return *it; }
445                 
446                 ///
447                 LyXParagraph * getPar() { return par; }
448                 ///
449                 LyXParagraph::size_type getPos() const { return it.getPos(); }
450                 ///
451                 friend
452                 bool operator==(inset_iterator const & iter1,
453                                 inset_iterator const & iter2);
454         private:
455                 ///
456                 void SetParagraph();
457                 ///
458                 LyXParagraph * par;
459                 ///
460                 LyXParagraph::inset_iterator it;
461         };
462
463         ///
464         inset_iterator inset_iterator_begin() {
465                 return inset_iterator(paragraph);
466         }
467         ///
468         inset_iterator inset_iterator_end() {
469                 return inset_iterator();
470         }
471 };
472
473
474 inline
475 void Buffer::addUser(BufferView * u)
476 {
477         users = u;
478 }
479
480
481 inline
482 void Buffer::delUser(BufferView *)
483 {
484         users = 0;
485 }
486         
487
488 inline
489 void Buffer::redraw()
490 {
491         users->redraw(); 
492         users->fitCursor(users->text); 
493 }
494
495
496 inline
497 Language const * Buffer::GetLanguage() const
498 {
499         return params.language;
500 }
501         
502
503 inline
504 bool Buffer::isLyxClean() const
505 {
506         return lyx_clean;
507 }
508         
509
510 inline
511 bool Buffer::isBakClean() const
512 {
513         return bak_clean;
514 }
515
516
517 inline
518 void Buffer::markLyxClean() const
519
520         if (!lyx_clean) {
521                 lyx_clean = true; 
522                 updateTitles();
523         }
524         // if the .lyx file has been saved, we don't need an
525         // autosave 
526         bak_clean = true;
527 }
528
529
530 inline
531 void Buffer::markBakClean()
532 {
533         bak_clean = true;
534 }
535
536
537 inline
538 void Buffer::setUnnamed(bool flag)
539 {
540         unnamed = flag;
541 }
542
543
544 inline
545 bool Buffer::isUnnamed()
546 {
547         return unnamed;
548 }
549
550
551 inline
552 void Buffer::markDirty()
553 {
554         if (lyx_clean) {
555                 lyx_clean = false;
556                 updateTitles();
557         }
558         bak_clean = false;
559         DEPCLEAN * tmp = dep_clean;
560         while (tmp) {
561                 tmp->clean = false;
562                 tmp = tmp->next;
563         }
564 }
565
566
567 inline
568 string const & Buffer::fileName() const
569 {
570         return filename;
571 }
572
573
574 inline
575 bool Buffer::isReadonly() const
576 {
577         return read_only;
578 }
579
580
581 inline
582 BufferView * Buffer::getUser() const
583 {
584         return users;
585 }
586
587
588 inline  
589 void Buffer::setParentName(string const & name)
590 {
591         params.parentname = name;    
592 }
593
594
595 ///
596 inline
597 bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b) {
598         return a.par == b.par && a.str == b.str;
599         // No need to compare depth.
600 }
601
602
603 ///
604 inline
605 bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b) {
606         return !(a == b);
607         // No need to compare depth.
608 }
609
610 ///
611 inline
612 bool operator==(Buffer::inset_iterator const & iter1,
613                 Buffer::inset_iterator const & iter2) {
614         return iter1.par == iter2.par
615                 && (iter1.par == 0 || iter1.it == iter2.it);
616 }
617
618 ///
619 inline
620 bool operator!=(Buffer::inset_iterator const & iter1,
621                 Buffer::inset_iterator const & iter2) {
622         return !(iter1 == iter2);
623 }
624 #endif
625