]> git.lyx.org Git - lyx.git/blob - src/buffer.h
47d94282eaa51b0f2ac6bb9f3399e8c224f5ea3f
[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 #ifndef BUFFER_H
14 #define BUFFER_H
15
16 #ifdef __GNUG__
17 #pragma interface
18 #endif
19
20 #include "LString.h"
21 #include "undo.h"
22 #include "undostack.h"
23 #include "lyxvc.h"
24 #include "bufferparams.h"
25 #include "texrow.h"
26 #include "paragraph.h"
27
28 class BufferView;
29 class LyXRC;
30 class TeXErrors;
31 class LaTeXFeatures;
32 class Language;
33
34 ///
35 struct DEPCLEAN {
36         ///
37         bool clean;
38         ///
39         string master;
40         ///
41         DEPCLEAN * next;
42 };
43
44 /** The buffer object.
45   This is the buffer object. It contains all the informations about
46   a document loaded into LyX. I am not sure if the class is complete or
47   minimal, probably not.
48   \author Lars Gullik Bjønnes
49   */
50 class Buffer {
51 public:
52         /// What type of log will \c getLogName() return?
53         enum LogType {
54                 latexlog, ///< LaTeX log
55                 buildlog  ///< Literate build log
56         };
57
58         /** Constructor
59             \param file
60             \param b  optional \c false by default
61         */
62         explicit Buffer(string const & file, bool b = false);
63         
64         /// Destructor
65         ~Buffer();
66
67         /** Save the buffer's parameters as user default.
68             This function saves a file \c user_lyxdir/templates/defaults.lyx
69             which parameters are those of the current buffer. This file
70             is used as a default template when creating a new
71             file. Returns \c true on success.
72         */
73         bool saveParamsAsDefaults();
74
75         /** High-level interface to buffer functionality.
76             This function parses a command string and executes it
77         */
78         bool dispatch(string const & command);
79
80         /// Maybe we know the function already by number...
81         bool dispatch(int ac, string const & argument);
82
83         /// 
84         void resizeInsets(BufferView *);
85
86         /// Update window titles of all users.
87         void updateTitles() const;
88
89         /// Reset autosave timers for all users.
90         void resetAutosaveTimers() const;
91
92         /** Adds the BufferView to the users list.
93             Later this func will insert the \c BufferView into a real list,
94             not just setting a pointer.
95         */
96         void addUser(BufferView * u);
97
98         /** Removes the #BufferView# from the users list.
99             Since we only can have one at the moment, we just reset it.
100         */
101         void delUser(BufferView *);
102         
103         ///
104         void redraw();
105
106         /// Load the autosaved file.
107         void loadAutoSaveFile();
108         
109         /** Reads a file. 
110             \param par if != 0 insert the file.
111             \return \c false if method fails.
112         */
113         bool readFile(LyXLex &, Paragraph * par = 0);
114         
115         /** Reads a file without header.
116             \param par if != 0 insert the file.
117             \return \c false if file is not completely read.
118         */
119         bool readLyXformat2(LyXLex &, Paragraph * par = 0);
120
121         /// This parses a single LyXformat-Token.
122         bool parseSingleLyXformat2Token(LyXLex &, Paragraph *& par,
123                                         Paragraph *& return_par,
124                                         string const & token, int & pos,
125                                         Paragraph::depth_type & depth, 
126                                         LyXFont &);
127 private:
128         /// Parse a single inset.
129         void readInset(LyXLex &, Paragraph *& par, int & pos, LyXFont &);
130 public:
131         /** Save file.
132             Takes care of auto-save files and backup file if requested.
133             Returns \c true if the save is successful, \c false otherwise.
134         */
135         bool save() const;
136         
137         /// Write file. Returns \c false if unsuccesful.
138         bool writeFile(string const &, bool) const;
139         
140         ///
141         void writeFileAscii(string const & , int);
142         ///
143         void writeFileAscii(std::ostream &, int);
144         ///
145         string const asciiParagraph(Paragraph const *,
146                                     unsigned int linelen) const;
147         ///
148         void makeLaTeXFile(string const & filename,
149                            string const & original_path,
150                            bool nice, bool only_body = false);
151         /** LaTeX all paragraphs from par to endpar.
152             \param \a endpar if == 0 then to the end
153         */
154         void latexParagraphs(std::ostream & os, Paragraph * par,
155                              Paragraph * endpar, TexRow & texrow) const;
156
157         ///
158         void simpleDocBookOnePar(std::ostream &, string & extra,
159                                  Paragraph * par, int & desc_on,
160                                  Paragraph::depth_type depth) const ;
161
162         ///
163         int runChktex();
164
165         ///
166         void makeLinuxDocFile(string const & filename,
167                               bool nice, bool only_body = false);
168         ///
169         void makeDocBookFile(string const & filename,
170                              bool nice, bool only_body = false);
171
172         /// returns the main language for the buffer (document)
173         Language const * getLanguage() const;
174         ///
175         bool isLyxClean() const;
176         ///
177         bool isBakClean() const;
178         ///
179         bool isDepClean(string const & name) const;
180         
181         ///
182         void markLyxClean() const;
183
184         ///
185         void markBakClean();
186         
187         ///
188         void markDepClean(string const & name);
189         
190         ///
191         void setUnnamed(bool flag = true);
192
193         ///
194         bool isUnnamed();
195
196         /// Mark this buffer as dirty.
197         void markDirty();
198
199         /// Returns the buffers filename.
200         string const & fileName() const;
201
202         /** A transformed version of the file name, adequate for LaTeX.
203             \param no_path optional if \c true then the path is stripped.
204         */
205         string const getLatexName(bool no_path = true) const;
206
207         /// Get the name and type of the log.
208         std::pair<LogType, string> const getLogName() const;
209  
210         /// Change name of buffer. Updates "read-only" flag.
211         void setFileName(string const & newfile);
212
213         /// Name of the document's parent
214         void setParentName(string const &);
215
216         /// Is buffer read-only?
217         bool isReadonly() const;
218
219         /// Set buffer read-only flag
220         void setReadonly(bool flag = true);
221
222         /// returns \c true if the buffer contains a LaTeX document
223         bool isLatex() const;
224         /// returns \c true if the buffer contains a LinuxDoc document
225         bool isLinuxDoc() const;
226         /// returns \c true if the buffer contains a DocBook document
227         bool isDocBook() const;
228         /** returns \c true if the buffer contains either a LinuxDoc
229             or DocBook document */
230         bool isSGML() const;
231         /// returns \c true if the buffer contains a Wed document
232         bool isLiterate() const;
233
234         ///
235         void setPaperStuff();
236
237         /** Validate a buffer for LaTeX.
238             This validates the buffer, and returns a struct for use by
239             #makeLaTeX# and others. Its main use is to figure out what
240             commands and packages need to be included in the LaTeX file.
241             It (should) also check that the needed constructs are there
242             (i.e. that the \refs points to coresponding \labels). It
243             should perhaps inset "error" insets to help the user correct
244             obvious mistakes.
245         */
246         void validate(LaTeXFeatures &) const;
247
248         ///
249         string const getIncludeonlyList(char delim = ',');
250         ///
251         std::vector<std::pair<string, string> > const getBibkeyList();
252         ///
253         struct TocItem {
254                 TocItem(Paragraph * p, int d, string const & s)
255                         : par(p), depth(d), str(s) {}
256                 ///
257                 Paragraph * par;
258                 ///
259                 int depth;
260                 ///
261                 string str;
262         };
263         ///
264         typedef std::vector<TocItem> SingleList;
265         ///
266         typedef std::map<string, SingleList> Lists;
267         ///
268         Lists const getLists() const;
269         ///
270         std::vector<string> const getLabelList();
271
272         /** This will clearly have to change later. Later we can have more
273             than one user per buffer. */
274         BufferView * getUser() const;
275
276         ///
277         void changeLanguage(Language const * from, Language const * to);
278         ///
279         bool isMultiLingual();
280
281         /// Does this mean that this is buffer local?
282         UndoStack undostack;
283         
284         /// Does this mean that this is buffer local? 
285         UndoStack redostack;
286         
287         ///
288         BufferParams params;
289         
290         /** The list of paragraphs.
291             This is a linked list of paragraph, this list holds the
292             whole contents of the document.
293          */
294         Paragraph * paragraph;
295
296         /// LyX version control object.
297         LyXVC lyxvc;
298
299         /// Where to put temporary files.
300         string tmppath;
301
302         /// The path to the document file.
303         string filepath;
304
305         /** If we are writing a nice LaTeX file or not.
306             While writing as LaTeX, tells whether we are
307             doing a 'nice' LaTeX file */
308         bool niceFile;
309
310         /// Used when typesetting to place errorboxes.
311         TexRow texrow;
312 private:
313         ///
314         void docBookHandleCaption(std::ostream & os, string & inner_tag,
315                                   Paragraph::depth_type depth, int desc_on,
316                                   Paragraph * & par);
317         /// Open SGML/XML tag.
318         void sgmlOpenTag(std::ostream & os, Paragraph::depth_type depth,
319                          string const & latexname) const;
320         /// Closes SGML/XML tag.
321         void sgmlCloseTag(std::ostream & os, Paragraph::depth_type depth,
322                           string const & latexname) const;
323         ///
324         void linuxDocError(Paragraph * par, int pos,
325                            string const & message);
326         ///
327         void simpleLinuxDocOnePar(std::ostream & os, Paragraph * par, 
328                                   Paragraph::depth_type depth);
329
330         /// is save needed
331         mutable bool lyx_clean;
332         
333         /// is autosave needed
334         mutable bool bak_clean;
335         
336         /// is this a unnamed file (New...)
337         bool unnamed;
338
339         /// is regenerating #.tex# necessary
340         DEPCLEAN * dep_clean;
341
342         /// buffer is r/o
343         bool read_only;
344
345         /// name of the file the buffer is associated with.
346         string filename;
347
348         /// Format number of buffer
349         int file_format;
350         /** A list of views using this buffer.
351             Why not keep a list of the BufferViews that use this buffer?
352
353             At least then we don't have to do a lot of magic like:
354             #buffer->lyx_gui->bufferview->updateLayoutChoice#. Just ask each
355             of the buffers in the list of users to do a #updateLayoutChoice#.
356         */
357         BufferView * users;
358
359 public:
360         ///
361         class inset_iterator {
362         public:
363                 typedef std::input_iterator_tag iterator_category;
364                 typedef Inset value_type;
365                 typedef ptrdiff_t difference_type;
366                 typedef Inset * pointer;
367                 typedef Inset & reference;
368                 
369                 
370                 ///
371                 inset_iterator() : par(0) /*, it(0)*/ {}
372                 //
373                 inset_iterator(Paragraph * paragraph) : par(paragraph) {
374                         setParagraph();
375                 }
376                 ///
377                 inset_iterator(Paragraph * paragraph,
378                                Paragraph::size_type pos);
379                 ///
380                 inset_iterator & operator++() { // prefix ++
381                         if (par) {
382                                 ++it;
383                                 if (it == par->inset_iterator_end()) {
384                                         par = par->next();
385                                         setParagraph();
386                                 }
387                         }
388                         return *this;
389                 }
390                 ///
391                 inset_iterator operator++(int) { // postfix ++
392                         inset_iterator tmp(par, it.getPos());
393                         if (par) {
394                                 ++it;
395                                 if (it == par->inset_iterator_end()) {
396                                         par = par->next();
397                                         setParagraph();
398                                 }
399                         }
400                         return tmp;
401                 }
402                 ///
403                 Inset * operator*() { return *it; }
404                 
405                 ///
406                 Paragraph * getPar() { return par; }
407                 ///
408                 Paragraph::size_type getPos() const { return it.getPos(); }
409                 ///
410                 friend
411                 bool operator==(inset_iterator const & iter1,
412                                 inset_iterator const & iter2);
413         private:
414                 ///
415                 void setParagraph();
416                 ///
417                 Paragraph * par;
418                 ///
419                 Paragraph::inset_iterator it;
420         };
421
422         ///
423         inset_iterator inset_iterator_begin() {
424                 return inset_iterator(paragraph);
425         }
426         ///
427         inset_iterator inset_iterator_end() {
428                 return inset_iterator();
429         }
430         ///
431         inset_iterator inset_const_iterator_begin() const {
432                 return inset_iterator(paragraph);
433         }
434         ///
435         inset_iterator inset_const_iterator_end() const {
436                 return inset_iterator();
437         }
438         ///
439         Inset * getInsetFromID(int id_arg) const;
440 };
441
442
443 inline
444 void Buffer::addUser(BufferView * u)
445 {
446         users = u;
447 }
448
449
450 inline
451 void Buffer::delUser(BufferView *)
452 {
453         users = 0;
454 }
455         
456
457 inline
458 Language const * Buffer::getLanguage() const
459 {
460         return params.language;
461 }
462         
463
464 inline
465 bool Buffer::isLyxClean() const
466 {
467         return lyx_clean;
468 }
469         
470
471 inline
472 bool Buffer::isBakClean() const
473 {
474         return bak_clean;
475 }
476
477
478 inline
479 void Buffer::markLyxClean() const
480
481         if (!lyx_clean) {
482                 lyx_clean = true; 
483                 updateTitles();
484         }
485         // if the .lyx file has been saved, we don't need an
486         // autosave 
487         bak_clean = true;
488 }
489
490
491 inline
492 void Buffer::markBakClean()
493 {
494         bak_clean = true;
495 }
496
497
498 inline
499 void Buffer::setUnnamed(bool flag)
500 {
501         unnamed = flag;
502 }
503
504
505 inline
506 bool Buffer::isUnnamed()
507 {
508         return unnamed;
509 }
510
511
512 inline
513 void Buffer::markDirty()
514 {
515         if (lyx_clean) {
516                 lyx_clean = false;
517                 updateTitles();
518         }
519         bak_clean = false;
520         DEPCLEAN * tmp = dep_clean;
521         while (tmp) {
522                 tmp->clean = false;
523                 tmp = tmp->next;
524         }
525 }
526
527
528 inline
529 string const & Buffer::fileName() const
530 {
531         return filename;
532 }
533
534
535 inline
536 bool Buffer::isReadonly() const
537 {
538         return read_only;
539 }
540
541
542 inline
543 BufferView * Buffer::getUser() const
544 {
545         return users;
546 }
547
548
549 inline  
550 void Buffer::setParentName(string const & name)
551 {
552         params.parentname = name;    
553 }
554
555
556 ///
557 inline
558 bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b) {
559         return a.par == b.par && a.str == b.str;
560         // No need to compare depth.
561 }
562
563
564 ///
565 inline
566 bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b) {
567         return !(a == b);
568         // No need to compare depth.
569 }
570
571
572 ///
573 inline
574 bool operator==(Buffer::inset_iterator const & iter1,
575                 Buffer::inset_iterator const & iter2) {
576         return iter1.par == iter2.par
577                 && (iter1.par == 0 || iter1.it == iter2.it);
578 }
579
580
581 ///
582 inline
583 bool operator!=(Buffer::inset_iterator const & iter1,
584                 Buffer::inset_iterator const & iter2) {
585         return !(iter1 == iter2);
586 }
587 #endif