]> git.lyx.org Git - lyx.git/blob - src/Buffer.h
6192dd101abf7796daf997e134340234feed69d5
[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 "OutputEnums.h"
16 #include "OutputParams.h"
17
18 #include "insets/InsetCode.h"
19
20 #include "support/strfwd.h"
21 #include "support/types.h"
22
23 #include <map>
24 #include <list>
25 #include <set>
26 #include <string>
27 #include <vector>
28
29
30 namespace lyx {
31
32 class BiblioInfo;
33 class BibTeXInfo;
34 class BufferParams;
35 class DispatchResult;
36 class DocIterator;
37 class docstring_list;
38 class ErrorList;
39 class FuncRequest;
40 class FuncStatus;
41 class Inset;
42 class InsetLabel;
43 class InsetRef;
44 class Font;
45 class Format;
46 class Lexer;
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 namespace graphics {
76 class PreviewLoader;
77 }
78
79
80 class Buffer;
81 typedef std::list<Buffer *> ListOfBuffers;
82
83
84 /** The buffer object.
85  * This is the buffer object. It contains all the informations about
86  * a document loaded into LyX.
87  * The buffer object owns the Text (wrapped in an InsetText), which
88  * contains the individual paragraphs of the document.
89  *
90  *
91  * I am not sure if the class is complete or
92  * minimal, probably not.
93  * \author Lars Gullik Bjønnes
94  */
95 class Buffer {
96 public:
97         /// What type of log will \c getLogName() return?
98         enum LogType {
99                 latexlog, ///< LaTeX log
100                 buildlog  ///< Literate build log
101         };
102
103         /// Result of \c readFile()
104         enum ReadStatus {
105                 ReadSuccess,
106                 ReadCancel,
107                 // failures
108                 ReadFailure,
109                 ReadWrongVersion,
110                 ReadFileNotFound,
111                 ReadVCError,
112                 ReadAutosaveFailure,            
113                 ReadEmergencyFailure,
114                 ReadNoLyXFormat,
115                 ReadDocumentFailure,
116                 // lyx2lyx
117                 LyX2LyXNoTempFile,
118                 LyX2LyXNotFound,
119                 LyX2LyXOlderFormat,
120                 LyX2LyXNewerFormat,
121                 // other
122                 ReadOriginal
123         };
124
125
126         /// Method to check if a file is externally modified, used by
127         /// isExternallyModified()
128         /**
129          * timestamp is fast but inaccurate. For example, the granularity
130          * of timestamp on a FAT filesystem is 2 second. Also, various operations
131          * may touch the timestamp of a file even when its content is unchanged.
132          *
133          * checksum is accurate but slow, which can be a problem when it is
134          * frequently used, or used for a large file on a slow (network) file
135          * system.
136          *
137          * FIXME: replace this method with support/FileMonitor.
138          */
139         enum CheckMethod {
140                 checksum_method, ///< Use file checksum
141                 timestamp_method ///< Use timestamp, and checksum if timestamp has changed
142         };
143
144         ///
145         enum UpdateScope {
146                 UpdateMaster,
147                 UpdateChildOnly
148         };
149
150         /// Constructor
151         explicit Buffer(std::string const & file, bool readonly = false,
152                 Buffer const * cloned_buffer = 0);
153
154         /// Destructor
155         ~Buffer();
156
157         ///
158         Buffer * clone() const;
159         ///
160         bool isClone() const;
161
162         /** High-level interface to buffer functionality.
163             This function parses a command string and executes it.
164         */
165         void dispatch(std::string const & command, DispatchResult & result);
166
167         /// Maybe we know the function already by number...
168         void dispatch(FuncRequest const & func, DispatchResult & result);
169
170         /// Can this function be exectued?
171         /// \return true if we made a decision
172         bool getStatus(FuncRequest const & cmd, FuncStatus & flag);
173
174         ///
175         DocIterator getParFromID(int id) const;
176         /// do we have a paragraph with this id?
177         bool hasParWithID(int id) const;
178
179         ///
180         frontend::WorkAreaManager & workAreaManager() const;
181
182         /** Save file.
183             Takes care of auto-save files and backup file if requested.
184             Returns \c true if the save is successful, \c false otherwise.
185         */
186         bool save() const;
187         /// Renames and saves the buffer
188         bool saveAs(support::FileName const & fn);
189
190         /// Write document to stream. Returns \c false if unsuccessful.
191         bool write(std::ostream &) const;
192         /// Write file. Returns \c false if unsuccessful.
193         bool writeFile(support::FileName const &) const;
194
195         /// \name Functions involved in reading files/strings.
196         //@{
197         /// Loads the LyX file into the buffer. This function
198         /// tries to extract the file from version control if it
199         /// cannot be found. If it can be found, it will try to
200         /// read an emergency save file or an autosave file.
201         /// \sa loadThisLyXFile
202         ReadStatus loadLyXFile();
203         /// Loads the LyX file \c fn into the buffer. If you want
204         /// to check for files in a version control container,
205         /// emergency or autosave files, one should use \c loadLyXFile.
206         /// /sa loadLyXFile
207         ReadStatus loadThisLyXFile(support::FileName const & fn);
208         /// read a new document from a string
209         bool readString(std::string const &);
210         /// Reloads the LyX file
211         ReadStatus reload();
212 //FIXME: The following function should be private
213 //private:
214         /// read the header, returns number of unknown tokens
215         int readHeader(Lexer & lex);
216
217 private:
218         ///
219         typedef std::map<Buffer const *, Buffer *> BufferMap;
220         ///
221         void clone(BufferMap &) const;
222         /// save timestamp and checksum of the given file.
223         void saveCheckSum() const;      
224         /// read a new file
225         ReadStatus readFile(support::FileName const & fn);
226         /// Reads a file without header.
227         /// \param par if != 0 insert the file.
228         /// \return \c true if file is not completely read.
229         bool readDocument(Lexer &);
230         /// Try to extract the file from a version control container
231         /// before reading if the file cannot be found. This is only
232         /// implemented for RCS.
233         /// \sa LyXVC::file_not_found_hook
234         ReadStatus extractFromVC();
235         /// Reads the first tag of a LyX File and 
236         /// returns the file format number.
237         ReadStatus parseLyXFormat(Lexer & lex, support::FileName const & fn,
238                 int & file_format) const;
239         /// Convert the LyX file to the LYX_FORMAT using
240         /// the lyx2lyx script and returns the filename
241         /// of the temporary file to be read
242         ReadStatus convertLyXFormat(support::FileName const & fn, 
243                 support::FileName & tmpfile, int from_format);
244         //@}
245
246 public:
247         /// \name Functions involved in autosave and emergency files.
248         //@{
249         /// Save an autosave file to #filename.lyx#
250         bool autoSave() const;  
251         /// save emergency file
252         /// \return a status message towards the user.
253         docstring emergencyWrite();
254
255 //FIXME:The following function should be private
256 //private:
257         ///
258         void removeAutosaveFile() const;
259         
260 private:
261         /// Try to load an autosave file associated to \c fn.
262         ReadStatus loadAutosave();
263         /// Try to load an emergency file associated to \c fn. 
264         ReadStatus loadEmergency();
265         /// Get the filename of the emergency file associated with the Buffer
266         support::FileName getEmergencyFileName() const;
267         /// Get the filename of the autosave file associated with the Buffer
268         support::FileName getAutosaveFileName() const;
269         ///
270         void moveAutosaveFile(support::FileName const & old) const;
271         //@}
272
273 public:
274         /// Fill in the ErrorList with the TeXErrors
275         void bufferErrors(TeXErrors const &, ErrorList &) const;
276
277         /// Just a wrapper for writeLaTeXSource, first creating the ofstream.
278         bool makeLaTeXFile(support::FileName const & filename,
279                            OutputParams const &,
280                            bool output_preamble = true,
281                            bool output_body = true) const;
282         /** Export the buffer to LaTeX.
283             If \p os is a file stream, and params().inputenc is "auto" or
284             "default", and the buffer contains text in different languages
285             with more than one encoding, then this method will change the
286             encoding associated to \p os. Therefore you must not call this
287             method with a string stream if the output is supposed to go to a
288             file. \code
289             ofdocstream ofs;
290             otexstream os(ofs, texrow);
291             ofs.open("test.tex");
292             writeLaTeXSource(os, ...);
293             ofs.close();
294             \endcode is NOT equivalent to \code
295             odocstringstream oss;
296             otexstream os(oss, texrow);
297             writeLaTeXSource(os, ...);
298             ofdocstream ofs;
299             ofs.open("test.tex");
300             ofs << oss.str();
301             ofs.close();
302             \endcode
303          */
304         void writeLaTeXSource(otexstream & os,
305                            OutputParams const &,
306                            bool output_preamble = true,
307                            bool output_body = true) const;
308         ///
309         void makeDocBookFile(support::FileName const & filename,
310                              OutputParams const & runparams_in,
311                              bool only_body = false) const;
312         ///
313         void writeDocBookSource(odocstream & os, std::string const & filename,
314                              OutputParams const & runparams_in,
315                              bool only_body = false) const;
316         ///
317         void makeLyXHTMLFile(support::FileName const & filename,
318                              OutputParams const & runparams_in) const;
319         ///
320         void writeLyXHTMLSource(odocstream & os,
321                              OutputParams const & runparams_in,
322                              bool only_body = false) const;
323         /// returns the main language for the buffer (document)
324         Language const * language() const;
325         /// get l10n translated to the buffers language
326         docstring const B_(std::string const & l10n) const;
327
328         ///
329         int runChktex();
330         /// return true if the main lyx file does not need saving
331         bool isClean() const;
332         ///
333         bool isDepClean(std::string const & name) const;
334
335         /// whether or not disk file has been externally modified
336         bool isExternallyModified(CheckMethod method) const;
337
338         /// mark the main lyx file as not needing saving
339         void markClean() const;
340
341         ///
342         void markDepClean(std::string const & name);
343
344         ///
345         void setUnnamed(bool flag = true);
346
347         /// Whether or not a filename has been assigned to this buffer
348         bool isUnnamed() const;
349
350         /// Whether or not this buffer is internal.
351         ///
352         /// An internal buffer does not contain a real document, but some auxiliary text segment.
353         /// It is not associated with a filename, it is never saved, thus it does not need to be
354         /// automatically saved, nor it needs to trigger any "do you want to save ?" question.
355         bool isInternal() const;
356
357         /// Mark this buffer as dirty.
358         void markDirty();
359
360         /// Returns the buffer's filename. It is always an absolute path.
361         support::FileName fileName() const;
362
363         /// Returns the buffer's filename. It is always an absolute path.
364         std::string absFileName() const;
365
366         /// Returns the the path where the buffer lives.
367         /// It is always an absolute path.
368         std::string filePath() const;
369
370         /** A transformed version of the file name, adequate for LaTeX.
371             \param no_path optional if \c true then the path is stripped.
372         */
373         std::string latexName(bool no_path = true) const;
374
375         /// Get the name and type of the log.
376         std::string logName(LogType * type = 0) const;
377
378         /// Set document's parent Buffer.
379         void setParent(Buffer const *);
380         Buffer const * parent() const;
381
382         /** Get the document's master (or \c this if this is not a
383             child document)
384          */
385         Buffer const * masterBuffer() const;
386
387         /// \return true if \p child is a child of this \c Buffer.
388         bool isChild(Buffer * child) const;
389         
390         /// \return true if this \c Buffer has children
391         bool hasChildren() const;
392         
393         /// \return a list of the direct children of this Buffer.
394         /// this list has no duplicates and is in the order in which
395         /// the children appear.
396         ListOfBuffers getChildren() const;
397         
398         /// \return a list of all descendents of this Buffer (children,
399         /// grandchildren, etc). this list has no duplicates and is in
400         /// the order in which the children appear.
401         ListOfBuffers getDescendents() const;
402
403         /// Collect all relative buffers, in the order in which they appear.
404         /// I.e., the "root" Buffer is first, then its first child, then any
405         /// of its children, etc. However, there are no duplicates in this
406         /// list.
407         /// This is "stable", too, in the sense that it returns the same
408         /// thing from whichever Buffer it is called.
409         ListOfBuffers allRelatives() const;
410
411         /// Is buffer read-only?
412         bool isReadonly() const;
413
414         /// Set buffer read-only flag
415         void setReadonly(bool flag = true);
416
417         /** Validate a buffer for LaTeX.
418             This validates the buffer, and returns a struct for use by
419             #makeLaTeX# and others. Its main use is to figure out what
420             commands and packages need to be included in the LaTeX file.
421             It (should) also check that the needed constructs are there
422             (i.e. that the \refs points to coresponding \labels). It
423             should perhaps inset "error" insets to help the user correct
424             obvious mistakes.
425         */
426         void validate(LaTeXFeatures &) const;
427
428         /// Reference information is cached in the Buffer, so we do not
429         /// have to check or read things over and over. 
430         ///
431         /// There are two caches.
432         ///
433         /// One is a cache of the BibTeX files from which reference info is
434         /// being gathered. This cache is PER BUFFER, and the cache for the
435         /// master essentially includes the cache for its children. This gets
436         /// invalidated when an InsetBibtex is created, deleted, or modified.
437         /// 
438         /// The other is a cache of the reference information itself. This
439         /// exists only in the master buffer, and when it needs to be updated,
440         /// the children add their information to the master's cache.
441         
442         /// Calling this method invalidates the cache and so requires a
443         /// re-read.
444         void invalidateBibinfoCache() const;
445         /// This invalidates the cache of files we need to check.
446         void invalidateBibfileCache() const;
447         /// Updates the cached bibliography information, checking first to see
448         /// whether the cache is valid. If so, we do nothing. If not, then we
449         /// reload all the BibTeX info.
450         /// Note that this operates on the master document.
451         void reloadBibInfoCache() const;
452         /// \return the bibliography information for this buffer's master,
453         /// or just for it, if it isn't a child.
454         BiblioInfo const & masterBibInfo() const;
455         /// collect bibliography info from the various insets in this buffer.
456         void collectBibKeys() const;
457         /// add some BiblioInfo to our cache
458         void addBiblioInfo(BiblioInfo const & bi) const;
459         /// add a single piece of bibliography info to our cache
460         void addBibTeXInfo(docstring const & key, BibTeXInfo const & bi) const;
461         ///
462         bool citeLabelsValid() const;
463         ///
464         void getLabelList(std::vector<docstring> &) const;
465
466         ///
467         void changeLanguage(Language const * from, Language const * to);
468
469         ///
470         bool isMultiLingual() const;
471         ///
472         std::set<Language const *> getLanguages() const;
473
474         ///
475         BufferParams & params();
476         BufferParams const & params() const;
477
478         /** The list of paragraphs.
479             This is a linked list of paragraph, this list holds the
480             whole contents of the document.
481          */
482         ParagraphList & paragraphs();
483         ParagraphList const & paragraphs() const;
484
485         /// LyX version control object.
486         LyXVC & lyxvc();
487         LyXVC const & lyxvc() const;
488
489         /// Where to put temporary files.
490         std::string const temppath() const;
491
492         /// Used when typesetting to place errorboxes.
493         TexRow const & texrow() const;
494         TexRow & texrow();
495
496         ///
497         ParIterator par_iterator_begin();
498         ///
499         ParConstIterator par_iterator_begin() const;
500         ///
501         ParIterator par_iterator_end();
502         ///
503         ParConstIterator par_iterator_end() const;
504
505         // Position of the child buffer where it appears first in the master.
506         DocIterator firstChildPosition(Buffer const * child);
507
508         /** \returns true only when the file is fully loaded.
509          *  Used to prevent the premature generation of previews
510          *  and by the citation inset.
511          */
512         bool isFullyLoaded() const;
513         /// Set by buffer_funcs' newFile.
514         void setFullyLoaded(bool);
515
516         /// FIXME: Needed by RenderPreview.
517         graphics::PreviewLoader * loader() const;
518         /// Update the LaTeX preview snippets associated with this buffer
519         void updatePreviews() const;
520         /// Remove any previewed LaTeX snippets associated with this buffer
521         void removePreviews() const;
522
523         /// Our main text (inside the top InsetText)
524         Text & text() const;
525
526         /// Our top InsetText
527         Inset & inset() const;
528
529         //
530         // Macro handling
531         //
532         /// Collect macro definitions in paragraphs
533         void updateMacros() const;
534         /// Iterate through the whole buffer and try to resolve macros
535         void updateMacroInstances(UpdateType) const;
536
537         /// List macro names of this buffer, the parent and the children
538         void listMacroNames(MacroNameSet & macros) const;
539         /// Collect macros of the parent and its children in front of this buffer.
540         void listParentMacros(MacroSet & macros, LaTeXFeatures & features) const;
541
542         /// Return macro defined before pos (or in the master buffer)
543         MacroData const * getMacro(docstring const & name, DocIterator const & pos, bool global = true) const;
544         /// Return macro defined anywhere in the buffer (or in the master buffer)
545         MacroData const * getMacro(docstring const & name, bool global = true) const;
546         /// Return macro defined before the inclusion of the child
547         MacroData const * getMacro(docstring const & name, Buffer const & child, bool global = true) const;
548
549         /// Collect user macro names at loading time
550         typedef std::set<docstring> UserMacroSet;
551         mutable UserMacroSet usermacros;
552
553         /// Replace the inset contents for insets which InsetCode is equal
554         /// to the passed \p inset_code.
555         void changeRefsIfUnique(docstring const & from, docstring const & to,
556                 InsetCode code);
557
558         /// get source code (latex/docbook) for some paragraphs, or all paragraphs
559         /// including preamble
560         void getSourceCode(odocstream & os, std::string const format,
561                            pit_type par_begin, pit_type par_end, bool full_source) const;
562
563         /// Access to error list.
564         /// This method is used only for GUI visualisation of Buffer related
565         /// errors (like parsing or LateX compilation). This method is const
566         /// because modifying the returned ErrorList does not touch the document
567         /// contents.
568         ErrorList & errorList(std::string const & type) const;
569
570         /// The Toc backend.
571         /// This is useful only for screen visualisation of the Buffer. This
572         /// method is const because modifying this backend does not touch
573         /// the document contents.
574         TocBackend & tocBackend() const;
575
576         ///
577         Undo & undo();
578
579         /// This function is called when the buffer is changed.
580         void changed(bool update_metrics) const;
581         ///
582         void setChild(DocIterator const & dit, Buffer * child);
583         ///
584         void updateTocItem(std::string const &, DocIterator const &) const;
585         /// This function is called when the buffer structure is changed.
586         void structureChanged() const;
587         /// This function is called when some parsing error shows up.
588         void errors(std::string const & err, bool from_master = false) const;
589         /// This function is called when the buffer busy status change.
590         void setBusy(bool on) const;
591         /// Update window titles of all users.
592         void updateTitles() const;
593         /// Reset autosave timers for all users.
594         void resetAutosaveTimers() const;
595         ///
596         void message(docstring const & msg) const;
597
598         ///
599         void setGuiDelegate(frontend::GuiBufferDelegate * gui);
600         ///
601         bool hasGuiDelegate() const;
602
603         
604
605         /// target is a format name optionally followed by a space
606         /// and a destination file-name
607         bool doExport(std::string const & target, bool put_in_tempdir,
608                 bool includeall, std::string & result_file) const;
609         ///
610         bool doExport(std::string const & target, bool put_in_tempdir,
611                       bool includeall = false) const;
612         ///
613         bool preview(std::string const & format, bool includeall = false) const;
614         /// mark the buffer as busy exporting something, or not
615         void setExportStatus(bool e) const;
616         ///
617         bool isExporting() const;
618
619         ///
620         typedef std::vector<std::pair<Inset *, ParIterator> > References;
621         References & references(docstring const & label);
622         References const & references(docstring const & label) const;
623         void clearReferenceCache() const;
624         void setInsetLabel(docstring const & label, InsetLabel const * il);
625         InsetLabel const * insetLabel(docstring const & label) const;
626
627         /// return a list of all used branches (also in children)
628         void getUsedBranches(std::list<docstring> &, bool const from_master = false) const;
629
630         /// sets the buffer_ member for every inset in this buffer.
631         // FIXME This really shouldn't be needed, but at the moment it's not
632         // clear how to do it just for the individual pieces we need.
633         void setBuffersForInsets() const;
634         /// Updates screen labels and some other information associated with
635         /// insets and paragraphs. Actually, it's more like a general "recurse
636         /// through the Buffer" routine, that visits all the insets and paragraphs.
637         void updateBuffer() const { updateBuffer(UpdateMaster, InternalUpdate); }
638         /// \param scope: whether to start with the master document or just
639         /// do this one.
640         /// \param output: whether we are preparing for output.
641         void updateBuffer(UpdateScope scope, UpdateType utype) const;
642         /// 
643         void updateBuffer(ParIterator & parit, UpdateType utype) const;
644
645         /// Spellcheck starting from \p from.
646         /// \p from initial position, will then points to the next misspelled
647         ///    word.
648         /// \p to will points to the end of the next misspelled word.
649         /// \p word_lang will contain the found misspelled word.
650         /// \return progress if a new word was found.
651         int spellCheck(DocIterator & from, DocIterator & to,
652                 WordLangTuple & word_lang, docstring_list & suggestions) const;
653         ///
654         void checkChildBuffers();
655
656 private:
657         /// Change name of buffer. Updates "read-only" flag.
658         void setFileName(support::FileName const & fname);
659         ///
660         void getLanguages(std::set<Language const *> &) const;
661         /// Checks whether any of the referenced bibfiles have changed since the
662         /// last time we loaded the cache. Note that this does NOT update the
663         /// cached information.
664         void checkIfBibInfoCacheIsValid() const;
665         /// Update the list of all bibfiles in use (including bibfiles
666         /// of loaded child documents).
667         void updateBibfilesCache(UpdateScope scope = UpdateMaster) const;
668         /// Return the list with all bibfiles in use (including bibfiles
669         /// of loaded child documents).
670         support::FileNameList const & 
671                 getBibfilesCache(UpdateScope scope = UpdateMaster) const;
672         ///
673         void collectChildren(ListOfBuffers & children, bool grand_children) const;
674
675         /// noncopyable
676         Buffer(Buffer const &);
677         void operator=(Buffer const &);
678
679         /// Use the Pimpl idiom to hide the internals.
680         class Impl;
681         /// The pointer never changes although *pimpl_'s contents may.
682         Impl * const d;
683 };
684
685
686 } // namespace lyx
687
688 #endif