2007-08-30 20:46:42 +00:00
|
|
|
// -*- C++ -*-
|
|
|
|
/**
|
|
|
|
* \file EmbeddedFiles.h
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
*
|
|
|
|
* \author Bo Peng
|
|
|
|
*
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef EMBEDDEDFILES_H
|
|
|
|
#define EMBEDDEDFILES_H
|
|
|
|
|
|
|
|
#include "support/FileName.h"
|
|
|
|
|
2007-11-30 20:57:53 +00:00
|
|
|
#include <string>
|
2007-08-30 20:46:42 +00:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
This file, and the embedding dialog implemented in src/frontends, implements
|
|
|
|
an 'Embedded Files' feature of lyx.
|
|
|
|
|
|
|
|
|
|
|
|
Expected features:
|
|
|
|
=========================
|
|
|
|
|
2007-10-30 22:21:48 +00:00
|
|
|
1. Bundled .lyx file can embed graphics, listings, bib file etc. The bundle
|
|
|
|
format is used when Document->Save in bundled format is selected.
|
2007-08-30 20:46:42 +00:00
|
|
|
|
2007-10-30 22:21:48 +00:00
|
|
|
2. Embedded file.lyx file is a zip file, with content.lyx and embedded files.
|
2007-08-30 20:46:42 +00:00
|
|
|
|
2007-10-30 22:21:48 +00:00
|
|
|
3. The embedding status of embedded files can be set at the inset level,
|
|
|
|
or from Document->Settings->Embedded Files.
|
|
|
|
|
|
|
|
4. Extra files such as .cls and .layout can be embedded from Document->
|
|
|
|
Settings->Embedded Files->Extra 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.
|
2007-08-30 20:46:42 +00:00
|
|
|
|
|
|
|
Overall, this feature allows two ways of editing a .lyx file
|
|
|
|
|
|
|
|
a. The continuous use of the pure-text .lyx file format with external
|
|
|
|
files. This is the default file format, and allows external editing
|
|
|
|
of .lyx file and better use of version control systems.
|
|
|
|
|
|
|
|
b. The embedded way. Figures etc are inserted to .lyx file and will
|
|
|
|
be embedded. These embedded files can be viewed or edited through
|
|
|
|
the embedding dialog. This file can be shared with others more
|
2007-09-07 03:02:24 +00:00
|
|
|
easily.
|
2007-08-30 20:46:42 +00:00
|
|
|
|
2008-01-05 05:28:39 +00:00
|
|
|
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.
|
2007-08-30 20:46:42 +00:00
|
|
|
|
|
|
|
Implementation:
|
|
|
|
======================
|
|
|
|
|
|
|
|
1. An EmbeddedFiles class is implemented to keep the embedded files (
|
|
|
|
class EmbeddedFile). (c.f. src/EmbeddedFiles.[h|cpp])
|
|
|
|
|
|
|
|
2. When a file is saved, it is scanned for embedded files. (c.f.
|
|
|
|
EmbeddedFiles::update(), Inset::registerEmbeddedFiles()).
|
|
|
|
|
2007-10-30 22:21:48 +00:00
|
|
|
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.
|
2007-08-30 20:46:42 +00:00
|
|
|
If embedding is disabled, file.lyx is saved in the usual pure-text form.
|
2007-09-11 14:23:12 +00:00
|
|
|
(c.f. Buffer::writeFile(), EmbeddedFiles::writeFile())
|
2007-08-30 20:46:42 +00:00
|
|
|
|
|
|
|
4. When a lyx file.lyx file is opened, if it is a zip file, it is
|
2007-10-30 22:21:48 +00:00
|
|
|
decompressed to tmppath() and tmppath()/content.lyx is read as usual.
|
2007-08-30 20:46:42 +00:00
|
|
|
(c.f. bool Buffer::readFile())
|
|
|
|
|
2007-10-30 22:21:48 +00:00
|
|
|
5. A menu item Document -> Save in bundled format is provided to pack/unpack
|
|
|
|
a .lyx file.
|
2007-08-30 20:46:42 +00:00
|
|
|
|
2007-09-07 03:02:24 +00:00
|
|
|
6. If embedding of a .lyx file with embedded files is disabled, all its
|
2007-08-30 20:46:42 +00:00
|
|
|
embedded files are copied to their respective external filenames. This
|
|
|
|
is why external filename will exist even if a file is at "EMBEDDED" status.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace lyx {
|
|
|
|
|
|
|
|
class Buffer;
|
2007-11-03 17:37:37 +00:00
|
|
|
class Inset;
|
2007-09-10 03:54:02 +00:00
|
|
|
class Lexer;
|
|
|
|
class ErrorList;
|
2007-08-30 20:46:42 +00:00
|
|
|
|
|
|
|
class EmbeddedFile : public support::DocFileName
|
|
|
|
{
|
|
|
|
public:
|
2008-01-05 05:28:39 +00:00
|
|
|
EmbeddedFile(std::string const & file = std::string(),
|
|
|
|
std::string const & buffer_path = std::string());
|
|
|
|
|
|
|
|
/// set filename and inzipName.
|
2008-01-10 23:39:58 +00:00
|
|
|
/**
|
|
|
|
* 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...
|
|
|
|
**/
|
2008-01-05 05:28:39 +00:00
|
|
|
void set(std::string const & filename, std::string const & buffer_path);
|
2008-01-10 23:39:58 +00:00
|
|
|
/** 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);
|
2008-01-07 03:34:21 +00:00
|
|
|
|
2008-01-05 05:28:39 +00:00
|
|
|
/// filename in the zip file, which is the relative path
|
2007-08-30 20:46:42 +00:00
|
|
|
std::string inzipName() const { return inzip_name_; }
|
2008-01-05 05:28:39 +00:00
|
|
|
|
2007-08-30 20:46:42 +00:00
|
|
|
/// embedded file, equals to temppath()/inzipName()
|
2008-01-07 03:34:21 +00:00
|
|
|
std::string embeddedFile() const;
|
2007-09-07 03:02:24 +00:00
|
|
|
/// embeddedFile() or absFilename() depending on embedding status
|
2008-01-07 03:34:21 +00:00
|
|
|
/// and whether or not embedding is enabled.
|
|
|
|
FileName availableFile() const;
|
|
|
|
///
|
|
|
|
std::string latexFilename(std::string const & buffer_path) const;
|
2007-08-30 20:46:42 +00:00
|
|
|
|
2007-09-09 07:07:13 +00:00
|
|
|
/// add an inset that refers to this file
|
|
|
|
void addInset(Inset const * inset);
|
|
|
|
int refCount() const { return inset_list_.size(); }
|
2007-08-30 20:46:42 +00:00
|
|
|
|
|
|
|
/// embedding status of this file
|
2007-09-07 03:02:24 +00:00
|
|
|
bool embedded() const { return embedded_; }
|
2007-09-08 04:10:43 +00:00
|
|
|
/// set embedding status. updateFromExternal() should be called before this
|
|
|
|
/// to copy or sync the embedded file with external one.
|
2008-01-05 05:28:39 +00:00
|
|
|
void setEmbed(bool embed);
|
2008-01-07 03:34:21 +00:00
|
|
|
|
|
|
|
/// 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);
|
2007-08-30 20:46:42 +00:00
|
|
|
|
2007-09-07 16:33:55 +00:00
|
|
|
/// extract file, does not change embedding status
|
2008-01-07 03:34:21 +00:00
|
|
|
bool extract() const;
|
2007-09-07 16:33:55 +00:00
|
|
|
/// update embedded file from external file, does not change embedding status
|
2008-01-07 03:34:21 +00:00
|
|
|
bool updateFromExternalFile() const;
|
2007-09-12 14:27:47 +00:00
|
|
|
///
|
|
|
|
/// After the embedding status is changed, update all insets related
|
2008-01-05 05:28:39 +00:00
|
|
|
/// 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.
|
2008-02-27 21:51:29 +00:00
|
|
|
void updateInsets() const;
|
2007-08-30 20:46:42 +00:00
|
|
|
|
2008-01-07 03:34:21 +00:00
|
|
|
/// Check readability of availableFile
|
|
|
|
bool isReadableFile() const;
|
2008-01-08 16:35:43 +00:00
|
|
|
/// Calculate checksum of availableFile
|
|
|
|
unsigned long checksum() const;
|
2008-01-07 03:34:21 +00:00
|
|
|
|
2008-01-10 23:39:58 +00:00
|
|
|
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);
|
|
|
|
|
2007-08-30 20:46:42 +00:00
|
|
|
private:
|
|
|
|
/// filename in zip file
|
|
|
|
std::string inzip_name_;
|
|
|
|
/// the status of this docfile
|
2007-09-07 03:02:24 +00:00
|
|
|
bool embedded_;
|
2007-10-30 22:21:48 +00:00
|
|
|
/// Insets that contains this file item. Because a
|
2007-09-08 04:10:43 +00:00
|
|
|
/// file item can be referred by several Insets, a vector is used.
|
2007-09-09 07:07:13 +00:00
|
|
|
std::vector<Inset const *> inset_list_;
|
2008-01-07 03:34:21 +00:00
|
|
|
/// 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_;
|
2007-08-30 20:46:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-01-05 05:28:39 +00:00
|
|
|
bool operator==(EmbeddedFile const & lhs, EmbeddedFile const & rhs);
|
|
|
|
bool operator!=(EmbeddedFile const & lhs, EmbeddedFile const & rhs);
|
|
|
|
|
|
|
|
|
2008-01-08 18:55:34 +00:00
|
|
|
class EmbeddedFileList : public std::vector<EmbeddedFile> {
|
2007-08-30 20:46:42 +00:00
|
|
|
public:
|
2007-09-08 04:10:43 +00:00
|
|
|
/// set buffer params embedded flag. Files will be updated or extracted
|
|
|
|
/// if such an operation fails, enable will fail.
|
2008-01-08 18:33:43 +00:00
|
|
|
void enable(bool flag, Buffer & buffer);
|
2007-09-08 04:10:43 +00:00
|
|
|
|
2008-01-08 18:33:43 +00:00
|
|
|
/// add a file item.
|
2008-01-05 05:28:39 +00:00
|
|
|
/* \param file Embedded file to add
|
2007-09-10 03:54:02 +00:00
|
|
|
* \param inset Inset pointer
|
2007-09-08 04:10:43 +00:00
|
|
|
*/
|
2008-01-08 18:33:43 +00:00
|
|
|
void registerFile(EmbeddedFile const & file, Inset const * inset, Buffer const & buffer);
|
2007-08-30 20:46:42 +00:00
|
|
|
|
|
|
|
/// scan the buffer and get a list of EmbeddedFile
|
2008-01-08 18:33:43 +00:00
|
|
|
void update(Buffer const & buffer);
|
2007-08-30 20:46:42 +00:00
|
|
|
|
|
|
|
/// write a zip file
|
2008-01-08 18:33:43 +00:00
|
|
|
bool writeFile(support::DocFileName const & filename, Buffer const & buffer);
|
2007-08-30 20:46:42 +00:00
|
|
|
};
|
|
|
|
|
2007-09-11 21:27:57 +00:00
|
|
|
} // namespace lyx
|
2007-08-30 20:46:42 +00:00
|
|
|
|
|
|
|
#endif
|