Embedding dialog: add extract and extractAll functions

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19977 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Bo Peng 2007-09-01 20:08:16 +00:00
parent e0db6e2679
commit a7e45a7376
6 changed files with 120 additions and 31 deletions

View 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

View 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 &);

View File

@ -87,5 +87,11 @@ docstring const ControlEmbeddedFiles::browseFile()
}
bool ControlEmbeddedFiles::extract(EmbeddedFile const & item)
{
return item.extract(&kernel().buffer());
}
} // namespace frontend
} // namespace lyx

View 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

View 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

View 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);
///