diff --git a/src/EmbeddedFiles.cpp b/src/EmbeddedFiles.cpp index a11bc8206e..e5d7ab35c1 100644 --- a/src/EmbeddedFiles.cpp +++ b/src/EmbeddedFiles.cpp @@ -254,6 +254,64 @@ bool EmbeddedFile::updateFromExternalFile() const } +EmbeddedFile EmbeddedFile::copyTo(Buffer const * buf) +{ + EmbeddedFile file = EmbeddedFile(absFilename(), buf->filePath()); + file.setEmbed(embedded()); + file.enable(buf->embedded(), buf, false); + + // use external file. + if (!embedded()) + return file; + + LYXERR(Debug::FILES, "Copy " << availableFile() + << " to " << file.availableFile()); + + FileName from_file = availableFile(); + FileName to_file = file.availableFile(); + + if (!from_file.exists()) { + // no from file + throw ExceptionMessage(ErrorException, + _("Failed to copy embedded file"), + bformat(_("Failed to embed file %1$s.\n" + "Please check whether the source file is available"), + from_utf8(absFilename()))); + file.setEmbed(false); + return file; + } + + // if destination file already exists ... + if (to_file.exists()) { + // no need to copy if the files are the same + if (checksum() == to_file.checksum()) + return file; + // other wise, ask if overwrite + int const ret = Alert::prompt( + _("Update embedded file?"), + bformat(_("Embedded file %1$s already exists, do you want to overwrite it"), + from_utf8(to_file.absFilename())), 1, 1, _("&Overwrite"), _("&Cancel")); + if (ret != 0) + // if the user does not want to overwrite, we still consider it + // a successful operation. + return file; + } + // copy file + // need to make directory? + FileName path = to_file.onlyPath(); + if (!path.isDirectory()) + path.createPath(); + if (from_file.copyTo(to_file)) + return file; + throw ExceptionMessage(ErrorException, + _("Copy file failure"), + bformat(_("Cannot copy file %1$s to %2$s.\n" + "Please check whether the directory exists and is writeable."), + from_utf8(from_file.absFilename()), from_utf8(to_file.absFilename()))); + return file; +} + + void EmbeddedFile::updateInsets() const { vector::const_iterator it = inset_list_.begin(); @@ -414,7 +472,7 @@ void EmbeddedFileList::enable(bool flag, Buffer & buffer, bool updateFile) for (it = begin(); it != it_end; ++it) it->updateInsets(); - if (!updateFile) + if (!updateFile || (count_external == 0 && count_embedded == 0)) return; // show result diff --git a/src/EmbeddedFiles.h b/src/EmbeddedFiles.h index a2fa1a7f94..5a8df69853 100644 --- a/src/EmbeddedFiles.h +++ b/src/EmbeddedFiles.h @@ -158,6 +158,8 @@ public: bool extract() const; /// update embedded file from external file, does not change embedding status bool updateFromExternalFile() const; + /// copy an embedded file to another buffer + EmbeddedFile copyTo(Buffer const * buf); /// /// After the embedding status is changed, update all insets related /// to this file item. For example, a graphic inset may need to monitor diff --git a/src/insets/InsetBibtex.cpp b/src/insets/InsetBibtex.cpp index 2b12c9f03b..69e8f7bba2 100644 --- a/src/insets/InsetBibtex.cpp +++ b/src/insets/InsetBibtex.cpp @@ -52,6 +52,18 @@ InsetBibtex::InsetBibtex(InsetCommandParams const & p) {} +void InsetBibtex::setBuffer(Buffer & buffer) +{ + if (buffer_) { + EmbeddedFileList::iterator it = bibfiles_.begin(); + EmbeddedFileList::iterator it_end = bibfiles_.end(); + for (; it != it_end; ++it) + *it = it->copyTo(&buffer); + } + Inset::setBuffer(buffer); +} + + ParamInfo const & InsetBibtex::findInfo(string const & /* cmdName */) { static ParamInfo param_info_; diff --git a/src/insets/InsetBibtex.h b/src/insets/InsetBibtex.h index ff511d2479..efee21ef44 100644 --- a/src/insets/InsetBibtex.h +++ b/src/insets/InsetBibtex.h @@ -27,6 +27,8 @@ public: /// InsetBibtex(InsetCommandParams const &); /// + void setBuffer(Buffer & buffer); + /// docstring screenLabel() const; /// EDITABLE editable() const { return IS_EDITABLE; } diff --git a/src/insets/InsetExternal.cpp b/src/insets/InsetExternal.cpp index c6f1142bc9..63102bc506 100644 --- a/src/insets/InsetExternal.cpp +++ b/src/insets/InsetExternal.cpp @@ -419,6 +419,14 @@ InsetExternal::~InsetExternal() } +void InsetExternal::setBuffer(Buffer & buffer) +{ + if (buffer_) + params_.filename = params_.filename.copyTo(&buffer); + Inset::setBuffer(buffer); +} + + void InsetExternal::statusChanged() const { updateFrontend(); diff --git a/src/insets/InsetExternal.h b/src/insets/InsetExternal.h index b5adef3d65..97c4b7a440 100644 --- a/src/insets/InsetExternal.h +++ b/src/insets/InsetExternal.h @@ -112,6 +112,8 @@ public: /// ~InsetExternal(); /// + void setBuffer(Buffer & buffer); + /// InsetCode lyxCode() const { return EXTERNAL_CODE; } /// EDITABLE editable() const { return IS_EDITABLE; } diff --git a/src/insets/InsetGraphics.cpp b/src/insets/InsetGraphics.cpp index 39c5d8ad3a..3f61db4aaf 100644 --- a/src/insets/InsetGraphics.cpp +++ b/src/insets/InsetGraphics.cpp @@ -154,6 +154,14 @@ InsetGraphics::~InsetGraphics() } +void InsetGraphics::setBuffer(Buffer & buffer) +{ + if (buffer_) + params_.filename = params_.filename.copyTo(&buffer); + Inset::setBuffer(buffer); +} + + void InsetGraphics::doDispatch(Cursor & cur, FuncRequest & cmd) { switch (cmd.action) { diff --git a/src/insets/InsetGraphics.h b/src/insets/InsetGraphics.h index b1270bb30c..b5c8043c23 100644 --- a/src/insets/InsetGraphics.h +++ b/src/insets/InsetGraphics.h @@ -34,6 +34,8 @@ public: /// ~InsetGraphics(); /// + void setBuffer(Buffer & buffer); + /// bool isLabeled() const { return true; } void metrics(MetricsInfo &, Dimension &) const; /// diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index 6b5ba04776..9b8428ae30 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -215,6 +215,12 @@ InsetInclude::~InsetInclude() void InsetInclude::setBuffer(Buffer & buffer) { + if (buffer_) { + EmbeddedFile file_from = includedFilename(*buffer_, params()); + EmbeddedFile file_to = file_from.copyTo(&buffer); + if (file_to.embedded()) + setParam("embed", from_utf8(file_to.inzipName())); + } buffer_ = &buffer; if (label_) label_->setBuffer(buffer);