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