]> git.lyx.org Git - lyx.git/blob - src/Buffer.h
Fix bug 5859.
[lyx.git] / src / Buffer.h
1 // -*- C++ -*-
2 /**
3  * \file Buffer.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Lars Gullik Bjønnes
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #ifndef BUFFER_H
13 #define BUFFER_H
14
15 #include "insets/InsetCode.h"
16
17 #include "support/strfwd.h"
18 #include "support/types.h"
19 #include "support/SignalSlot.h"
20
21 #include <string>
22 #include <vector>
23
24
25 namespace lyx {
26
27 class BiblioInfo;
28 class BufferParams;
29 class BufferSet;
30 class DocIterator;
31 class ErrorItem;
32 class ErrorList;
33 class FuncRequest;
34 class Inset;
35 class InsetRef;
36 class InsetLabel;
37 class Font;
38 class Format;
39 class Lexer;
40 class LyXRC;
41 class Text;
42 class LyXVC;
43 class LaTeXFeatures;
44 class Language;
45 class MacroData;
46 class MacroNameSet;
47 class MacroSet;
48 class OutputParams;
49 class Paragraph;
50 class ParConstIterator;
51 class ParIterator;
52 class ParagraphList;
53 class TeXErrors;
54 class TexRow;
55 class TocBackend;
56 class Undo;
57
58 namespace frontend {
59 class GuiBufferDelegate;
60 class WorkAreaManager;
61 }
62
63 namespace support {
64 class FileName;
65 class FileNameList;
66 }
67
68 /** The buffer object.
69  * This is the buffer object. It contains all the informations about
70  * a document loaded into LyX.
71  * The buffer object owns the Text (wrapped in an InsetText), which
72  * contains the individual paragraphs of the document.
73  *
74  *
75  * I am not sure if the class is complete or
76  * minimal, probably not.
77  * \author Lars Gullik Bjønnes
78  */
79 class Buffer {
80 public:
81         /// What type of log will \c getLogName() return?
82         enum LogType {
83                 latexlog, ///< LaTeX log
84                 buildlog  ///< Literate build log
85         };
86
87         /// Result of \c readFile()
88         enum ReadStatus {
89                 failure, ///< The file could not be read
90                 success, ///< The file could not be read
91                 wrongversion ///< The version of the file does not match ours
92         };
93
94
95         /// Method to check if a file is externally modified, used by
96         /// isExternallyModified()
97         /**
98          * timestamp is fast but inaccurate. For example, the granularity
99          * of timestamp on a FAT filesystem is 2 second. Also, various operations
100          * may touch the timestamp of a file even when its content is unchanged.
101          *
102          * checksum is accurate but slow, which can be a problem when it is
103          * frequently used, or used for a large file on a slow (network) file
104          * system.
105          *
106          * FIXME: replace this method with support/FileMonitor.
107          */
108         enum CheckMethod {
109                 checksum_method,  ///< Use file checksum
110                 timestamp_method, ///< Use timestamp, and checksum if timestamp has changed
111         };
112
113         ///
114         enum UpdateScope {
115                 UpdateMaster,
116                 UpdateChildOnly
117         };
118
119         /// Constructor
120         explicit Buffer(std::string const & file, bool b = false);
121
122         /// Destructor
123         ~Buffer();
124
125         /** High-level interface to buffer functionality.
126             This function parses a command string and executes it
127         */
128         bool dispatch(std::string const & command, bool * result = 0);
129
130         /// Maybe we know the function already by number...
131         bool dispatch(FuncRequest const & func, bool * result = 0);
132
133         /// Load the autosaved file.
134         void loadAutoSaveFile();
135
136         /// read a new document from a string
137         bool readString(std::string const &);
138         /// load a new file
139         bool readFile(support::FileName const & filename);
140
141         /// read the header, returns number of unknown tokens
142         int readHeader(Lexer & lex);
143
144         /** Reads a file without header.
145             \param par if != 0 insert the file.
146             \return \c true if file is not completely read.
147         */
148         bool readDocument(Lexer &);
149
150         ///
151         void insertStringAsLines(ParagraphList & plist,
152                 pit_type &, pos_type &,
153                 Font const &, docstring const &, bool);
154         ///
155         DocIterator getParFromID(int id) const;
156         /// do we have a paragraph with this id?
157         bool hasParWithID(int id) const;
158
159         ///
160         frontend::WorkAreaManager & workAreaManager() const;
161
162         /** Save file.
163             Takes care of auto-save files and backup file if requested.
164             Returns \c true if the save is successful, \c false otherwise.
165         */
166         bool save() const;
167
168         /// Write document to stream. Returns \c false if unsuccesful.
169         bool write(std::ostream &) const;
170         /// Write file. Returns \c false if unsuccesful.
171         bool writeFile(support::FileName const &) const;
172
173         /// Loads LyX file \c filename into buffer, *  and \return success
174         bool loadLyXFile(support::FileName const & s);
175
176         /// Fill in the ErrorList with the TeXErrors
177         void bufferErrors(TeXErrors const &, ErrorList &) const;
178
179         /// Just a wrapper for writeLaTeXSource, first creating the ofstream.
180         bool makeLaTeXFile(support::FileName const & filename,
181                            std::string const & original_path,
182                            OutputParams const &,
183                            bool output_preamble = true,
184                            bool output_body = true) const;
185         /** Export the buffer to LaTeX.
186             If \p os is a file stream, and params().inputenc is "auto" or
187             "default", and the buffer contains text in different languages
188             with more than one encoding, then this method will change the
189             encoding associated to \p os. Therefore you must not call this
190             method with a string stream if the output is supposed to go to a
191             file. \code
192             ofdocstream ofs;
193             ofs.open("test.tex");
194             writeLaTeXSource(ofs, ...);
195             ofs.close();
196             \endcode is NOT equivalent to \code
197             odocstringstream oss;
198             writeLaTeXSource(oss, ...);
199             ofdocstream ofs;
200             ofs.open("test.tex");
201             ofs << oss.str();
202             ofs.close();
203             \endcode
204          */
205         void writeLaTeXSource(odocstream & os,
206                            std::string const & original_path,
207                            OutputParams const &,
208                            bool output_preamble = true,
209                            bool output_body = true) const;
210         ///
211         void makeDocBookFile(support::FileName const & filename,
212                              OutputParams const & runparams_in,
213                              bool only_body = false) const;
214         ///
215         void writeDocBookSource(odocstream & os, std::string const & filename,
216                              OutputParams const & runparams_in,
217                              bool only_body = false) const;
218         /// returns the main language for the buffer (document)
219         Language const * language() const;
220         /// get l10n translated to the buffers language
221         docstring const B_(std::string const & l10n) const;
222
223         ///
224         int runChktex();
225         /// return true if the main lyx file does not need saving
226         bool isClean() const;
227         ///
228         bool isBakClean() const;
229         ///
230         bool isDepClean(std::string const & name) const;
231
232         /// whether or not disk file has been externally modified
233         bool isExternallyModified(CheckMethod method) const;
234
235         /// save timestamp and checksum of the given file.
236         void saveCheckSum(support::FileName const & file) const;
237
238         /// mark the main lyx file as not needing saving
239         void markClean() const;
240
241         ///
242         void markBakClean() const;
243
244         ///
245         void markDepClean(std::string const & name);
246
247         ///
248         void setUnnamed(bool flag = true);
249
250         ///
251         bool isUnnamed() const;
252
253         /// Mark this buffer as dirty.
254         void markDirty();
255
256         /// Returns the buffer's filename. It is always an absolute path.
257         support::FileName fileName() const;
258
259         /// Returns the buffer's filename. It is always an absolute path.
260         std::string absFileName() const;
261
262         /// Returns the the path where the buffer lives.
263         /// It is always an absolute path.
264         std::string filePath() const;
265
266         /** A transformed version of the file name, adequate for LaTeX.
267             \param no_path optional if \c true then the path is stripped.
268         */
269         std::string latexName(bool no_path = true) const;
270
271         /// Get thee name and type of the log.
272         std::string logName(LogType * type = 0) const;
273
274         /// Change name of buffer. Updates "read-only" flag.
275         void setFileName(std::string const & newfile);
276
277         /// Set document's parent Buffer.
278         void setParent(Buffer const *);
279         Buffer const * parent() const;
280
281         // Collect all relative buffer
282         std::vector<Buffer const *> allRelatives() const;
283
284         /** Get the document's master (or \c this if this is not a
285             child document)
286          */
287         Buffer const * masterBuffer() const;
288
289         /// \return true if \p child is a child of this \c Buffer.
290         bool isChild(Buffer * child) const;
291         
292         /// return a vector with all children and grandchildren
293         std::vector<Buffer *> getChildren() const;
294
295         /// Is buffer read-only?
296         bool isReadonly() const;
297
298         /// Set buffer read-only flag
299         void setReadonly(bool flag = true);
300
301         /// returns \c true if the buffer contains a LaTeX document
302         bool isLatex() const;
303         /// returns \c true if the buffer contains a DocBook document
304         bool isDocBook() const;
305         /// returns \c true if the buffer contains a Wed document
306         bool isLiterate() const;
307
308         /** Validate a buffer for LaTeX.
309             This validates the buffer, and returns a struct for use by
310             #makeLaTeX# and others. Its main use is to figure out what
311             commands and packages need to be included in the LaTeX file.
312             It (should) also check that the needed constructs are there
313             (i.e. that the \refs points to coresponding \labels). It
314             should perhaps inset "error" insets to help the user correct
315             obvious mistakes.
316         */
317         void validate(LaTeXFeatures &) const;
318
319         /// Update the cache with all bibfiles in use (including bibfiles
320         /// of loaded child documents).
321         void updateBibfilesCache(UpdateScope scope = UpdateMaster) const;
322         ///
323         void invalidateBibinfoCache();
324         /// Return the cache with all bibfiles in use (including bibfiles
325         /// of loaded child documents).
326         support::FileNameList const & 
327                 getBibfilesCache(UpdateScope scope = UpdateMaster) const;
328         /// \return the bibliography information for this buffer's master,
329         /// or just for it, if it isn't a child.
330         BiblioInfo const & masterBibInfo() const;
331         /// \return the bibliography information for this buffer ONLY.
332         BiblioInfo const & localBibInfo() const;
333         ///
334         void getLabelList(std::vector<docstring> &) const;
335
336         ///
337         void changeLanguage(Language const * from, Language const * to);
338
339         ///
340         bool isMultiLingual() const;
341
342         ///
343         BufferParams & params();
344         BufferParams const & params() const;
345
346         /** The list of paragraphs.
347             This is a linked list of paragraph, this list holds the
348             whole contents of the document.
349          */
350         ParagraphList & paragraphs();
351         ParagraphList const & paragraphs() const;
352
353         /// LyX version control object.
354         LyXVC & lyxvc();
355         LyXVC const & lyxvc() const;
356
357         /// Where to put temporary files.
358         std::string const temppath() const;
359
360         /// Used when typesetting to place errorboxes.
361         TexRow const & texrow() const;
362         TexRow & texrow();
363
364         ///
365         ParIterator par_iterator_begin();
366         ///
367         ParConstIterator par_iterator_begin() const;
368         ///
369         ParIterator par_iterator_end();
370         ///
371         ParConstIterator par_iterator_end() const;
372
373         // Position of the child buffer where it appears first in the master.
374         DocIterator firstChildPosition(Buffer const * child);
375
376         /** \returns true only when the file is fully loaded.
377          *  Used to prevent the premature generation of previews
378          *  and by the citation inset.
379          */
380         bool isFullyLoaded() const;
381         /// Set by buffer_funcs' newFile.
382         void setFullyLoaded(bool);
383
384         /// Our main text (inside the top InsetText)
385         Text & text() const;
386
387         /// Our top InsetText
388         Inset & inset() const;
389
390         //
391         // Macro handling
392         //
393         /// Collect macro definitions in paragraphs
394         void updateMacros() const;
395         /// Iterate through the whole buffer and try to resolve macros
396         void updateMacroInstances() const;
397
398         /// List macro names of this buffer, the parent and the children
399         void listMacroNames(MacroNameSet & macros) const;
400         /// Collect macros of the parent and its children in front of this buffer.
401         void listParentMacros(MacroSet & macros, LaTeXFeatures & features) const;
402
403         /// Return macro defined before pos (or in the master buffer)
404         MacroData const * getMacro(docstring const & name, DocIterator const & pos, bool global = true) const;
405         /// Return macro defined anywhere in the buffer (or in the master buffer)
406         MacroData const * getMacro(docstring const & name, bool global = true) const;
407         /// Return macro defined before the inclusion of the child
408         MacroData const * getMacro(docstring const & name, Buffer const & child, bool global = true) const;
409
410         /// Replace the inset contents for insets which InsetCode is equal
411         /// to the passed \p inset_code.
412         void changeRefsIfUnique(docstring const & from, docstring const & to,
413                 InsetCode code);
414
415         /// get source code (latex/docbook) for some paragraphs, or all paragraphs
416         /// including preamble
417         void getSourceCode(odocstream & os, pit_type par_begin, pit_type par_end,
418                 bool full_source) const;
419
420         /// Access to error list.
421         /// This method is used only for GUI visualisation of Buffer related
422         /// errors (like parsing or LateX compilation). This method is const
423         /// because modifying the returned ErrorList does not touch the document
424         /// contents.
425         ErrorList & errorList(std::string const & type) const;
426
427         /// The Toc backend.
428         /// This is useful only for screen visualisation of the Buffer. This
429         /// method is const because modifying this backend does not touch
430         /// the document contents.
431         TocBackend & tocBackend() const;
432
433         ///
434         Undo & undo();
435
436         /// This function is called when the buffer is changed.
437         void changed() const;
438         ///
439         void updateTocItem(std::string const &, DocIterator const &) const;
440         /// This function is called when the buffer structure is changed.
441         void structureChanged() const;
442         /// This function is called when some parsing error shows up.
443         void errors(std::string const & err) const;
444         /// This function is called when the buffer busy status change.
445         void setBusy(bool on) const;
446         /// This function is called when the buffer readonly status change.
447         void setReadOnly(bool on) const;
448         /// Update window titles of all users.
449         void updateTitles() const;
450         /// Reset autosave timers for all users.
451         void resetAutosaveTimers() const;
452         ///
453         void message(docstring const & msg) const;
454
455         ///
456         void setGuiDelegate(frontend::GuiBufferDelegate * gui);
457         ///
458         bool hasGuiDelegate() const;
459
460         ///
461         void autoSave() const;
462
463         /// return the format of the buffer on a string
464         std::string bufferFormat() const;
465
466         ///
467         bool doExport(std::string const & format, bool put_in_tempdir,
468                 std::string & result_file) const;
469         ///
470         bool doExport(std::string const & format, bool put_in_tempdir) const;
471         ///
472         bool preview(std::string const & format) const;
473         ///
474         bool isExportable(std::string const & format) const;
475         ///
476         std::vector<Format const *> exportableFormats(bool only_viewable) const;
477
478         ///
479         typedef std::vector<std::pair<InsetRef *, ParIterator> > References;
480         References & references(docstring const & label);
481         References const & references(docstring const & label) const;
482         void clearReferenceCache() const;
483         void setInsetLabel(docstring const & label, InsetLabel const * il);
484         InsetLabel const * insetLabel(docstring const & label) const;
485
486         /// sets the buffer_ member for every inset in this buffer.
487         // FIXME This really shouldn't be needed, but at the moment it's not
488         // clear how to do it just for the individual pieces we need.
489         void setBuffersForInsets() const;
490         ///
491         void updateLabels(UpdateScope = UpdateMaster) const;
492         ///
493         void updateLabels(ParIterator & parit) const;
494
495         /// Find next word starting from \p from.
496         /// \p from initial position to search, will then points to the next
497         ///    word.
498         /// \p to will points to the end of the next word.
499         /// \p word will contain the found word if any.
500         /// \return true if a new word was found.
501         bool nextWord(DocIterator & from, DocIterator & to,
502                 docstring & word) const;
503
504 private:
505         /// search for macro in local (buffer) table or in children
506         MacroData const * getBufferMacro(docstring const & name,
507                                          DocIterator const & pos) const;
508         /** Update macro table starting with position of it
509             \param it in some text inset
510         */
511         void updateMacros(DocIterator & it,
512                                      DocIterator & scope) const;
513
514         ///
515         void collectRelatives(BufferSet & bufs) const;
516
517         ///
518         bool readFileHelper(support::FileName const & s);
519         ///
520         std::vector<std::string> backends() const;
521         /** Inserts a file into a document
522             \return \c false if method fails.
523         */
524         ReadStatus readFile(Lexer &, support::FileName const & filename,
525                             bool fromString = false);
526
527         /// Use the Pimpl idiom to hide the internals.
528         class Impl;
529         /// The pointer never changes although *pimpl_'s contents may.
530         Impl * const d;
531
532         frontend::GuiBufferDelegate * gui_;
533
534         /// This function is called when the buffer structure is changed.
535         Signal structureChanged_;
536         /// This function is called when some parsing error shows up.
537         //Signal errors(std::string const &) = 0;
538         /// This function is called when some message shows up.
539         //Signal message(docstring const &) = 0;
540         /// This function is called when the buffer busy status change.
541         //Signal setBusy(bool) = 0;
542         /// Reset autosave timers for all users.
543         Signal resetAutosaveTimers_;
544 };
545
546
547 } // namespace lyx
548
549 #endif