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