From 5ffc0d19c1fed59b310658cdefa2f2db71265324 Mon Sep 17 00:00:00 2001 From: Bo Peng Date: Sat, 15 Mar 2008 04:48:31 +0000 Subject: [PATCH] Embedding: when an inset with an embedded file is copied to another buffer, the embedded file needs to be copied, to an external file or to the temporary directory of that buffer. Otherwise, pasted insets will become invalid when the source buffer is closed and the embedded files are removed. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23758 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/EmbeddedFiles.cpp | 60 +++++++++++++++++++++++++++++++++++- src/EmbeddedFiles.h | 2 ++ src/insets/InsetBibtex.cpp | 12 ++++++++ src/insets/InsetBibtex.h | 2 ++ src/insets/InsetExternal.cpp | 8 +++++ src/insets/InsetExternal.h | 2 ++ src/insets/InsetGraphics.cpp | 8 +++++ src/insets/InsetGraphics.h | 2 ++ src/insets/InsetInclude.cpp | 6 ++++ 9 files changed, 101 insertions(+), 1 deletion(-) 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); -- 2.39.2