#include "support/FileName.h"
+#include <string>
#include <vector>
-#include <utility>
-
-#include "ParIterator.h"
-#include "Paragraph.h"
/**
the embedding dialog. This file can be shared with others more
easily.
-Format a anb b can be converted easily, by packing/unpacking a .lyx file.
+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:
======================
namespace lyx {
class Buffer;
+class Inset;
class Lexer;
class ErrorList;
class EmbeddedFile : public support::DocFileName
{
public:
- EmbeddedFile() {};
-
- EmbeddedFile(std::string const & file, std::string const & inzip_name,
- bool embedded, Inset const * inset);
+ EmbeddedFile(std::string const & file = std::string(),
+ std::string const & buffer_path = std::string());
+
+ /// set filename and inzipName.
+ /**
+ * NOTE: inzip_name_ is not unique across operation systems and is not
+ * guaranteed to be the same across different versions of lyx.
+ * inzip_name_ will be saved to the lyx file, and is used to indicate
+ * whether or not a file is embedded, and where the embedded file is in
+ * the bundled file. However, the embedded file will be renamed to the
+ * name set here when an EmbeddedFile is enabled. It is therefore
+ * safe to change the naming scheme here.
+ *
+ * NOTE that this treatment does not welcome an UUID solution because
+ * all embedded files will have to be renamed when an embedded file is
+ * opened. It is of course possible to use saved inzipname, but that is
+ * not easy. For example, when a new EmbeddedFile is created with the same
+ * file as an old one, it needs to be synced to the old inzipname...
+ **/
+ void set(std::string const & filename, std::string const & buffer_path);
+ /** Set the inzip name of an EmbeddedFile, which should be the name
+ * of an actual embedded file on disk. When an EmbeddedFile is enabled,
+ * this file will be renamed to the default inzipName if needed.
+ */
+ void setInzipName(std::string const & name);
- /// 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_; }
- void setInzipName(std::string name) { inzip_name_ = 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;
/// add an inset that refers to this file
void addInset(Inset const * inset);
- Inset const * inset(int idx) const;
- /// save the location of this inset as bookmark so that
- /// it can be located using LFUN_BOOKMARK_GOTO
- void saveBookmark(Buffer const * buf, 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 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.
- void setEmbed(bool embed) { embedded_ = embed; }
+ 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.
- /// Because inset pointers may not be up to date, EmbeddedFiles::update()
- /// would better be called before this function is called.
+ /// 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;
+ /// Calculate checksum of availableFile
+ unsigned long checksum() const;
+
+private:
+ // calculate inzip_name_ from filename
+ std::string calcInzipName(std::string const & buffer_path);
+ // move an embedded disk file with an existing inzip_name_ to
+ // an calculated inzip_name_
+ void syncInzipFile(std::string const & buffer_path);
+
private:
/// filename in zip file
std::string inzip_name_;
/// Insets that contains this file item. Because a
/// file item can be referred by several Insets, a vector is used.
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_;
};
-class EmbeddedFiles {
-public:
- typedef std::vector<EmbeddedFile> EmbeddedFileList;
-public:
- ///
- EmbeddedFiles(Buffer * buffer = 0) : file_list_(), buffer_(buffer) {}
- ///
- ~EmbeddedFiles() {}
+bool operator==(EmbeddedFile const & lhs, EmbeddedFile const & rhs);
+bool operator!=(EmbeddedFile const & lhs, EmbeddedFile const & rhs);
+
- /// return buffer params embedded flag
- bool enabled() const;
+class EmbeddedFileList : public std::vector<EmbeddedFile> {
+public:
/// set buffer params embedded flag. Files will be updated or extracted
/// if such an operation fails, enable will fail.
- void enable(bool flag);
+ void enable(bool flag, Buffer & buffer);
- /// 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.
+ /// add a file item.
+ /* \param file Embedded file to add
* \param inset Inset pointer
- * \param inzipName suggested inzipname
*/
- EmbeddedFile & registerFile(std::string const & filename, bool embed = false,
- Inset const * inset = 0,
- std::string const & inzipName = std::string());
+ void registerFile(EmbeddedFile const & file, Inset const * inset, Buffer const & buffer);
/// scan the buffer and get a list of EmbeddedFile
- void update();
+ void update(Buffer const & buffer);
/// write a zip file
- 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;
- ///
- /// update all insets to use embedded files when embedding status is changed
- void updateInsets() const;
-private:
- /// get a unique inzip name, a suggestion can be given.
- std::string const getInzipName(std::string const & name, std::string const & inzipName);
- /// list of embedded files
- EmbeddedFileList file_list_;
- ///
- Buffer * buffer_;
+ bool writeFile(support::DocFileName const & filename, Buffer const & buffer);
};
} // namespace lyx