]> git.lyx.org Git - lyx.git/blob - src/Buffer.h
b6ae1f338d0ea007f47ba5340410353d773dbd36
[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                            std::string const & original_path,
280                            OutputParams const &,
281                            bool output_preamble = true,
282                            bool output_body = true) const;
283         /** Export the buffer to LaTeX.
284             If \p os is a file stream, and params().inputenc is "auto" or
285             "default", and the buffer contains text in different languages
286             with more than one encoding, then this method will change the
287             encoding associated to \p os. Therefore you must not call this
288             method with a string stream if the output is supposed to go to a
289             file. \code
290             ofdocstream ofs;
291             otexstream os(ofs, texrow);
292             ofs.open("test.tex");
293             writeLaTeXSource(os, ...);
294             ofs.close();
295             \endcode is NOT equivalent to \code
296             odocstringstream oss;
297             otexstream os(oss, texrow);
298             writeLaTeXSource(os, ...);
299             ofdocstream ofs;
300             ofs.open("test.tex");
301             ofs << oss.str();
302             ofs.close();
303             \endcode
304          */
305         void writeLaTeXSource(otexstream & os,
306                            std::string const & original_path,
307                            OutputParams const &,
308                            bool output_preamble = true,
309                            bool output_body = true) const;
310         ///
311         void makeDocBookFile(support::FileName const & filename,
312                              OutputParams const & runparams_in,
313                              bool only_body = false) const;
314         ///
315         void writeDocBookSource(odocstream & os, std::string const & filename,
316                              OutputParams const & runparams_in,
317                              bool only_body = false) const;
318         ///
319         void makeLyXHTMLFile(support::FileName const & filename,
320                              OutputParams const & runparams_in) const;
321         ///
322         void writeLyXHTMLSource(odocstream & os,
323                              OutputParams const & runparams_in,
324                              bool only_body = false) const;
325         /// returns the main language for the buffer (document)
326         Language const * language() const;
327         /// get l10n translated to the buffers language
328         docstring const B_(std::string const & l10n) const;
329
330         ///
331         int runChktex();
332         /// return true if the main lyx file does not need saving
333         bool isClean() const;
334         ///
335         bool isDepClean(std::string const & name) const;
336
337         /// whether or not disk file has been externally modified
338         bool isExternallyModified(CheckMethod method) const;
339
340         /// mark the main lyx file as not needing saving
341         void markClean() const;
342
343         ///
344         void markDepClean(std::string const & name);
345
346         ///
347         void setUnnamed(bool flag = true);
348
349         /// Whether or not a filename has been assigned to this buffer
350         bool isUnnamed() const;
351
352         /// Whether or not this buffer is internal.
353         ///
354         /// An internal buffer does not contain a real document, but some auxiliary text segment.
355         /// It is not associated with a filename, it is never saved, thus it does not need to be
356         /// automatically saved, nor it needs to trigger any "do you want to save ?" question.
357         bool isInternal() const;
358
359         /// Mark this buffer as dirty.
360         void markDirty();
361
362         /// Returns the buffer's filename. It is always an absolute path.
363         support::FileName fileName() const;
364
365         /// Returns the buffer's filename. It is always an absolute path.
366         std::string absFileName() const;
367
368         /// Returns the the path where the buffer lives.
369         /// It is always an absolute path.
370         std::string filePath() const;
371
372         /** A transformed version of the file name, adequate for LaTeX.
373             \param no_path optional if \c true then the path is stripped.
374         */
375         std::string latexName(bool no_path = true) const;
376
377         /// Get the name and type of the log.
378         std::string logName(LogType * type = 0) const;
379
380         /// Set document's parent Buffer.
381         void setParent(Buffer const *);
382         Buffer const * parent() const;
383
384         /** Get the document's master (or \c this if this is not a
385             child document)
386          */
387         Buffer const * masterBuffer() const;
388
389         /// \return true if \p child is a child of this \c Buffer.
390         bool isChild(Buffer * child) const;
391         
392         /// \return true if this \c Buffer has children
393         bool hasChildren() const;
394         
395         /// \return a list of the direct children of this Buffer.
396         /// this list has no duplicates and is in the order in which
397         /// the children appear.
398         ListOfBuffers getChildren() const;
399         
400         /// \return a list of all descendents of this Buffer (children,
401         /// grandchildren, etc). this list has no duplicates and is in
402         /// the order in which the children appear.
403         ListOfBuffers getDescendents() const;
404
405         /// Collect all relative buffers, in the order in which they appear.
406         /// I.e., the "root" Buffer is first, then its first child, then any
407         /// of its children, etc. However, there are no duplicates in this
408         /// list.
409         /// This is "stable", too, in the sense that it returns the same
410         /// thing from whichever Buffer it is called.
411         ListOfBuffers allRelatives() const;
412
413         /// Is buffer read-only?
414         bool isReadonly() const;
415
416         /// Set buffer read-only flag
417         void setReadonly(bool flag = true);
418
419         /** Validate a buffer for LaTeX.
420             This validates the buffer, and returns a struct for use by
421             #makeLaTeX# and others. Its main use is to figure out what
422             commands and packages need to be included in the LaTeX file.
423             It (should) also check that the needed constructs are there
424             (i.e. that the \refs points to coresponding \labels). It
425             should perhaps inset "error" insets to help the user correct
426             obvious mistakes.
427         */
428         void validate(LaTeXFeatures &) const;
429
430         /// Reference information is cached in the Buffer, so we do not
431         /// have to check or read things over and over. 
432         ///
433         /// There are two caches.
434         ///
435         /// One is a cache of the BibTeX files from which reference info is
436         /// being gathered. This cache is PER BUFFER, and the cache for the
437         /// master essentially includes the cache for its children. This gets
438         /// invalidated when an InsetBibtex is created, deleted, or modified.
439         /// 
440         /// The other is a cache of the reference information itself. This
441         /// exists only in the master buffer, and when it needs to be updated,
442         /// the children add their information to the master's cache.
443         
444         /// Calling this method invalidates the cache and so requires a
445         /// re-read.
446         void invalidateBibinfoCache() const;
447         /// This invalidates the cache of files we need to check.
448         void invalidateBibfileCache() const;
449         /// Updates the cached bibliography information, checking first to see
450         /// whether the cache is valid. If so, we do nothing. If not, then we
451         /// reload all the BibTeX info.
452         /// Note that this operates on the master document.
453         void reloadBibInfoCache() const;
454         /// \return the bibliography information for this buffer's master,
455         /// or just for it, if it isn't a child.
456         BiblioInfo const & masterBibInfo() const;
457         /// collect bibliography info from the various insets in this buffer.
458         void collectBibKeys() const;
459         /// add some BiblioInfo to our cache
460         void addBiblioInfo(BiblioInfo const & bi) const;
461         /// add a single piece of bibliography info to our cache
462         void addBibTeXInfo(docstring const & key, BibTeXInfo const & bi) const;
463         ///
464         bool citeLabelsValid() const;
465         ///
466         void getLabelList(std::vector<docstring> &) const;
467
468         ///
469         void changeLanguage(Language const * from, Language const * to);
470
471         ///
472         bool isMultiLingual() const;
473         ///
474         std::set<Language const *> getLanguages() const;
475
476         ///
477         BufferParams & params();
478         BufferParams const & params() const;
479
480         /** The list of paragraphs.
481             This is a linked list of paragraph, this list holds the
482             whole contents of the document.
483          */
484         ParagraphList & paragraphs();
485         ParagraphList const & paragraphs() const;
486
487         /// LyX version control object.
488         LyXVC & lyxvc();
489         LyXVC const & lyxvc() const;
490
491         /// Where to put temporary files.
492         std::string const temppath() const;
493
494         /// Used when typesetting to place errorboxes.
495         TexRow const & texrow() const;
496         TexRow & texrow();
497
498         ///
499         ParIterator par_iterator_begin();
500         ///
501         ParConstIterator par_iterator_begin() const;
502         ///
503         ParIterator par_iterator_end();
504         ///
505         ParConstIterator par_iterator_end() const;
506
507         // Position of the child buffer where it appears first in the master.
508         DocIterator firstChildPosition(Buffer const * child);
509
510         /** \returns true only when the file is fully loaded.
511          *  Used to prevent the premature generation of previews
512          *  and by the citation inset.
513          */
514         bool isFullyLoaded() const;
515         /// Set by buffer_funcs' newFile.
516         void setFullyLoaded(bool);
517
518         /// FIXME: Needed by RenderPreview.
519         graphics::PreviewLoader * loader() const;
520         /// Update the LaTeX preview snippets associated with this buffer
521         void updatePreviews() const;
522         /// Remove any previewed LaTeX snippets associated with this buffer
523         void removePreviews() const;
524
525         /// Our main text (inside the top InsetText)
526         Text & text() const;
527
528         /// Our top InsetText
529         Inset & inset() const;
530
531         //
532         // Macro handling
533         //
534         /// Collect macro definitions in paragraphs
535         void updateMacros() const;
536         /// Iterate through the whole buffer and try to resolve macros
537         void updateMacroInstances(UpdateType) const;
538
539         /// List macro names of this buffer, the parent and the children
540         void listMacroNames(MacroNameSet & macros) const;
541         /// Collect macros of the parent and its children in front of this buffer.
542         void listParentMacros(MacroSet & macros, LaTeXFeatures & features) const;
543
544         /// Return macro defined before pos (or in the master buffer)
545         MacroData const * getMacro(docstring const & name, DocIterator const & pos, bool global = true) const;
546         /// Return macro defined anywhere in the buffer (or in the master buffer)
547         MacroData const * getMacro(docstring const & name, bool global = true) const;
548         /// Return macro defined before the inclusion of the child
549         MacroData const * getMacro(docstring const & name, Buffer const & child, bool global = true) const;
550
551         /// Collect user macro names at loading time
552         typedef std::set<docstring> UserMacroSet;
553         mutable UserMacroSet usermacros;
554
555         /// Replace the inset contents for insets which InsetCode is equal
556         /// to the passed \p inset_code.
557         void changeRefsIfUnique(docstring const & from, docstring const & to,
558                 InsetCode code);
559
560         /// get source code (latex/docbook) for some paragraphs, or all paragraphs
561         /// including preamble
562         void getSourceCode(odocstream & os, std::string const format,
563                            pit_type par_begin, pit_type par_end, bool full_source) const;
564
565         /// Access to error list.
566         /// This method is used only for GUI visualisation of Buffer related
567         /// errors (like parsing or LateX compilation). This method is const
568         /// because modifying the returned ErrorList does not touch the document
569         /// contents.
570         ErrorList & errorList(std::string const & type) const;
571
572         /// The Toc backend.
573         /// This is useful only for screen visualisation of the Buffer. This
574         /// method is const because modifying this backend does not touch
575         /// the document contents.
576         TocBackend & tocBackend() const;
577
578         ///
579         Undo & undo();
580
581         /// This function is called when the buffer is changed.
582         void changed(bool update_metrics) const;
583         ///
584         void setChild(DocIterator const & dit, Buffer * child);
585         ///
586         void updateTocItem(std::string const &, DocIterator const &) const;
587         /// This function is called when the buffer structure is changed.
588         void structureChanged() const;
589         /// This function is called when some parsing error shows up.
590         void errors(std::string const & err, bool from_master = false) const;
591         /// This function is called when the buffer busy status change.
592         void setBusy(bool on) const;
593         /// Update window titles of all users.
594         void updateTitles() const;
595         /// Reset autosave timers for all users.
596         void resetAutosaveTimers() const;
597         ///
598         void message(docstring const & msg) const;
599
600         ///
601         void setGuiDelegate(frontend::GuiBufferDelegate * gui);
602         ///
603         bool hasGuiDelegate() const;
604
605         
606
607         /// target is a format name optionally followed by a space
608         /// and a destination file-name
609         bool doExport(std::string const & target, bool put_in_tempdir,
610                 bool includeall, std::string & result_file) const;
611         ///
612         bool doExport(std::string const & target, bool put_in_tempdir,
613                       bool includeall) const;
614         ///
615         bool preview(std::string const & format, bool includeall = false) const;
616         /// mark the buffer as busy exporting something, or not
617         void setExportStatus(bool e) const;
618         ///
619         bool isExporting() const;
620
621         ///
622         typedef std::vector<std::pair<Inset *, ParIterator> > References;
623         References & references(docstring const & label);
624         References const & references(docstring const & label) const;
625         void clearReferenceCache() const;
626         void setInsetLabel(docstring const & label, InsetLabel const * il);
627         InsetLabel const * insetLabel(docstring const & label) const;
628
629         /// return a list of all used branches (also in children)
630         void getUsedBranches(std::list<docstring> &, bool const from_master = false) const;
631
632         /// sets the buffer_ member for every inset in this buffer.
633         // FIXME This really shouldn't be needed, but at the moment it's not
634         // clear how to do it just for the individual pieces we need.
635         void setBuffersForInsets() const;
636         /// Updates screen labels and some other information associated with
637         /// insets and paragraphs. Actually, it's more like a general "recurse
638         /// through the Buffer" routine, that visits all the insets and paragraphs.
639         void updateBuffer() const { updateBuffer(UpdateMaster, InternalUpdate); }
640         /// \param scope: whether to start with the master document or just
641         /// do this one.
642         /// \param output: whether we are preparing for output.
643         void updateBuffer(UpdateScope scope, UpdateType utype) const;
644         /// 
645         void updateBuffer(ParIterator & parit, UpdateType utype) const;
646
647         /// Spellcheck starting from \p from.
648         /// \p from initial position, will then points to the next misspelled
649         ///    word.
650         /// \p to will points to the end of the next misspelled word.
651         /// \p word_lang will contain the found misspelled word.
652         /// \return progress if a new word was found.
653         int spellCheck(DocIterator & from, DocIterator & to,
654                 WordLangTuple & word_lang, docstring_list & suggestions) const;
655         ///
656         void checkChildBuffers();
657
658 private:
659         /// Change name of buffer. Updates "read-only" flag.
660         void setFileName(support::FileName const & fname);
661         ///
662         void getLanguages(std::set<Language const *> &) const;
663         /// Checks whether any of the referenced bibfiles have changed since the
664         /// last time we loaded the cache. Note that this does NOT update the
665         /// cached information.
666         void checkIfBibInfoCacheIsValid() const;
667         /// Update the list of all bibfiles in use (including bibfiles
668         /// of loaded child documents).
669         void updateBibfilesCache(UpdateScope scope = UpdateMaster) const;
670         /// Return the list with all bibfiles in use (including bibfiles
671         /// of loaded child documents).
672         support::FileNameList const & 
673                 getBibfilesCache(UpdateScope scope = UpdateMaster) const;
674         ///
675         void collectChildren(ListOfBuffers & children, bool grand_children) const;
676
677         /// noncopyable
678         Buffer(Buffer const &);
679         void operator=(Buffer const &);
680
681         /// Use the Pimpl idiom to hide the internals.
682         class Impl;
683         /// The pointer never changes although *pimpl_'s contents may.
684         Impl * const d;
685 };
686
687
688 } // namespace lyx
689
690 #endif