mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-23 10:18:50 +00:00
Embedding: add 'addFile' to embed arbitrary file, fix a few bugs along the way
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19967 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
efec6dde3d
commit
7a6edab5c1
@ -60,6 +60,7 @@ using support::makeRelPath;
|
|||||||
using support::changeExtension;
|
using support::changeExtension;
|
||||||
using support::bformat;
|
using support::bformat;
|
||||||
using support::zipFiles;
|
using support::zipFiles;
|
||||||
|
using support::prefixIs;
|
||||||
|
|
||||||
|
|
||||||
EmbeddedFile::EmbeddedFile(string const & file, string const & inzip_name,
|
EmbeddedFile::EmbeddedFile(string const & file, string const & inzip_name,
|
||||||
@ -75,6 +76,13 @@ string EmbeddedFile::embeddedFile(Buffer const * buf) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int const EmbeddedFile::parID() const
|
||||||
|
{
|
||||||
|
// some embedded file do not have a valid par iterator
|
||||||
|
return par_it_ == ParConstIterator() ? 0 : par_it_->id();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void EmbeddedFile::setParIter(ParConstIterator const & pit)
|
void EmbeddedFile::setParIter(ParConstIterator const & pit)
|
||||||
{
|
{
|
||||||
par_it_ = pit;
|
par_it_ = pit;
|
||||||
@ -119,23 +127,8 @@ void EmbeddedFiles::registerFile(string const & filename,
|
|||||||
it->validate();
|
it->validate();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// register a new one, using relative file path as inzip_name
|
file_list_.push_back(EmbeddedFile(abs_filename,
|
||||||
string inzip_name = to_utf8(makeRelPath(from_utf8(abs_filename),
|
getInzipName(abs_filename), status, pit));
|
||||||
from_utf8(buffer_->fileName())));
|
|
||||||
// if inzip_name is an absolute path, use filename only to avoid
|
|
||||||
// leaking of filesystem information in inzip_name
|
|
||||||
if (absolutePath(inzip_name))
|
|
||||||
inzip_name = onlyFilename(inzip_name);
|
|
||||||
// if this name has been used...
|
|
||||||
// use _1_name, _2_name etc
|
|
||||||
if (!validInzipName(inzip_name)) {
|
|
||||||
size_t i = 1;
|
|
||||||
string tmp = inzip_name;
|
|
||||||
do {
|
|
||||||
inzip_name = convert<string>(i) + "_" + tmp;
|
|
||||||
} while (!validInzipName(inzip_name));
|
|
||||||
}
|
|
||||||
file_list_.push_back(EmbeddedFile(abs_filename, inzip_name, status, pit));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -148,6 +141,9 @@ void EmbeddedFiles::update()
|
|||||||
EmbeddedFileList::iterator it = file_list_.begin();
|
EmbeddedFileList::iterator it = file_list_.begin();
|
||||||
EmbeddedFileList::iterator it_end = file_list_.end();
|
EmbeddedFileList::iterator it_end = file_list_.end();
|
||||||
for (; it != it_end; ++it)
|
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)
|
||||||
it->invalidate();
|
it->invalidate();
|
||||||
|
|
||||||
ParIterator pit = buffer_->par_iterator_begin();
|
ParIterator pit = buffer_->par_iterator_begin();
|
||||||
@ -187,14 +183,25 @@ bool EmbeddedFiles::write(DocFileName const & filename)
|
|||||||
EmbeddedFileList::iterator it_end = file_list_.end();
|
EmbeddedFileList::iterator it_end = file_list_.end();
|
||||||
for (; it != it_end; ++it) {
|
for (; it != it_end; ++it) {
|
||||||
if (it->valid() && it->embedded()) {
|
if (it->valid() && it->embedded()) {
|
||||||
// use external file if possible
|
string ext_file = it->absFilename();
|
||||||
if (it->status() != EmbeddedFile::EMBEDDED && fs::exists(it->absFilename()))
|
string emb_file = it->embeddedFile(buffer_);
|
||||||
filenames.push_back(make_pair(it->absFilename(), it->inzipName()));
|
if (it->status() == EmbeddedFile::AUTO) {
|
||||||
// use embedded file (AUTO or EMBEDDED mode)
|
// use external file first
|
||||||
else if(fs::exists(it->embeddedFile(buffer_)))
|
if (fs::exists(ext_file))
|
||||||
filenames.push_back(make_pair(it->embeddedFile(buffer_), it->inzipName()));
|
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
|
else
|
||||||
lyxerr << "File " << it->absFilename() << " does not exist. Skip embedding it. " << endl;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add filename (.lyx) and manifest to filenames
|
// add filename (.lyx) and manifest to filenames
|
||||||
@ -221,14 +228,35 @@ bool EmbeddedFiles::write(DocFileName const & filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool EmbeddedFiles::validInzipName(string const & name)
|
string const EmbeddedFiles::getInzipName(string const & abs_filename)
|
||||||
{
|
{
|
||||||
EmbeddedFileList::iterator it = file_list_.begin();
|
// register a new one, using relative file path as inzip_name
|
||||||
|
string inzip_name = to_utf8(makeRelPath(from_utf8(abs_filename),
|
||||||
|
from_utf8(buffer_->fileName())));
|
||||||
|
// if inzip_name is an absolute path, use filename only to avoid
|
||||||
|
// leaking of filesystem information in inzip_name
|
||||||
|
if (absolutePath(inzip_name) || prefixIs(inzip_name, ".."))
|
||||||
|
inzip_name = onlyFilename(inzip_name);
|
||||||
|
// if this name has been used...
|
||||||
|
// use _1_name, _2_name etc
|
||||||
|
string tmp = inzip_name;
|
||||||
|
EmbeddedFileList::iterator it;
|
||||||
EmbeddedFileList::iterator it_end = file_list_.end();
|
EmbeddedFileList::iterator it_end = file_list_.end();
|
||||||
|
bool unique_name = false;
|
||||||
|
while (!unique_name) {
|
||||||
|
unique_name = true;
|
||||||
|
size_t i = 0;
|
||||||
|
if (i > 0)
|
||||||
|
inzip_name = convert<string>(i) + "_" + tmp;
|
||||||
|
it = file_list_.begin();
|
||||||
for (; it != it_end; ++it)
|
for (; it != it_end; ++it)
|
||||||
if (it->inzipName() == name)
|
if (it->inzipName() == inzip_name) {
|
||||||
return false;
|
unique_name = false;
|
||||||
return true;
|
++i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inzip_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,7 +137,8 @@ public:
|
|||||||
// to generate output, and be embedded to the saved lyx file.
|
// to generate output, and be embedded to the saved lyx file.
|
||||||
// Otherwise, embedded version will be used.
|
// Otherwise, embedded version will be used.
|
||||||
AUTO,
|
AUTO,
|
||||||
// Always use embedded version.
|
// Always use embedded version. The file will be embedded even
|
||||||
|
// if the file is no longer referred by the document.
|
||||||
EMBEDDED,
|
EMBEDDED,
|
||||||
// Do not embed this file, always use external version.
|
// Do not embed this file, always use external version.
|
||||||
EXTERNAL
|
EXTERNAL
|
||||||
@ -153,7 +154,7 @@ public:
|
|||||||
|
|
||||||
/// paragraph id
|
/// paragraph id
|
||||||
void setParIter(ParConstIterator const & pit);
|
void setParIter(ParConstIterator const & pit);
|
||||||
int const parID() const { return par_it_->id(); }
|
int const parID() const;
|
||||||
|
|
||||||
/// embedding status of this file
|
/// embedding status of this file
|
||||||
bool embedded() const { return status_ != EXTERNAL; }
|
bool embedded() const { return status_ != EXTERNAL; }
|
||||||
@ -225,8 +226,8 @@ public:
|
|||||||
|
|
||||||
friend std::ostream & operator<< (std::ostream & os, EmbeddedFiles const &);
|
friend std::ostream & operator<< (std::ostream & os, EmbeddedFiles const &);
|
||||||
private:
|
private:
|
||||||
/// if a inzip name already exists
|
/// get a unique inzip name
|
||||||
bool validInzipName(std::string const & name);
|
std::string const getInzipName(std::string const & name);
|
||||||
/// list of embedded files
|
/// list of embedded files
|
||||||
EmbeddedFileList file_list_;
|
EmbeddedFileList file_list_;
|
||||||
///
|
///
|
||||||
|
@ -18,13 +18,20 @@
|
|||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "Format.h"
|
#include "Format.h"
|
||||||
|
#include "LyXRC.h"
|
||||||
|
|
||||||
|
#include "frontend_helpers.h"
|
||||||
#include "frontends/LyXView.h"
|
#include "frontends/LyXView.h"
|
||||||
|
|
||||||
|
#include "support/FileFilterList.h"
|
||||||
#include "support/convert.h"
|
#include "support/convert.h"
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
namespace lyx {
|
namespace lyx {
|
||||||
|
|
||||||
|
using support::FileFilterList;
|
||||||
|
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
|
|
||||||
ControlEmbeddedFiles::ControlEmbeddedFiles(Dialog & parent)
|
ControlEmbeddedFiles::ControlEmbeddedFiles(Dialog & parent)
|
||||||
@ -55,8 +62,11 @@ void ControlEmbeddedFiles::dispatchParams()
|
|||||||
|
|
||||||
void ControlEmbeddedFiles::goTo(EmbeddedFile const & item)
|
void ControlEmbeddedFiles::goTo(EmbeddedFile const & item)
|
||||||
{
|
{
|
||||||
|
int id = item.parID();
|
||||||
|
if (id != 0) {
|
||||||
string const tmp = convert<string>(item.parID());
|
string const tmp = convert<string>(item.parID());
|
||||||
kernel().lyxview().dispatch(FuncRequest(LFUN_PARAGRAPH_GOTO, tmp));
|
kernel().lyxview().dispatch(FuncRequest(LFUN_PARAGRAPH_GOTO, tmp));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -65,5 +75,17 @@ void ControlEmbeddedFiles::view(EmbeddedFile const & item)
|
|||||||
formats.view(kernel().buffer(), item, formats.getFormatFromFile(item));
|
formats.view(kernel().buffer(), item, formats.getFormatFromFile(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
docstring const ControlEmbeddedFiles::browseFile()
|
||||||
|
{
|
||||||
|
std::pair<docstring, docstring> dir1(_("Documents|#o#O"),
|
||||||
|
lyx::from_utf8(lyxrc.document_path));
|
||||||
|
FileFilterList const filter(_("All file (*.*)"));
|
||||||
|
return browseRelFile(docstring(), lyx::from_utf8(kernel().bufferFilepath()),
|
||||||
|
_("Select a file to embed"),
|
||||||
|
filter, false, dir1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace frontend
|
} // namespace frontend
|
||||||
} // namespace lyx
|
} // namespace lyx
|
||||||
|
@ -48,6 +48,8 @@ public:
|
|||||||
void goTo(EmbeddedFile const & item);
|
void goTo(EmbeddedFile const & item);
|
||||||
///
|
///
|
||||||
void view(EmbeddedFile const & item);
|
void view(EmbeddedFile const & item);
|
||||||
|
///
|
||||||
|
docstring const browseFile();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// directly handle buffer embedded files
|
// directly handle buffer embedded files
|
||||||
|
@ -127,6 +127,7 @@ void GuiEmbeddedFilesDialog::on_actionPB_clicked()
|
|||||||
// ACTION
|
// ACTION
|
||||||
QString action = actionCB->currentText();
|
QString action = actionCB->currentText();
|
||||||
if (action == "Add file") {
|
if (action == "Add file") {
|
||||||
|
addFile();
|
||||||
} else if (action == "Extract file") {
|
} else if (action == "Extract file") {
|
||||||
} else if (action == "Extract all") {
|
} else if (action == "Extract all") {
|
||||||
} else if (action == "Embed all") {
|
} else if (action == "Embed all") {
|
||||||
@ -138,6 +139,16 @@ void GuiEmbeddedFilesDialog::on_actionPB_clicked()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GuiEmbeddedFilesDialog::addFile()
|
||||||
|
{
|
||||||
|
docstring const file = form_->browseFile();
|
||||||
|
if (!file.empty()) {
|
||||||
|
EmbeddedFiles & files = form_->embeddedFiles();
|
||||||
|
files.registerFile(to_utf8(file), EmbeddedFile::EMBEDDED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiEmbeddedFilesDialog::on_actionCB_stateChanged(int idx)
|
void GuiEmbeddedFilesDialog::on_actionCB_stateChanged(int idx)
|
||||||
{
|
{
|
||||||
// valid action, enable action button
|
// valid action, enable action button
|
||||||
|
@ -43,6 +43,8 @@ public Q_SLOTS:
|
|||||||
void on_autoRB_clicked();
|
void on_autoRB_clicked();
|
||||||
void on_embeddedRB_clicked();
|
void on_embeddedRB_clicked();
|
||||||
void on_externalRB_clicked();
|
void on_externalRB_clicked();
|
||||||
|
///
|
||||||
|
void addFile();
|
||||||
private:
|
private:
|
||||||
void set_embedding_status(EmbeddedFile::STATUS);
|
void set_embedding_status(EmbeddedFile::STATUS);
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user