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