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