#include "support/FileName.h"
+#include <string>
#include <vector>
-#include <utility>
-
-#include "ParIterator.h"
-#include "Paragraph.h"
/**
Expected features:
=========================
-1. With embedding enabled (disabled by default), .lyx file can embed graphics,
-listings, bib file etc.
+1. Bundled .lyx file can embed graphics, listings, bib file etc. The bundle
+format is used when Document->Save in bundled format is selected.
+
+2. Embedded file.lyx file is a zip file, with content.lyx and embedded files.
+
+3. The embedding status of embedded files can be set at the inset level,
+or from Document->Settings->Embedded Files.
-2. Embedded file.lyx file is a zip file, with file.lyx, manifest.txt
-and embedded files.
+4. Extra files such as .cls and .layout can be embedded from Document->
+Settings->Embedded Files->Extra Files.
-3. An embedding dialog is provided to change embedding status (buffer
-level or individual embedded files), manually embed, extract, view
-or edit files.
+5. When Document->Save in bundled format is selected, all embedded files
+become bundled. Changes to the external version of this file does not
+affect the output of the .lyx file.
+
+6. When Document->Save in bundled format is unchecked, all embedded files
+are copied to their original locations.
Overall, this feature allows two ways of editing a .lyx file
the embedding dialog. This file can be shared with others more
easily.
-Format a anb b can be converted easily, by enable/disable embedding. Diabling
-embedding is also called unpacking because all embedded files will be copied
-to their original locations.
+Format a and b can be converted easily, by packing/unpacking a .lyx file.
+
+NOTE: With current implementation, files with absolute filenames (not in
+or deeper under the current document directory) can not be embedded.
Implementation:
======================
1. An EmbeddedFiles class is implemented to keep the embedded files (
class EmbeddedFile). (c.f. src/EmbeddedFiles.[h|cpp])
-This class keeps a manifest that has
- a. external relative filename
- b. inzip filename. It is the relative path name if the embedded file is
- in or under the document directory, or file name otherwise. Name aliasing
- is used if two external files share the same name.
- c. embedding status.
-It also provides functions to
- a. manipulate manifest
- b. scan a buffer for embeddable files
- c. determine which file to use according to embedding status
2. When a file is saved, it is scanned for embedded files. (c.f.
EmbeddedFiles::update(), Inset::registerEmbeddedFiles()).
-3. When a lyx file file.lyx is saved, it is save to tmppath() first.
-Embedded files are compressed along with file.lyx and a manifest.txt.
+3. When a lyx file file.lyx is saved, it is save to tmppath()/content.lyx
+first. Embedded files are compressed along with content.lyx.
If embedding is disabled, file.lyx is saved in the usual pure-text form.
-(c.f. Buffer::writeFile(), EmbeddedFiles::write())
+(c.f. Buffer::writeFile(), EmbeddedFiles::writeFile())
4. When a lyx file.lyx file is opened, if it is a zip file, it is
-decompressed to tmppath(). If manifest.txt and file.lyx exists in
-tmppath(), the manifest is read to buffer, and tmppath()/file.lyx is
-read as usual. If file.lyx is not a zip file, it is read as usual.
+decompressed to tmppath() and tmppath()/content.lyx is read as usual.
(c.f. bool Buffer::readFile())
-5. A menu item Document -> Embedded Files is provided to open
-a embedding dialog. It handles a EmbddedFiles point directly.
-From this dialog, a user can disable embedding, change embedding status,
-or embed other files, extract, view, edit files.
+5. A menu item Document -> Save in bundled format is provided to pack/unpack
+a .lyx file.
6. If embedding of a .lyx file with embedded files is disabled, all its
embedded files are copied to their respective external filenames. This
is why external filename will exist even if a file is at "EMBEDDED" status.
-7. Individual embeddable insets should find ways to handle embedded files.
-InsetGraphics replace params().filename with its temppath()/inzipname version
-when the inset is created. The filename appears as /tmp/..../inzipname
-when lyx runs. When params().filename is saved, lyx checks if this is an
-embedded file (check path == temppath()), if so, save filename() instead.
-(c.f. InsetGraphic::read(), InsetGraphics::edit(), InsetGraphicsParams::write())
-
-
*/
namespace lyx {
class Buffer;
+class Inset;
+class Lexer;
+class ErrorList;
class EmbeddedFile : public support::DocFileName
{
public:
- EmbeddedFile(std::string const & file, std::string const & inzip_name,
- bool embedded, ParConstIterator const & pit);
+ EmbeddedFile(std::string const & file = std::string(),
+ std::string const & buffer_path = std::string());
+
+ /// set filename and inzipName.
+ void set(std::string const & filename, std::string const & buffer_path);
- /// filename in the zip file, usually the relative path
+ /// filename in the zip file, which is the relative path
std::string inzipName() const { return inzip_name_; }
+
/// embedded file, equals to temppath()/inzipName()
- std::string embeddedFile(Buffer const * buf) const;
+ std::string embeddedFile() const;
/// embeddedFile() or absFilename() depending on embedding status
- std::string availableFile(Buffer const * buf) const;
+ /// and whether or not embedding is enabled.
+ FileName availableFile() const;
+ ///
+ std::string latexFilename(std::string const & buffer_path) const;
- /// paragraph id
- void addParIter(ParConstIterator const & pit);
- int parID(int idx) const;
- /// Number of Insets this file item is referred
- /// If refCount() == 0, this file must be manually inserted.
- /// This fact is used by the update() function to skip updating
- /// such items.
- int refCount() const { return par_it_.size(); }
+ /// add an inset that refers to this file
+ void addInset(Inset const * inset);
+ int refCount() const { return inset_list_.size(); }
/// embedding status of this file
bool embedded() const { return embedded_; }
/// set embedding status. updateFromExternal() should be called before this
/// to copy or sync the embedded file with external one.
- bool setEmbed(bool embed) { embedded_ = embed; }
-
- // A flag indicating whether or not this filename is valid.
- // When lyx runs, InsetGraphics etc may be added or removed so filename
- // maybe obsolete. In Buffer::updateEmbeddedFiles, the EmbeddedFiles is first
- // invalidated (c.f. invalidate()), and all insets are asked to register
- // embedded files. In this way, EmbeddedFileList will be refreshed, with
- // status setting untouched.
- bool valid() const { return valid_; }
- void validate() { valid_ = true; }
- void invalidate();
+ void setEmbed(bool embed);
+
+ /// whether or not embedding is enabled in the current buffer
+ bool enabled() const { return temp_path_ != ""; }
+ /// enable embedding of this file
+ void enable(bool flag, Buffer const * buf);
/// extract file, does not change embedding status
- bool extract(Buffer const * buf) const;
+ bool extract() const;
/// update embedded file from external file, does not change embedding status
- bool updateFromExternalFile(Buffer const * buf) const;
+ bool updateFromExternalFile() const;
+ ///
+ /// After the embedding status is changed, update all insets related
+ /// to this file item. For example, a graphic inset may need to monitor
+ /// embedded file instead of external file. To make sure inset pointers
+ /// are up to date, please make sure there is no modification to the
+ /// document between EmbeddedFiles::update() and this function.
+ void updateInsets(Buffer const * buf) const;
+
+ /// Check readability of availableFile
+ bool isReadableFile() const;
private:
/// filename in zip file
std::string inzip_name_;
/// the status of this docfile
bool embedded_;
- ///
- bool valid_;
- /// Current position of the item, used to locate the files. Because one
+ /// Insets that contains this file item. Because a
/// file item can be referred by several Insets, a vector is used.
- std::vector<ParConstIterator> par_it_;
+ std::vector<Inset const *> inset_list_;
+ /// Embedded file needs to know whether enbedding is enabled,
+ /// and where is the lyx temporary directory. Such information can
+ /// be retrived from a buffer, but a buffer is not always available when
+ /// an EmbeddedFile is used.
+ std::string temp_path_;
};
+bool operator==(EmbeddedFile const & lhs, EmbeddedFile const & rhs);
+bool operator!=(EmbeddedFile const & lhs, EmbeddedFile const & rhs);
+
+
class EmbeddedFiles {
public:
typedef std::vector<EmbeddedFile> EmbeddedFileList;
public:
///
- EmbeddedFiles(Buffer * buffer = NULL): file_list_(), buffer_(buffer) {}
+ EmbeddedFiles(Buffer * buffer = 0) : file_list_(), buffer_(buffer) {}
///
~EmbeddedFiles() {}
bool enabled() const;
/// set buffer params embedded flag. Files will be updated or extracted
/// if such an operation fails, enable will fail.
- bool enable(bool flag);
+ void enable(bool flag);
/// add a file item.
- /* \param filename filename to add
- * \param embed embedding status. For a new file item, this is always true.
- * If the file already exists, this parameter is ignored.
- * \param pit paragraph id.
+ /* \param file Embedded file to add
+ * \param inset Inset pointer
*/
- void registerFile(std::string const & filename, bool embed = false,
- ParConstIterator const & pit = ParConstIterator());
+ void registerFile(EmbeddedFile const & file, Inset const * inset = 0);
/// scan the buffer and get a list of EmbeddedFile
void update();
/// write a zip file
- bool write(support::DocFileName const & filename);
+ bool writeFile(support::DocFileName const & filename);
void clear() { file_list_.clear(); }
- ///
- EmbeddedFile & operator[](size_t idx) { return *(file_list_.begin() + idx); }
- EmbeddedFile const & operator[](size_t idx) const { return *(file_list_.begin() + idx); }
///
EmbeddedFileList::iterator begin() { return file_list_.begin(); }
EmbeddedFileList::iterator end() { return file_list_.end(); }
EmbeddedFileList::const_iterator begin() const { return file_list_.begin(); }
EmbeddedFileList::const_iterator end() const { return file_list_.end(); }
- // try to locate filename, using either absFilename() or embeddedFile()
- EmbeddedFileList::const_iterator find(std::string filename) const;
- /// extract all file items, used when disable embedding
- bool extract() const;
- /// update all files from external, used when enable embedding
- bool updateFromExternalFile() const;
- ///
- friend std::istream & operator>> (std::istream & is, EmbeddedFiles &);
- friend std::ostream & operator<< (std::ostream & os, EmbeddedFiles const &);
private:
- /// get a unique inzip name
- std::string const getInzipName(std::string const & name);
/// list of embedded files
EmbeddedFileList file_list_;
///
Buffer * buffer_;
};
+} // namespace lyx
-std::istream & operator>> (std::istream & is, EmbeddedFiles &);
-
-std::ostream & operator<< (std::ostream & os, EmbeddedFiles const &);
-
-}
#endif