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