Embedding patch two: read/write embedded files'

*  src/insets/InsetGraphics.h
	*  src/insets/InsetExternal.cpp
	*  src/insets/InsetGraphics.cpp
	*  src/insets/InsetInclude.cpp
	*  src/insets/Inset.h
	*  src/insets/InsetInclude.h
	*  src/insets/InsetExternal.h: register embedded files
	*  src/EmbeddedFiles.h|cpp: core of embedded files
	*  src/Buffer.h|cpp: read/write embed file
	*  src/BufferParams.h|cpp: embedded flag
	*  src/Makefile.am
	*  po/POTFILES.in
	*  development/scons/scons_manifest.py: build system updates


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19924 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Bo Peng 2007-08-30 20:46:42 +00:00
parent edd3e65556
commit 692363bbca
16 changed files with 663 additions and 6 deletions

View File

@ -56,6 +56,7 @@ src_header_files = Split('''
Dimension.h
DispatchResult.h
DocIterator.h
EmbeddedFiles.h
Encoding.h
ErrorList.h
Exporter.h
@ -166,6 +167,7 @@ src_pre_files = Split('''
CutAndPaste.cpp
DepTable.cpp
DocIterator.cpp
EmbeddedFiles.cpp
Encoding.cpp
ErrorList.cpp
Exporter.cpp

View File

@ -7,6 +7,7 @@ src/Chktex.cpp
src/Color.cpp
src/Converter.cpp
src/CutAndPaste.cpp
src/EmbeddedFiles.cpp
src/Exporter.cpp
src/Font.cpp
src/Format.cpp

View File

@ -54,6 +54,7 @@
#include "TocBackend.h"
#include "Undo.h"
#include "version.h"
#include "EmbeddedFiles.h"
#include "insets/InsetBibitem.h"
#include "insets/InsetBibtex.h"
@ -98,6 +99,7 @@ using std::map;
using std::ostream;
using std::ostringstream;
using std::ofstream;
using std::ifstream;
using std::pair;
using std::stack;
using std::vector;
@ -132,6 +134,7 @@ using support::subst;
using support::tempName;
using support::trim;
using support::sum;
using support::unzipToDir;
namespace Alert = frontend::Alert;
namespace os = support::os;
@ -194,6 +197,9 @@ public:
/// Container for all sort of Buffer dependant errors.
map<string, ErrorList> errorLists;
/// all embedded files of this buffer
EmbeddedFiles embedded_files;
/// timestamp and checksum used to test if the file has been externally
/// modified. (Used to properly enable 'File->Revert to saved', bug 4114).
time_t timestamp_;
@ -204,7 +210,7 @@ public:
Buffer::Impl::Impl(Buffer & parent, FileName const & file, bool readonly_)
: lyx_clean(true), bak_clean(true), unnamed(false), read_only(readonly_),
filename(file), file_fully_loaded(false), inset(params),
toc_backend(&parent), timestamp_(0), checksum_(0)
toc_backend(&parent), embedded_files(&parent), timestamp_(0), checksum_(0)
{
inset.setAutoBreakRows(true);
lyxvc.buffer(&parent);
@ -351,6 +357,18 @@ TocBackend const & Buffer::tocBackend() const
}
EmbeddedFiles & Buffer::embeddedFiles()
{
return pimpl_->embedded_files;
}
EmbeddedFiles const & Buffer::embeddedFiles() const
{
return pimpl_->embedded_files;
}
string const Buffer::getLatexName(bool const no_path) const
{
string const name = changeExtension(makeLatexName(fileName()), ".tex");
@ -634,8 +652,32 @@ bool Buffer::readString(std::string const & s)
bool Buffer::readFile(FileName const & filename)
{
FileName fname(filename);
// Check if the file is compressed.
string const format = getFormatFromContents(filename);
string format = getFormatFromContents(filename);
if (format == "zip") {
// decompress to a temp directory
LYXERR(Debug::FILES) << filename << " is in zip format. Unzip to " << temppath() << endl;
unzipToDir(filename.toFilesystemEncoding(), temppath());
//
FileName manifest(addName(temppath(), "manifest.txt"));
FileName lyxfile(addName(temppath(),
onlyFilename(filename.toFilesystemEncoding())));
// if both manifest.txt and file.lyx exist, this is am embedded file
if (fs::exists(manifest.toFilesystemEncoding()) &&
fs::exists(lyxfile.toFilesystemEncoding())) {
params().embedded = true;
fname = lyxfile;
// read manifest file
ifstream is(manifest.toFilesystemEncoding().c_str());
is >> pimpl_->embedded_files;
is.close();
LYXERR(Debug::FILES) << filename << " is a embedded file. Its manifest is:\n"
<< pimpl_->embedded_files;
}
}
// The embedded lyx file can also be compressed, for backward compatibility
format = getFormatFromContents(fname);
if (format == "gzip" || format == "zip" || format == "compress") {
params().compressed = true;
}
@ -643,8 +685,8 @@ bool Buffer::readFile(FileName const & filename)
// remove dummy empty par
paragraphs().clear();
Lexer lex(0, 0);
lex.setFile(filename);
if (readFile(lex, filename) != success)
lex.setFile(fname);
if (readFile(lex, fname) != success)
return false;
return true;
@ -845,20 +887,34 @@ bool Buffer::writeFile(FileName const & fname) const
bool retval = false;
FileName content;
if (params().embedded)
// first write the .lyx file to the temporary directory
content = FileName(addName(temppath(),
onlyFilename(fname.toFilesystemEncoding())));
else
content = fname;
if (params().compressed) {
gz::ogzstream ofs(fname.toFilesystemEncoding().c_str(), ios::out|ios::trunc);
gz::ogzstream ofs(content.toFilesystemEncoding().c_str(), ios::out|ios::trunc);
if (!ofs)
return false;
retval = write(ofs);
} else {
ofstream ofs(fname.toFilesystemEncoding().c_str(), ios::out|ios::trunc);
ofstream ofs(content.toFilesystemEncoding().c_str(), ios::out|ios::trunc);
if (!ofs)
return false;
retval = write(ofs);
}
if (retval && params().embedded) {
// write file.lyx and all the embedded files to the zip file fname
// if embedding is enabled, and there is any embedded file
pimpl_->embedded_files.update();
return pimpl_->embedded_files.write(fname);
}
return retval;
}

View File

@ -396,6 +396,11 @@ public:
TocBackend & tocBackend();
TocBackend const & tocBackend() const;
//@}
//@{
EmbeddedFiles & embeddedFiles();
EmbeddedFiles const & embeddedFiles() const;
//@}
private:
/** Inserts a file into a document

View File

@ -353,6 +353,9 @@ BufferParams::BufferParams()
listings_params = string();
pagestyle = "default";
compressed = false;
// temporarily enable embedding for testing. Will set to false
// when embedding GUI is added
embedded = true;
for (int iter = 0; iter < 4; ++iter) {
user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
temp_bullet(iter) = ITEMIZE_DEFAULTS[iter];

View File

@ -261,6 +261,8 @@ public:
std::string parentname;
///
bool compressed;
///
bool embedded;
/// the author list for the document
AuthorList & authors();

307
src/EmbeddedFiles.cpp Normal file
View File

@ -0,0 +1,307 @@
// -*- C++ -*-
/**
* \file EmbeddedFiles.cpp
* 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.
*
*/
#include <config.h>
#include "EmbeddedFiles.h"
#include "Buffer.h"
#include "BufferParams.h"
#include "Paragraph.h"
#include "ParIterator.h"
#include "debug.h"
#include "gettext.h"
#include "Format.h"
#include "frontends/alert.h"
#include <boost/filesystem/operations.hpp>
#include "support/filetools.h"
#include "support/fs_extras.h"
#include "support/convert.h"
#include <sstream>
#include <fstream>
#include <utility>
using std::ofstream;
using std::endl;
using std::vector;
using std::string;
using std::pair;
using std::make_pair;
using std::istream;
using std::ostream;
using std::getline;
using std::istringstream;
namespace lyx {
namespace fs = boost::filesystem;
namespace Alert = frontend::Alert;
using support::FileName;
using support::DocFileName;
using support::makeAbsPath;
using support::addName;
using support::onlyPath;
using support::absolutePath;
using support::onlyFilename;
using support::makeRelPath;
using support::changeExtension;
using support::bformat;
using support::zipFiles;
EmbeddedFile::EmbeddedFile(string const & file, string const & inzip_name,
STATUS status, ParConstIterator const & pit)
: DocFileName(file, true), inzip_name_(inzip_name), status_(status),
par_it_(pit), valid_(true)
{}
string EmbeddedFile::embeddedFile(Buffer const * buf) const
{
return addName(buf->temppath(), inzip_name_);
}
void EmbeddedFile::setParIter(ParConstIterator const & pit)
{
par_it_ = pit;
}
bool EmbeddedFiles::enabled() const
{
return buffer_->params().embedded;
}
void EmbeddedFiles::enable(bool flag)
{
if (enabled() != flag) {
// file will be changed
buffer_->markDirty();
buffer_->params().embedded = flag;
}
}
void EmbeddedFiles::registerFile(string const & filename,
EmbeddedFile::STATUS status, ParConstIterator const & pit)
{
string abs_filename = makeAbsPath(filename, buffer_->filePath()).absFilename();
// try to find this file from the list
EmbeddedFileList::iterator it = file_list_.begin();
EmbeddedFileList::iterator it_end = file_list_.end();
for (; it != it_end; ++it)
if (it->absFilename() == abs_filename)
break;
// find this filename
if (it != file_list_.end()) {
it->setParIter(pit);
it->setStatus(status);
it->validate();
return;
}
// register a new one, using relative file path as inzip_name
string inzip_name = to_utf8(makeRelPath(from_utf8(abs_filename),
from_utf8(buffer_->fileName())));
// if inzip_name is an absolute path, use filename only to avoid
// leaking of filesystem information in inzip_name
if (absolutePath(inzip_name))
inzip_name = onlyFilename(inzip_name);
// if this name has been used...
// use _1_name, _2_name etc
if (!validInzipName(inzip_name)) {
size_t i = 1;
string tmp = inzip_name;
do {
inzip_name = convert<string>(i) + "_" + tmp;
} while (!validInzipName(inzip_name));
}
file_list_.push_back(EmbeddedFile(abs_filename, inzip_name, status, pit));
}
void EmbeddedFiles::update()
{
// invalidate all files, obsolete files will then not be validated by the
// following document scan. These files will still be kept though, because
// they may be added later and their embedding status will be meaningful
// again (thinking of cut/paste of an InsetInclude).
EmbeddedFileList::iterator it = file_list_.begin();
EmbeddedFileList::iterator it_end = file_list_.end();
for (; it != it_end; ++it)
it->invalidate();
ParIterator pit = buffer_->par_iterator_begin();
ParIterator pit_end = buffer_->par_iterator_end();
for (; pit != pit_end; ++pit) {
// For each paragraph, traverse its insets and register embedded files
InsetList::const_iterator iit = pit->insetlist.begin();
InsetList::const_iterator iit_end = pit->insetlist.end();
for (; iit != iit_end; ++iit) {
Inset & inset = *iit->inset;
inset.registerEmbeddedFiles(*buffer_, *this, pit);
}
}
LYXERR(Debug::FILES) << "Manifest updated: " << endl
<< *this
<< "End Manifest" << endl;
}
bool EmbeddedFiles::write(DocFileName const & filename)
{
// file in the temporary path has the content
string const content = FileName(addName(buffer_->temppath(),
onlyFilename(filename.toFilesystemEncoding()))).toFilesystemEncoding();
// get a file list and write a manifest file
vector<pair<string, string> > filenames;
string const manifest = FileName(
addName(buffer_->temppath(), "manifest.txt")).toFilesystemEncoding();
// write a manifest file
ofstream os(manifest.c_str());
os << *this;
os.close();
// prepare list of embedded file
EmbeddedFileList::iterator it = file_list_.begin();
EmbeddedFileList::iterator it_end = file_list_.end();
for (; it != it_end; ++it) {
if (it->valid() && it->embedded()) {
// use external file if possible
if (it->status() != EmbeddedFile::EMBEDDED && fs::exists(it->absFilename()))
filenames.push_back(make_pair(it->absFilename(), it->inzipName()));
// use embedded file (AUTO or EMBEDDED mode)
else if(fs::exists(it->embeddedFile(buffer_)))
filenames.push_back(make_pair(it->embeddedFile(buffer_), it->inzipName()));
else
lyxerr << "File " << it->absFilename() << " does not exist. Skip embedding it. " << endl;
}
}
// add filename (.lyx) and manifest to filenames
filenames.push_back(make_pair(content, onlyFilename(filename.toFilesystemEncoding())));
filenames.push_back(make_pair(manifest, "manifest.txt"));
// write a zip file with all these files. Write to a temp file first, to
// avoid messing up the original file in case something goes terribly wrong.
DocFileName zipfile(addName(buffer_->temppath(),
onlyFilename(changeExtension(
filename.toFilesystemEncoding(), ".zip"))));
zipFiles(zipfile, filenames);
// copy file back
try {
fs::copy_file(zipfile.toFilesystemEncoding(), filename.toFilesystemEncoding(), false);
} catch (fs::filesystem_error const & fe) {
Alert::error(_("Save failure"),
bformat(_("Cannot create file %1$s.\n"
"Please check whether the directory exists and is writeable."),
from_utf8(filename.absFilename())));
LYXERR(Debug::DEBUG) << "Fs error: " << fe.what() << endl;
}
return true;
}
bool EmbeddedFiles::validInzipName(string const & name)
{
EmbeddedFileList::iterator it = file_list_.begin();
EmbeddedFileList::iterator it_end = file_list_.end();
for (; it != it_end; ++it)
if (it->inzipName() == name)
return false;
return true;
}
istream & operator>> (istream & is, EmbeddedFiles & files)
{
files.clear();
string tmp;
getline(is, tmp);
// get version
istringstream itmp(tmp);
int version;
itmp.ignore(string("# LyX manifest version ").size());
itmp >> version;
if (version != 1) {
lyxerr << "This version of LyX can only read LyX manifest version 1" << endl;
return is;
}
getline(is, tmp);
if (tmp != "<manifest>") {
lyxerr << "Invalid manifest file, lacking <manifest>" << endl;
return is;
}
// manifest file may be messed up, be carefully
while (is.good()) {
getline(is, tmp);
if (tmp != "<file>")
break;
string fname;
getline(is, fname);
string inzip_name;
getline(is, inzip_name);
getline(is, tmp);
istringstream itmp(tmp);
int status;
itmp >> status;
getline(is, tmp);
if (tmp != "</file>") {
lyxerr << "Invalid manifest file, lacking </file>" << endl;
break;
}
files.registerFile(fname, static_cast<EmbeddedFile::STATUS>(status));
};
// the last line must be </manifest>
if (tmp != "</manifest>") {
lyxerr << "Invalid manifest file, lacking </manifest>" << endl;
return is;
}
return is;
}
ostream & operator<< (ostream & os, EmbeddedFiles const & files)
{
// store a version so that operator >> can read later versions
// using version information.
os << "# lyx manifest version 1\n";
os << "<manifest>\n";
EmbeddedFiles::EmbeddedFileList::const_iterator it = files.begin();
EmbeddedFiles::EmbeddedFileList::const_iterator it_end = files.end();
for (; it != it_end; ++it) {
if (!it->valid())
continue;
// use differnt lines to make reading easier.
os << "<file>\n"
// save the relative path
<< to_utf8(makeRelPath(from_utf8(it->absFilename()),
from_utf8(files.buffer_->filePath()))) << '\n'
<< it->inzipName() << '\n'
<< it->status() << '\n'
<< "</file>\n";
}
os << "</manifest>\n";
return os;
}
}

239
src/EmbeddedFiles.h Normal file
View File

@ -0,0 +1,239 @@
// -*- 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"
#include <vector>
#include <utility>
#include "ParIterator.h"
#include "Paragraph.h"
/**
This file, and the embedding dialog implemented in src/frontends, implements
an 'Embedded Files' feature of lyx.
Expected features:
=========================
1. With embedding enabled (disabled by default), .lyx file can embed graphics,
listings, bib file etc.
2. Embedding of certain files are automatic (graphics, bib etc), and
other files can be embedded manually.
3. Embedded file.lyx file is a zip file, with file.lyx, manifest.txt
and embedded files.
4. Embedded files can be "EMBEDDED", "EXTERNAL", or "AUTO". In the
"AUTO" mode, external files will be used if available; otherwise the
embedded version will be used. In this way, users can work as usual by
modifying external listings, graphics, and do not have to worry about
embedding. "EMBEDDED" and "EXTERNAL" modes ignore or use external files
respectively.
5. An embedding dialog is provided to change embedding status (buffer
level or individual embedded files), manually embed, extract, view
or edit files.
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
easily. The advantage of lyx' embedding approach is that external files
will be automatically used and embedded if the file is in "AUTO" mode.
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 mode.
It also provides functions to
a. manipulate manifest
b. scan a buffer for embeddable files
c. look up inzipname from external filename
d. look up external filename from inzipname
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.
If embedding is disabled, file.lyx is saved in the usual pure-text form.
(c.f. Buffer::writeFile(), EmbeddedFiles::write())
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.
(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.
6. When a lyx file is loaded, Embedded files can have
a. both external and internal copy
b. only external copy (filename())
c. only embedded copy (temppath()/inzipname)
And each can have "AUTO", "EXTERNAL", "EMBEDDED" status. Proper
handling of each case is required.
7. 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.
8. 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 EmbeddedFile : public support::DocFileName
{
public:
/**
Embedding status of this DocFileName.
*/
enum STATUS {
// uninitialized/invalid status
NONE,
// If the external version of the file is available, it will be used
// to generate output, and be embedded to the saved lyx file.
// Otherwise, embedded version will be used.
AUTO,
// Always use embedded version.
EMBEDDED,
// Do not embed this file, always use external version.
EXTERNAL
};
EmbeddedFile(std::string const & file, std::string const & inzip_name,
STATUS status, ParConstIterator const & pit);
/// filename in the zip file, usually the relative path
std::string inzipName() const { return inzip_name_; }
/// embedded file, equals to temppath()/inzipName()
std::string embeddedFile(Buffer const * buf) const;
/// paragraph id
void setParIter(ParConstIterator const & pit);
int const parID() const { return par_it_->id(); }
/// embedding status of this file
bool embedded() const { return status_ != EXTERNAL; }
STATUS status() const { return status_; }
void setStatus(STATUS status) { status_ = status; }
// 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() { valid_ = false; }
private:
/// filename in zip file
std::string inzip_name_;
/// the status of this docfile
STATUS status_;
///
bool valid_;
/// Current position of the item, used to locate the files
/// A figure may be referred by several items. In this case
/// only the last location is recorded.
ParConstIterator par_it_;
};
class EmbeddedFiles {
public:
typedef std::vector<EmbeddedFile> EmbeddedFileList;
public:
///
EmbeddedFiles(Buffer * buffer = NULL): file_list_(), buffer_(buffer) {}
///
~EmbeddedFiles() {}
/// return buffer params embedded flag
bool enabled() const;
/// set buffer params embedded flag
void enable(bool flag);
/// add a file item
void registerFile(std::string const & filename,
EmbeddedFile::STATUS status=EmbeddedFile::AUTO,
ParConstIterator const & pit = ParConstIterator());
/// scan the buffer and get a list of EmbeddedFile
void update();
/// write a zip file
bool write(support::DocFileName const & filename);
void clear() { file_list_.clear(); }
///
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(); }
///
friend std::istream & operator>> (std::istream & is, EmbeddedFiles &);
friend std::ostream & operator<< (std::ostream & os, EmbeddedFiles const &);
private:
/// if a inzip name already exists
bool validInzipName(std::string const & name);
/// list of embedded files
EmbeddedFileList file_list_;
///
Buffer * buffer_;
};
std::istream & operator>> (std::istream & is, EmbeddedFiles &);
std::ostream & operator<< (std::ostream & os, EmbeddedFiles const &);
}
#endif

View File

@ -127,6 +127,8 @@ liblyxcore_la_SOURCES = \
DispatchResult.h \
DocIterator.cpp \
DocIterator.h \
EmbeddedFiles.h \
EmbeddedFiles.cpp \
Encoding.cpp \
Encoding.h \
ErrorList.cpp \

View File

@ -49,6 +49,7 @@ class ParConstIterator;
class ParIterator;
class Text;
class TocList;
class EmbeddedFiles;
namespace graphics { class PreviewLoader; }
@ -438,6 +439,9 @@ public:
/// Add an entry to the TocList
/// pit is the ParConstIterator of the paragraph containing the inset
virtual void addToToc(TocList &, Buffer const &, ParConstIterator const &) const {}
/// report files that can be embedded with the lyx file
virtual void registerEmbeddedFiles(Buffer const &, EmbeddedFiles &,
ParConstIterator const &) const {};
/// Fill keys with BibTeX information
virtual void fillWithBibKeys(Buffer const &,
BiblioInfo &, InsetIterator const &) const { return; }

View File

@ -481,6 +481,13 @@ bool InsetExternal::getStatus(Cursor & cur, FuncRequest const & cmd,
}
void InsetExternal::registerEmbeddedFiles(Buffer const &,
EmbeddedFiles & files, ParConstIterator const & pit) const
{
files.registerFile(params_.filename.absFilename(), EmbeddedFile::AUTO, pit);
}
void InsetExternal::edit(Cursor & cur, bool)
{
InsetExternalMailer(*this).showDialog(&cur.bv());

View File

@ -14,6 +14,7 @@
#include "Inset.h"
#include "ExternalTransforms.h"
#include "EmbeddedFiles.h"
#include "support/FileName.h"
#include "support/Translator.h"
@ -147,6 +148,9 @@ public:
void edit(Cursor & cur, bool left);
///
bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const;
/// external file can be embedded
void registerEmbeddedFiles(Buffer const &, EmbeddedFiles &,
ParConstIterator const &) const;
protected:
InsetExternal(InsetExternal const &);

View File

@ -71,6 +71,7 @@ TODO
#include "Mover.h"
#include "OutputParams.h"
#include "sgml.h"
#include "EmbeddedFiles.h"
#include "frontends/alert.h"
@ -230,6 +231,14 @@ bool InsetGraphics::getStatus(Cursor & cur, FuncRequest const & cmd,
}
void InsetGraphics::registerEmbeddedFiles(Buffer const &,
EmbeddedFiles & files, ParConstIterator const & pit) const
{
files.registerFile(params().filename.absFilename(),
EmbeddedFile::AUTO, pit);
}
void InsetGraphics::edit(Cursor & cur, bool)
{
InsetGraphicsMailer(*this).showDialog(&cur.bv());

View File

@ -78,6 +78,8 @@ public:
void editGraphics(InsetGraphicsParams const &, Buffer const &) const;
///
bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const;
/// all graphics can be embedded
void registerEmbeddedFiles(Buffer const &, EmbeddedFiles &, ParConstIterator const &) const;
protected:
InsetGraphics(InsetGraphics const &);
///

View File

@ -958,6 +958,16 @@ void InsetInclude::updateLabels(Buffer const & buffer,
}
void InsetInclude::registerEmbeddedFiles(Buffer const & buffer,
EmbeddedFiles & files, ParConstIterator const & pit) const
{
// include and input are temprarily not considered.
if (isVerbatim(params_) || isListings(params_))
files.registerFile(includedFilename(buffer, params_).absFilename(),
EmbeddedFile::AUTO, pit);
}
string const InsetIncludeMailer::name_("include");
InsetIncludeMailer::InsetIncludeMailer(InsetInclude & inset)

View File

@ -18,6 +18,7 @@
#include "RenderButton.h"
#include "MailInset.h"
#include "Counters.h"
#include "EmbeddedFiles.h"
#include "support/FileName.h"
@ -103,6 +104,9 @@ public:
bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const;
///
void updateLabels(Buffer const & buffer, ParIterator const &);
/// child document can be embedded
void registerEmbeddedFiles(Buffer const &, EmbeddedFiles &,
ParConstIterator const &) const;
protected:
InsetInclude(InsetInclude const &);
///