]> git.lyx.org Git - lyx.git/blobdiff - src/Buffer.h
Fix pdf format conversion
[lyx.git] / src / Buffer.h
index 384f34ec98ff87bac5754dbd95f4d70637abb040..386625e18d2906896a943d84cf5777c5edf29378 100644 (file)
 #define BUFFER_H
 
 #include "OutputEnums.h"
-
-#include "insets/InsetCode.h"
+#include "OutputParams.h"
 
 #include "support/strfwd.h"
 #include "support/types.h"
 
+#include <map>
 #include <list>
 #include <set>
 #include <string>
@@ -28,8 +28,8 @@
 namespace lyx {
 
 class BiblioInfo;
+class BibTeXInfo;
 class BufferParams;
-class BufferSet;
 class DispatchResult;
 class DocIterator;
 class docstring_list;
@@ -70,8 +70,19 @@ class FileName;
 class FileNameList;
 }
 
+namespace graphics {
+class PreviewLoader;
+}
+
+
+class Buffer;
+typedef std::list<Buffer *> ListOfBuffers;
+/// a list of Buffers we cloned
+typedef std::set<Buffer *> CloneList;
+
+
 /** The buffer object.
- * This is the buffer object. It contains all the informations about
+ * This is the buffer object. It contains all the information about
  * a document loaded into LyX.
  * The buffer object owns the Text (wrapped in an InsetText), which
  * contains the individual paragraphs of the document.
@@ -81,6 +92,9 @@ class FileNameList;
  * minimal, probably not.
  * \author Lars Gullik Bjønnes
  */
+
+class MarkAsExporting;
+
 class Buffer {
 public:
        /// What type of log will \c getLogName() return?
@@ -91,17 +105,44 @@ public:
 
        /// Result of \c readFile()
        enum ReadStatus {
-               failure, ///< The file could not be read
-               success, ///< The file could not be read
-               wrongversion ///< The version of the file does not match ours
+               ReadSuccess,
+               ReadCancel,
+               // failures
+               ReadFailure,
+               ReadWrongVersion,
+               ReadFileNotFound,
+               ReadVCError,
+               ReadAutosaveFailure,
+               ReadEmergencyFailure,
+               ReadNoLyXFormat,
+               ReadDocumentFailure,
+               // lyx2lyx
+               LyX2LyXNoTempFile,
+               LyX2LyXNotFound,
+               LyX2LyXOlderFormat,
+               LyX2LyXNewerFormat,
+               // other
+               ReadOriginal
        };
 
+       enum ExportStatus {
+               // export
+               ExportSuccess,
+               ExportCancel,
+               ExportError,
+               ExportNoPathToFormat,
+               ExportTexPathHasSpaces,
+               ExportConverterError,
+               // preview
+               PreviewSuccess,
+               PreviewError
+       };
 
        /// Method to check if a file is externally modified, used by
        /// isExternallyModified()
        /**
         * timestamp is fast but inaccurate. For example, the granularity
-        * of timestamp on a FAT filesystem is 2 second. Also, various operations
+        * of timestamp on a FAT filesystem is 2 seconds. Also, various operations
         * may touch the timestamp of a file even when its content is unchanged.
         *
         * checksum is accurate but slow, which can be a problem when it is
@@ -111,8 +152,8 @@ public:
         * FIXME: replace this method with support/FileMonitor.
         */
        enum CheckMethod {
-               checksum_method,  ///< Use file checksum
-               timestamp_method, ///< Use timestamp, and checksum if timestamp has changed
+               checksum_method, ///< Use file checksum
+               timestamp_method ///< Use timestamp, and checksum if timestamp has changed
        };
 
        ///
@@ -128,8 +169,11 @@ public:
        /// Destructor
        ~Buffer();
 
-       ///
-       Buffer * clone() const;
+       /// Clones the entire structure of which this Buffer is part, starting
+       /// with the master and cloning all the children, too.
+       Buffer * cloneFromMaster() const;
+       /// Just clones this single Buffer. For autosave.
+       Buffer * cloneBufferOnly() const;
        ///
        bool isClone() const;
 
@@ -145,20 +189,6 @@ public:
        /// \return true if we made a decision
        bool getStatus(FuncRequest const & cmd, FuncStatus & flag);
 
-       /// read a new document from a string
-       bool readString(std::string const &);
-       /// load a new file
-       bool readFile(support::FileName const & filename);
-
-       /// read the header, returns number of unknown tokens
-       int readHeader(Lexer & lex);
-
-       /** Reads a file without header.
-           \param par if != 0 insert the file.
-           \return \c true if file is not completely read.
-       */
-       bool readDocument(Lexer &);
-
        ///
        DocIterator getParFromID(int id) const;
        /// do we have a paragraph with this id?
@@ -172,29 +202,113 @@ public:
            Returns \c true if the save is successful, \c false otherwise.
        */
        bool save() const;
+       /// Renames and saves the buffer
+       bool saveAs(support::FileName const & fn);
 
-       /// Write document to stream. Returns \c false if unsuccesful.
+       /// Write document to stream. Returns \c false if unsuccessful.
        bool write(std::ostream &) const;
+       /// Write file. Returns \c false if unsuccessful.
+       bool writeFile(support::FileName const &) const;
+
+       /// \name Functions involved in reading files/strings.
+       //@{
+       /// Loads the LyX file into the buffer. This function
+       /// tries to extract the file from version control if it
+       /// cannot be found. If it can be found, it will try to
+       /// read an emergency save file or an autosave file.
+       /// \sa loadThisLyXFile
+       ReadStatus loadLyXFile();
+       /// Loads the LyX file \c fn into the buffer. If you want
+       /// to check for files in a version control container,
+       /// emergency or autosave files, one should use \c loadLyXFile.
+       /// /sa loadLyXFile
+       ReadStatus loadThisLyXFile(support::FileName const & fn);
+       /// import a new document from a string
+       bool importString(std::string const &, docstring const &, ErrorList &);
+       /// import a new file
+       bool importFile(std::string const &, support::FileName const &, ErrorList &);
+       /// read a new document from a string
+       bool readString(std::string const &);
+       /// Reloads the LyX file
+       /// \param clearUndo if false, leave alone the undo stack.
+       ReadStatus reload(bool clearUndo = true);
+//FIXME: The following function should be private
+//private:
+       /// read the header, returns number of unknown tokens
+       int readHeader(Lexer & lex);
+
+private:
+       ///
+       typedef std::map<Buffer const *, Buffer *> BufferMap;
+       ///
+       void cloneWithChildren(BufferMap &, CloneList *) const;
+       /// save timestamp and checksum of the given file.
+       void saveCheckSum() const;
+       /// read a new file
+       ReadStatus readFile(support::FileName const & fn);
+       /// Reads a file without header.
+       /// \param par if != 0 insert the file.
+       /// \return \c true if file is not completely read.
+       bool readDocument(Lexer &);
+       /// Try to extract the file from a version control container
+       /// before reading if the file cannot be found.
+       /// \sa LyXVC::file_not_found_hook
+       ReadStatus extractFromVC();
+       /// Reads the first tag of a LyX File and
+       /// returns the file format number.
+       ReadStatus parseLyXFormat(Lexer & lex, support::FileName const & fn,
+               int & file_format) const;
+       /// Convert the LyX file to the LYX_FORMAT using
+       /// the lyx2lyx script and returns the filename
+       /// of the temporary file to be read
+       ReadStatus convertLyXFormat(support::FileName const & fn,
+               support::FileName & tmpfile, int from_format);
+       //@}
+
+public:
+       /// \name Functions involved in autosave and emergency files.
+       //@{
+       /// Save an autosave file to #filename.lyx#
+       bool autoSave() const;
        /// save emergency file
        /// \return a status message towards the user.
        docstring emergencyWrite();
-       /// Write file. Returns \c false if unsuccesful.
-       bool writeFile(support::FileName const &) const;
 
-       /// Loads LyX file \c filename into buffer, *  and return success
-       bool loadLyXFile(support::FileName const & s);
-       /// Reloads the LyX file
-       bool reload();
+//FIXME:The following function should be private
+//private:
+       ///
+       void removeAutosaveFile() const;
+
+private:
+       /// Try to load an autosave file associated to \c fn.
+       ReadStatus loadAutosave();
+       /// Try to load an emergency file associated to \c fn.
+       ReadStatus loadEmergency();
+       /// Get the filename of the emergency file associated with the Buffer
+       support::FileName getEmergencyFileName() const;
+       /// Get the filename of the autosave file associated with the Buffer
+       support::FileName getAutosaveFileName() const;
+       ///
+       void moveAutosaveFile(support::FileName const & old) const;
+       //@}
 
+public:
        /// Fill in the ErrorList with the TeXErrors
        void bufferErrors(TeXErrors const &, ErrorList &) const;
 
+       enum OutputWhat {
+               FullSource,
+               OnlyBody,
+               IncludedFile,
+               OnlyPreamble,
+               CurrentParagraph
+       };
+
        /// Just a wrapper for writeLaTeXSource, first creating the ofstream.
        bool makeLaTeXFile(support::FileName const & filename,
                           std::string const & original_path,
                           OutputParams const &,
-                          bool output_preamble = true,
-                          bool output_body = true) const;
+                          OutputWhat output = FullSource) const;
        /** Export the buffer to LaTeX.
            If \p os is a file stream, and params().inputenc is "auto" or
            "default", and the buffer contains text in different languages
@@ -203,39 +317,39 @@ public:
            method with a string stream if the output is supposed to go to a
            file. \code
            ofdocstream ofs;
+           otexstream os(ofs, texrow);
            ofs.open("test.tex");
-           writeLaTeXSource(ofs, ...);
+           writeLaTeXSource(os, ...);
            ofs.close();
            \endcode is NOT equivalent to \code
            odocstringstream oss;
-           writeLaTeXSource(oss, ...);
+           otexstream os(oss, texrow);
+           writeLaTeXSource(os, ...);
            ofdocstream ofs;
            ofs.open("test.tex");
            ofs << oss.str();
            ofs.close();
            \endcode
         */
-       void writeLaTeXSource(odocstream & os,
+       void writeLaTeXSource(otexstream & os,
                           std::string const & original_path,
                           OutputParams const &,
-                          bool output_preamble = true,
-                          bool output_body = true) const;
+                          OutputWhat output = FullSource) const;
        ///
        void makeDocBookFile(support::FileName const & filename,
                             OutputParams const & runparams_in,
-                            bool only_body = false) const;
+                            OutputWhat output = FullSource) const;
        ///
        void writeDocBookSource(odocstream & os, std::string const & filename,
                             OutputParams const & runparams_in,
-                            bool only_body = false) const;
+                            OutputWhat output = FullSource) const;
        ///
        void makeLyXHTMLFile(support::FileName const & filename,
-                            OutputParams const & runparams_in,
-                            bool only_body = false) const;
+                            OutputParams const & runparams_in) const;
        ///
        void writeLyXHTMLSource(odocstream & os,
                             OutputParams const & runparams_in,
-                            bool only_body = false) const;
+                            OutputWhat output = FullSource) const;
        /// returns the main language for the buffer (document)
        Language const * language() const;
        /// get l10n translated to the buffers language
@@ -251,9 +365,6 @@ public:
        /// whether or not disk file has been externally modified
        bool isExternallyModified(CheckMethod method) const;
 
-       /// save timestamp and checksum of the given file.
-       void saveCheckSum(support::FileName const & file) const;
-
        /// mark the main lyx file as not needing saving
        void markClean() const;
 
@@ -273,6 +384,8 @@ public:
        /// automatically saved, nor it needs to trigger any "do you want to save ?" question.
        bool isInternal() const;
 
+       void setInternal(bool flag);
+
        /// Mark this buffer as dirty.
        void markDirty();
 
@@ -282,7 +395,7 @@ public:
        /// Returns the buffer's filename. It is always an absolute path.
        std::string absFileName() const;
 
-       /// Returns the the path where the buffer lives.
+       /// Returns the path where the buffer lives.
        /// It is always an absolute path.
        std::string filePath() const;
 
@@ -294,16 +407,10 @@ public:
        /// Get the name and type of the log.
        std::string logName(LogType * type = 0) const;
 
-       /// Change name of buffer. Updates "read-only" flag.
-       void setFileName(std::string const & newfile);
-
        /// Set document's parent Buffer.
        void setParent(Buffer const *);
        Buffer const * parent() const;
 
-       // Collect all relative buffer
-       std::vector<Buffer const *> allRelatives() const;
-
        /** Get the document's master (or \c this if this is not a
            child document)
         */
@@ -311,12 +418,27 @@ public:
 
        /// \return true if \p child is a child of this \c Buffer.
        bool isChild(Buffer * child) const;
-       
-       /// return a vector with all children (and grandchildren)
-       std::vector<Buffer *> getChildren(bool grand_children = true) const;
 
-       /// Add all children (and grandchildren) to supplied vector
-       void getChildren(std::vector<Buffer *> & children, bool grand_children = true) const;
+       /// \return true if this \c Buffer has children
+       bool hasChildren() const;
+
+       /// \return a list of the direct children of this Buffer.
+       /// this list has no duplicates and is in the order in which
+       /// the children appear.
+       ListOfBuffers getChildren() const;
+
+       /// \return a list of all descendents of this Buffer (children,
+       /// grandchildren, etc). this list has no duplicates and is in
+       /// the order in which the children appear.
+       ListOfBuffers getDescendents() const;
+
+       /// Collect all relative buffers, in the order in which they appear.
+       /// I.e., the "root" Buffer is first, then its first child, then any
+       /// of its children, etc. However, there are no duplicates in this
+       /// list.
+       /// This is "stable", too, in the sense that it returns the same
+       /// thing from whichever Buffer it is called.
+       ListOfBuffers allRelatives() const;
 
        /// Is buffer read-only?
        bool isReadonly() const;
@@ -324,13 +446,6 @@ public:
        /// Set buffer read-only flag
        void setReadonly(bool flag = true);
 
-       /// returns \c true if the buffer contains a LaTeX document
-       bool isLatex() const;
-       /// returns \c true if the buffer contains a DocBook document
-       bool isDocBook() const;
-       /// returns \c true if the buffer contains a Wed document
-       bool isLiterate() const;
-
        /** Validate a buffer for LaTeX.
            This validates the buffer, and returns a struct for use by
            #makeLaTeX# and others. Its main use is to figure out what
@@ -342,31 +457,49 @@ public:
        */
        void validate(LaTeXFeatures &) const;
 
-       /// Update the list of all bibfiles in use (including bibfiles
-       /// of loaded child documents).
-       void updateBibfilesCache(UpdateScope scope = UpdateMaster) const;
-       /// Return the list with all bibfiles in use (including bibfiles
-       /// of loaded child documents).
-       support::FileNameList const & 
-               getBibfilesCache(UpdateScope scope = UpdateMaster) const;
-       /// Information from BibTeX databases is cached in the Buffer, so
-       /// we do not have to read the file over and over. 
+       /// Reference information is cached in the Buffer, so we do not
+       /// have to check or read things over and over.
+       ///
+       /// There are two caches.
+       ///
+       /// One is a cache of the BibTeX files from which reference info is
+       /// being gathered. This cache is PER BUFFER, and the cache for the
+       /// master essentially includes the cache for its children. This gets
+       /// invalidated when an InsetBibtex is created, deleted, or modified.
+       ///
+       /// The other is a cache of the reference information itself. This
+       /// exists only in the master buffer, and when it needs to be updated,
+       /// the children add their information to the master's cache.
+
        /// Calling this method invalidates the cache and so requires a
        /// re-read.
-       void invalidateBibinfoCache();
-       /// Updates the cached bibliography information.
-       /// Note that you MUST call this method to update the cache. It will
-       /// not happen otherwise. (Currently, it is called at the start of
-       /// updateBuffer() and from GuiCitation.)
-       void checkBibInfoCache() const;
+       void invalidateBibinfoCache() const;
+       /// This invalidates the cache of files we need to check.
+       void invalidateBibfileCache() const;
+       /// Updates the cached bibliography information, checking first to see
+       /// whether the cache is valid. If so, we do nothing. If not, then we
+       /// reload all the BibTeX info.
+       /// Note that this operates on the master document.
+       void reloadBibInfoCache() const;
        /// \return the bibliography information for this buffer's master,
        /// or just for it, if it isn't a child.
        BiblioInfo const & masterBibInfo() const;
-       /// \return the bibliography information for this buffer ONLY.
-       BiblioInfo const & localBibInfo() const;
+       /// collect bibliography info from the various insets in this buffer.
+       void collectBibKeys() const;
+       /// add some BiblioInfo to our cache
+       void addBiblioInfo(BiblioInfo const & bi) const;
+       /// add a single piece of bibliography info to our cache
+       void addBibTeXInfo(docstring const & key, BibTeXInfo const & bi) const;
+       ///
+       void makeCitationLabels() const;
+       ///
+       bool citeLabelsValid() const;
        ///
        void getLabelList(std::vector<docstring> &) const;
 
+       /// This removes the .aux and .bbl files from the temp dir.
+       void removeBiblioTempFiles() const;
+
        ///
        void changeLanguage(Language const * from, Language const * to);
 
@@ -417,6 +550,13 @@ public:
        /// Set by buffer_funcs' newFile.
        void setFullyLoaded(bool);
 
+       /// FIXME: Needed by RenderPreview.
+       graphics::PreviewLoader * loader() const;
+       /// Update the LaTeX preview snippets associated with this buffer
+       void updatePreviews() const;
+       /// Remove any previewed LaTeX snippets associated with this buffer
+       void removePreviews() const;
+
        /// Our main text (inside the top InsetText)
        Text & text() const;
 
@@ -429,7 +569,7 @@ public:
        /// Collect macro definitions in paragraphs
        void updateMacros() const;
        /// Iterate through the whole buffer and try to resolve macros
-       void updateMacroInstances() const;
+       void updateMacroInstances(UpdateType) const;
 
        /// List macro names of this buffer, the parent and the children
        void listMacroNames(MacroNameSet & macros) const;
@@ -445,17 +585,17 @@ public:
 
        /// Collect user macro names at loading time
        typedef std::set<docstring> UserMacroSet;
-       UserMacroSet usermacros;
+       mutable UserMacroSet usermacros;
 
        /// Replace the inset contents for insets which InsetCode is equal
        /// to the passed \p inset_code.
-       void changeRefsIfUnique(docstring const & from, docstring const & to,
-               InsetCode code);
+       void changeRefsIfUnique(docstring const & from, docstring const & to);
 
        /// get source code (latex/docbook) for some paragraphs, or all paragraphs
        /// including preamble
-       void getSourceCode(odocstream & os, pit_type par_begin, pit_type par_end,
-               bool full_source) const;
+       void getSourceCode(odocstream & os, std::string const format,
+                          pit_type par_begin, pit_type par_end, OutputWhat output,
+                          bool master) const;
 
        /// Access to error list.
        /// This method is used only for GUI visualisation of Buffer related
@@ -498,40 +638,41 @@ public:
        bool hasGuiDelegate() const;
 
        ///
-       void autoSave() const;
+       ExportStatus doExport(std::string const & target, bool put_in_tempdir) const;
        ///
-       void removeAutosaveFile() const;
+       ExportStatus doExport(std::string const & target, bool put_in_tempdir,
+               std::string & result_file) const;
        ///
-       void moveAutosaveFile(support::FileName const & old) const;
-       ///
-       support::FileName getAutosaveFilename() const;
-
-       /// return the format of the buffer on a string
-       std::string bufferFormat() const;
-       /// return the default output format of the current backend
-       std::string getDefaultOutputFormat() const;
+       ExportStatus preview(std::string const & format) const;
 
-       ///
-       bool doExport(std::string const & format, bool put_in_tempdir,
+private:
+       /// target is a format name optionally followed by a space
+       /// and a destination file-name
+       ExportStatus doExport(std::string const & target, bool put_in_tempdir,
                bool includeall, std::string & result_file) const;
        ///
-       bool doExport(std::string const & format, bool put_in_tempdir,
-                     bool includeall = false) const;
-       ///
-       bool preview(std::string const & format, bool includeall = false) const;
+       ExportStatus doExport(std::string const & target, bool put_in_tempdir,
+               bool includeall) const;
        ///
-       bool isExportable(std::string const & format) const;
+       ExportStatus preview(std::string const & format, bool includeall = false) const;
        ///
-       std::vector<Format const *> exportableFormats(bool only_viewable) const;
+       void setMathFlavor(OutputParams & op) const;
+
+public:
        ///
-       bool isExportableFormat(std::string const & format) const;
+       bool isExporting() const;
 
        ///
        typedef std::vector<std::pair<Inset *, ParIterator> > References;
-       References & references(docstring const & label);
+       ///
        References const & references(docstring const & label) const;
+       ///
+       void addReference(docstring const & label, Inset * inset, ParIterator it);
+       ///
        void clearReferenceCache() const;
+       ///
        void setInsetLabel(docstring const & label, InsetLabel const * il);
+       ///
        InsetLabel const * insetLabel(docstring const & label) const;
 
        /// return a list of all used branches (also in children)
@@ -549,7 +690,7 @@ public:
        /// do this one.
        /// \param output: whether we are preparing for output.
        void updateBuffer(UpdateScope scope, UpdateType utype) const;
-       /// 
+       ///
        void updateBuffer(ParIterator & parit, UpdateType utype) const;
 
        /// Spellcheck starting from \p from.
@@ -562,19 +703,47 @@ public:
                WordLangTuple & word_lang, docstring_list & suggestions) const;
        ///
        void checkChildBuffers();
+       ///
+       void checkMasterBuffer();
+
+       /// compute statistics between \p from and \p to
+       /// \p from initial position
+       /// \p to points to the end position
+       /// \p skipNoOutput if notes etc. should be ignored
+       void updateStatistics(DocIterator & from, DocIterator & to,
+                                                 bool skipNoOutput = true) const;
+       /// statistics accessor functions
+       int wordCount() const;
+       int charCount(bool with_blanks) const;
 
 private:
+       friend class MarkAsExporting;
+       /// mark the buffer as busy exporting something, or not
+       void setExportStatus(bool e) const;
+
        ///
-       bool readFileHelper(support::FileName const & s);
-       ///
-       std::vector<std::string> backends() const;
-       /** Inserts a file into a document
-           \return \c false if method fails.
-       */
-       ReadStatus readFile(Lexer &, support::FileName const & filename,
-                           bool fromString = false);
+       References & getReferenceCache(docstring const & label);
+       /// Change name of buffer. Updates "read-only" flag.
+       void setFileName(support::FileName const & fname);
        ///
        void getLanguages(std::set<Language const *> &) const;
+       /// Checks whether any of the referenced bibfiles have changed since the
+       /// last time we loaded the cache. Note that this does NOT update the
+       /// cached information.
+       void checkIfBibInfoCacheIsValid() const;
+       /// Update the list of all bibfiles in use (including bibfiles
+       /// of loaded child documents).
+       void updateBibfilesCache(UpdateScope scope = UpdateMaster) const;
+       /// Return the list with all bibfiles in use (including bibfiles
+       /// of loaded child documents).
+       support::FileNameList const &
+               getBibfilesCache(UpdateScope scope = UpdateMaster) const;
+       ///
+       void collectChildren(ListOfBuffers & children, bool grand_children) const;
+
+       /// noncopyable
+       Buffer(Buffer const &);
+       void operator=(Buffer const &);
 
        /// Use the Pimpl idiom to hide the internals.
        class Impl;
@@ -583,6 +752,25 @@ private:
 };
 
 
+/// Helper class, to guarantee that the export status
+/// gets reset properly. To use, simply create a local variable:
+///    MarkAsExporting mex(bufptr);
+/// and leave the rest to us.
+class MarkAsExporting {
+public:
+       MarkAsExporting(Buffer const * buf) : buf_(buf)
+       {
+               buf_->setExportStatus(true);
+       }
+       ~MarkAsExporting()
+       {
+               buf_->setExportStatus(false);
+       }
+private:
+       Buffer const * const buf_;
+};
+
+
 } // namespace lyx
 
 #endif