From a7e45a73763ca3548dbad124965e246881ec15da Mon Sep 17 00:00:00 2001 From: Bo Peng Date: Sat, 1 Sep 2007 20:08:16 +0000 Subject: [PATCH] Embedding dialog: add extract and extractAll functions git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19977 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/EmbeddedFiles.cpp | 116 +++++++++++++----- src/EmbeddedFiles.h | 8 +- .../controllers/ControlEmbeddedFiles.cpp | 6 + .../controllers/ControlEmbeddedFiles.h | 2 + src/frontends/qt4/GuiEmbeddedFiles.cpp | 17 +++ src/frontends/qt4/GuiEmbeddedFiles.h | 2 + 6 files changed, 120 insertions(+), 31 deletions(-) diff --git a/src/EmbeddedFiles.cpp b/src/EmbeddedFiles.cpp index a781fdc2a0..e8bf1764d2 100644 --- a/src/EmbeddedFiles.cpp +++ b/src/EmbeddedFiles.cpp @@ -28,6 +28,8 @@ #include "support/filetools.h" #include "support/fs_extras.h" #include "support/convert.h" +#include "support/lyxlib.h" +#include "support/lstrings.h" #include #include @@ -61,6 +63,7 @@ using support::changeExtension; using support::bformat; using support::zipFiles; using support::prefixIs; +using support::sum; EmbeddedFile::EmbeddedFile(string const & file, string const & inzip_name, @@ -89,6 +92,61 @@ void EmbeddedFile::setParIter(ParConstIterator const & pit) } +string EmbeddedFile::availableFile(Buffer const * buf) const +{ + string ext_file = absFilename(); + string emb_file = embeddedFile(buf); + if (status_ == AUTO) { + // use external file first + if (fs::exists(ext_file)) + return ext_file; + else if (fs::exists(emb_file)) + return emb_file; + else + return string(); + } else if (status_ == EMBEDDED) { + // use embedded file first + if (fs::exists(emb_file)) + return emb_file; + else if (fs::exists(ext_file)) + return ext_file; + else + return string(); + } else + return string(); +} + + +bool EmbeddedFile::extract(Buffer const * buf) const +{ + string ext_file = absFilename(); + string emb_file = embeddedFile(buf); + bool copyFile = false; + // both files exist, are different, and in EMBEDDED status + if (fs::exists(ext_file) && fs::exists(emb_file) && status_ == EMBEDDED + && sum(*this) != sum(FileName(emb_file))) { + int const ret = Alert::prompt( + _("Overwrite external file?"), + bformat(_("External file %1$s already exists, do you want to overwrite it"), + from_utf8(ext_file)), 1, 1, _("&Overwrite"), _("&Cancel")); + copyFile = ret == 0; + } + // copy file in the previous case, and a new case + if (copyFile || (!fs::exists(ext_file) && fs::exists(emb_file))) { + try { + fs::copy_file(emb_file, ext_file, false); + return true; + } catch (fs::filesystem_error const & fe) { + Alert::error(_("Copy file failure"), + bformat(_("Cannot copy file %1$s to %2$s.\n" + "Please check whether the directory exists and is writeable."), + from_utf8(emb_file), from_utf8(ext_file))); + LYXERR(Debug::DEBUG) << "Fs error: " << fe.what() << endl; + } + } +} + + bool EmbeddedFiles::enabled() const { return buffer_->params().embedded; @@ -97,15 +155,13 @@ bool EmbeddedFiles::enabled() const void EmbeddedFiles::enable(bool flag) { - // FIXME: there are much more to do here. - // If we enable embedding, it is maybe a good idea to copy embedded files - // to temppath() - // if we disable embedding, embedded files need to be copied to their - // original positions. if (enabled() != flag) { - // file will be changed - buffer_->markDirty(); - buffer_->params().embedded = flag; + // if disable embedding, first extract all embedded files + if (flag || (!flag && extractAll())) { + // file will be changed + buffer_->markDirty(); + buffer_->params().embedded = flag; + } } } @@ -141,9 +197,9 @@ void EmbeddedFiles::update() EmbeddedFileList::iterator it = file_list_.begin(); EmbeddedFileList::iterator it_end = file_list_.end(); for (; it != it_end; ++it) - // if the status of a file is EMBEDDED, it will be there - // even if it is not referred by a document. - if (it->status() != EmbeddedFile::EMBEDDED) + // Only AUTO files will be updated. If the status of a file is EMBEDDED, + // it will be embedded even if it is not referred by a document. + if (it->status() == EmbeddedFile::AUTO) it->invalidate(); ParIterator pit = buffer_->par_iterator_begin(); @@ -183,25 +239,11 @@ bool EmbeddedFiles::write(DocFileName const & filename) EmbeddedFileList::iterator it_end = file_list_.end(); for (; it != it_end; ++it) { if (it->valid() && it->embedded()) { - string ext_file = it->absFilename(); - string emb_file = it->embeddedFile(buffer_); - if (it->status() == EmbeddedFile::AUTO) { - // use external file first - if (fs::exists(ext_file)) - filenames.push_back(make_pair(ext_file, it->inzipName())); - else if (fs::exists(emb_file)) - filenames.push_back(make_pair(emb_file, it->inzipName())); - else - lyxerr << "File " << ext_file << " does not exist. Skip embedding it. " << endl; - } else if (it->status() == EmbeddedFile::EMBEDDED) { - // use embedded file first - if (fs::exists(emb_file)) - filenames.push_back(make_pair(emb_file, it->inzipName())); - else if (fs::exists(ext_file)) - filenames.push_back(make_pair(ext_file, it->inzipName())); - else - lyxerr << "File " << ext_file << " does not exist. Skip embedding it. " << endl; - } + string file = it->availableFile(buffer_); + if (file.empty()) + lyxerr << "File " << it->absFilename() << " does not exist. Skip embedding it. " << endl; + else + filenames.push_back(make_pair(file, it->inzipName())); } } // add filename (.lyx) and manifest to filenames @@ -228,6 +270,20 @@ bool EmbeddedFiles::write(DocFileName const & filename) } +bool EmbeddedFiles::extractAll() const +{ + EmbeddedFileList::const_iterator it = file_list_.begin(); + EmbeddedFileList::const_iterator it_end = file_list_.end(); + // FIXME: the logic here is hard to decide, we should allow cancel for + // 'do not overwrite' this file, and cancel for 'cancel extract all files'. + // I am not sure how to do this now. + for (; it != it_end; ++it) + if (it->valid() && it->status() != EmbeddedFile::EXTERNAL) + it->extract(buffer_); + return true; +} + + string const EmbeddedFiles::getInzipName(string const & abs_filename) { // register a new one, using relative file path as inzip_name diff --git a/src/EmbeddedFiles.h b/src/EmbeddedFiles.h index c5b35a4314..132c84927c 100644 --- a/src/EmbeddedFiles.h +++ b/src/EmbeddedFiles.h @@ -151,6 +151,9 @@ public: std::string inzipName() const { return inzip_name_; } /// embedded file, equals to temppath()/inzipName() std::string embeddedFile(Buffer const * buf) const; + /// embeddedFile() or absFilename() depending on status_ and + /// file availability + std::string availableFile(Buffer const * buf) const; /// paragraph id void setParIter(ParConstIterator const & pit); @@ -170,6 +173,8 @@ public: bool valid() const { return valid_; } void validate() { valid_ = true; } void invalidate() { valid_ = false; } + /// + bool extract(Buffer const * buf) const; private: /// filename in zip file @@ -220,7 +225,8 @@ public: 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(); } - + /// + bool extractAll() const; /// friend std::istream & operator>> (std::istream & is, EmbeddedFiles &); diff --git a/src/frontends/controllers/ControlEmbeddedFiles.cpp b/src/frontends/controllers/ControlEmbeddedFiles.cpp index 6d051b1022..1d654ef4e2 100644 --- a/src/frontends/controllers/ControlEmbeddedFiles.cpp +++ b/src/frontends/controllers/ControlEmbeddedFiles.cpp @@ -87,5 +87,11 @@ docstring const ControlEmbeddedFiles::browseFile() } +bool ControlEmbeddedFiles::extract(EmbeddedFile const & item) +{ + return item.extract(&kernel().buffer()); +} + + } // namespace frontend } // namespace lyx diff --git a/src/frontends/controllers/ControlEmbeddedFiles.h b/src/frontends/controllers/ControlEmbeddedFiles.h index a327784259..77ce15a833 100644 --- a/src/frontends/controllers/ControlEmbeddedFiles.h +++ b/src/frontends/controllers/ControlEmbeddedFiles.h @@ -50,6 +50,8 @@ public: void view(EmbeddedFile const & item); /// docstring const browseFile(); + /// + bool extract(EmbeddedFile const & item); protected: // directly handle buffer embedded files diff --git a/src/frontends/qt4/GuiEmbeddedFiles.cpp b/src/frontends/qt4/GuiEmbeddedFiles.cpp index 2fbd69dd39..3b6c8a7682 100644 --- a/src/frontends/qt4/GuiEmbeddedFiles.cpp +++ b/src/frontends/qt4/GuiEmbeddedFiles.cpp @@ -129,7 +129,9 @@ void GuiEmbeddedFilesDialog::on_actionPB_clicked() if (action == "Add file") { addFile(); } else if (action == "Extract file") { + extractFile(); } else if (action == "Extract all") { + extractAll(); } else if (action == "Embed all") { } else if (action == "Embed layout file") { } else if (action == "View file") { @@ -149,6 +151,21 @@ void GuiEmbeddedFilesDialog::addFile() } +bool GuiEmbeddedFilesDialog::extractFile() +{ + EmbeddedFiles const & files = form_->embeddedFiles(); + QList selection = filesLW->selectedItems(); + form_->extract(files[filesLW->row(*selection.begin())]); +} + + +bool GuiEmbeddedFilesDialog::extractAll() +{ + EmbeddedFiles const & files = form_->embeddedFiles(); + files.extractAll(); +} + + void GuiEmbeddedFilesDialog::on_actionCB_stateChanged(int idx) { // valid action, enable action button diff --git a/src/frontends/qt4/GuiEmbeddedFiles.h b/src/frontends/qt4/GuiEmbeddedFiles.h index 70c1b17d13..d91ed43faa 100644 --- a/src/frontends/qt4/GuiEmbeddedFiles.h +++ b/src/frontends/qt4/GuiEmbeddedFiles.h @@ -45,6 +45,8 @@ public Q_SLOTS: void on_externalRB_clicked(); /// void addFile(); + bool extractFile(); + bool extractAll(); private: void set_embedding_status(EmbeddedFile::STATUS); /// -- 2.39.2