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