]> git.lyx.org Git - features.git/commitdiff
Embedding dialog: add extract and extractAll functions
authorBo Peng <bpeng@lyx.org>
Sat, 1 Sep 2007 20:08:16 +0000 (20:08 +0000)
committerBo Peng <bpeng@lyx.org>
Sat, 1 Sep 2007 20:08:16 +0000 (20:08 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19977 a592a061-630c-0410-9148-cb99ea01b6c8

src/EmbeddedFiles.cpp
src/EmbeddedFiles.h
src/frontends/controllers/ControlEmbeddedFiles.cpp
src/frontends/controllers/ControlEmbeddedFiles.h
src/frontends/qt4/GuiEmbeddedFiles.cpp
src/frontends/qt4/GuiEmbeddedFiles.h

index a781fdc2a0db8b45dc4a7ed61bb73abcf934aad4..e8bf1764d2610fc8c5292d10ea8365115019e323 100644 (file)
@@ -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 <sstream>
 #include <fstream>
@@ -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
index c5b35a4314fd16004f06a63f2b91be295a72d596..132c84927c6025bb153c136c1b43701824166153 100644 (file)
@@ -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 &);
 
index 6d051b10225edaa697811d0f8679ceb46ec6b3d5..1d654ef4e24ca2f7775a2469af32ca67e0a06546 100644 (file)
@@ -87,5 +87,11 @@ docstring const ControlEmbeddedFiles::browseFile()
 }
 
 
+bool ControlEmbeddedFiles::extract(EmbeddedFile const & item)
+{
+       return item.extract(&kernel().buffer());
+}
+
+
 } // namespace frontend
 } // namespace lyx
index a327784259239ccaa46e938ad5cf0fd6c29750dc..77ce15a833d093eefda1cc02ccd8b0abb92bcf75 100644 (file)
@@ -50,6 +50,8 @@ public:
        void view(EmbeddedFile const & item);
        ///
        docstring const browseFile();
+       ///
+       bool extract(EmbeddedFile const & item);
 
 protected:
        // directly handle buffer embedded files
index 2fbd69dd39560aebb08a01a39fd4ae7d604712a7..3b6c8a7682453505148c048b810cd22a84ddf664 100644 (file)
@@ -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<QListWidgetItem *> 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
index 70c1b17d134dea67b2c9b1163ab9c052a718e8a4..d91ed43faae6ebfa57b7643277bba9dbd6bef857 100644 (file)
@@ -45,6 +45,8 @@ public Q_SLOTS:
        void on_externalRB_clicked();
        ///
        void addFile();
+       bool extractFile();
+       bool extractAll();
 private:
        void set_embedding_status(EmbeddedFile::STATUS);
        ///