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