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