Embedding: remove AUTO feature, barely make it compile

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@20119 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Bo Peng 2007-09-07 03:02:24 +00:00
parent 7280043b2e
commit d4a2219813
7 changed files with 90 additions and 131 deletions

View File

@ -67,8 +67,8 @@ using support::makedir;
EmbeddedFile::EmbeddedFile(string const & file, string const & inzip_name,
STATUS status, ParConstIterator const & pit)
: DocFileName(file, true), inzip_name_(inzip_name), status_(status),
bool embed, ParConstIterator const & pit)
: DocFileName(file, true), inzip_name_(inzip_name), embedded_(embed),
valid_(true), par_it_(pit)
{}
@ -94,36 +94,23 @@ 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();
if (embedded_)
return embeddedFile(buf);
else
return absFilename();
}
bool EmbeddedFile::extract(Buffer const * buf) const
{
if (!embedded_)
return true;
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
// both files exist, are different
if (fs::exists(ext_file) && fs::exists(emb_file)
&& sum(*this) != sum(FileName(emb_file))) {
int const ret = Alert::prompt(
_("Overwrite external file?"),
@ -151,7 +138,43 @@ bool EmbeddedFile::extract(Buffer const * buf) const
return false;
}
bool EmbeddedFile::embed(Buffer const * buf)
{
string ext_file = absFilename();
string emb_file = embeddedFile(buf);
bool copyFile = false;
// both files exist, are different
if (fs::exists(ext_file) && fs::exists(emb_file)
&& sum(*this) != sum(FileName(emb_file))) {
int const ret = Alert::prompt(
_("Update embedded file?"),
bformat(_("Embeddedl 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 {
// need to make directory?
string path = onlyPath(emb_file);
if (!fs::is_directory(path))
makedir(const_cast<char*>(path.c_str()), 0755);
fs::copy_file(ext_file, emb_file, false);
embedded_ = 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(ext_file), from_utf8(emb_file)));
LYXERR(Debug::DEBUG) << "Fs error: " << fe.what() << endl;
embedded_ = false;
}
}
return embedded_;
}
bool EmbeddedFiles::enabled() const
{
return buffer_->params().embedded;
@ -172,7 +195,7 @@ void EmbeddedFiles::enable(bool flag)
void EmbeddedFiles::registerFile(string const & filename,
EmbeddedFile::STATUS status, ParConstIterator const & pit)
bool embed, ParConstIterator const & pit)
{
string abs_filename = makeAbsPath(filename, buffer_->filePath()).absFilename();
// try to find this file from the list
@ -184,12 +207,12 @@ void EmbeddedFiles::registerFile(string const & filename,
// find this filename
if (it != file_list_.end()) {
it->setParIter(pit);
it->setStatus(status);
it->embed(buffer_);
it->validate();
return;
}
file_list_.push_back(EmbeddedFile(abs_filename,
getInzipName(abs_filename), status, pit));
getInzipName(abs_filename), embed, pit));
}
@ -202,10 +225,7 @@ void EmbeddedFiles::update()
EmbeddedFileList::iterator it = file_list_.begin();
EmbeddedFileList::iterator it_end = file_list_.end();
for (; it != it_end; ++it)
// 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();
it->invalidate();
ParIterator pit = buffer_->par_iterator_begin();
ParIterator pit_end = buffer_->par_iterator_end();
@ -294,7 +314,7 @@ bool EmbeddedFiles::extractAll() const
// '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)
if (it->valid() && it->embedded())
it->extract(buffer_);
return true;
}
@ -366,8 +386,8 @@ istream & operator>> (istream & is, EmbeddedFiles & files)
getline(is, inzip_name);
getline(is, tmp);
istringstream itmp(tmp);
int status;
itmp >> status;
int embed;
itmp >> embed;
getline(is, tmp);
if (tmp != "</file>") {
@ -375,7 +395,7 @@ istream & operator>> (istream & is, EmbeddedFiles & files)
break;
}
files.registerFile(fname, static_cast<EmbeddedFile::STATUS>(status));
files.registerFile(fname, embed);
};
// the last line must be </manifest>
if (tmp != "</manifest>") {
@ -403,7 +423,7 @@ ostream & operator<< (ostream & os, EmbeddedFiles const & files)
<< to_utf8(makeRelPath(from_utf8(it->absFilename()),
from_utf8(files.buffer_->filePath()))) << '\n'
<< it->inzipName() << '\n'
<< it->status() << '\n'
<< it->embedded() << '\n'
<< "</file>\n";
}
os << "</manifest>\n";

View File

@ -33,20 +33,10 @@ Expected features:
1. With embedding enabled (disabled by default), .lyx file can embed graphics,
listings, bib file etc.
2. Embedding of certain files are automatic (graphics, bib etc), and
other files can be embedded manually.
3. Embedded file.lyx file is a zip file, with file.lyx, manifest.txt
2. Embedded file.lyx file is a zip file, with file.lyx, manifest.txt
and embedded files.
4. Embedded files can be "EMBEDDED", "EXTERNAL", or "AUTO". In the
"AUTO" mode, external files will be used if available; otherwise the
embedded version will be used. In this way, users can work as usual by
modifying external listings, graphics, and do not have to worry about
embedding. "EMBEDDED" and "EXTERNAL" modes ignore or use external files
respectively.
5. An embedding dialog is provided to change embedding status (buffer
3. An embedding dialog is provided to change embedding status (buffer
level or individual embedded files), manually embed, extract, view
or edit files.
@ -59,9 +49,11 @@ of .lyx file and better use of version control systems.
b. The embedded way. Figures etc are inserted to .lyx file and will
be embedded. These embedded files can be viewed or edited through
the embedding dialog. This file can be shared with others more
easily. The advantage of lyx' embedding approach is that external files
will be automatically used and embedded if the file is in "AUTO" mode.
easily.
Format a anb b can be converted easily, by enable/disable embedding. Diabling
embedding is also called unpacking because all embedded files will be copied
to their original locations.
Implementation:
======================
@ -73,12 +65,11 @@ This class keeps a manifest that has
b. inzip filename. It is the relative path name if the embedded file is
in or under the document directory, or file name otherwise. Name aliasing
is used if two external files share the same name.
c. embedding mode.
c. embedding status.
It also provides functions to
a. manipulate manifest
b. scan a buffer for embeddable files
c. look up inzipname from external filename
d. look up external filename from inzipname
c. determine which file to use according to embedding status
2. When a file is saved, it is scanned for embedded files. (c.f.
EmbeddedFiles::update(), Inset::registerEmbeddedFiles()).
@ -99,18 +90,11 @@ a embedding dialog. It handles a EmbddedFiles point directly.
From this dialog, a user can disable embedding, change embedding status,
or embed other files, extract, view, edit files.
6. When a lyx file is loaded, Embedded files can have
a. both external and internal copy
b. only external copy (filename())
c. only embedded copy (temppath()/inzipname)
And each can have "AUTO", "EXTERNAL", "EMBEDDED" status. Proper
handling of each case is required.
7. If embedding of a .lyx file with embedded files is disabled, all its
6. If embedding of a .lyx file with embedded files is disabled, all its
embedded files are copied to their respective external filenames. This
is why external filename will exist even if a file is at "EMBEDDED" status.
8. Individual embeddable insets should find ways to handle embedded files.
7. Individual embeddable insets should find ways to handle embedded files.
InsetGraphics replace params().filename with its temppath()/inzipname version
when the inset is created. The filename appears as /tmp/..../inzipname
when lyx runs. When params().filename is saved, lyx checks if this is an
@ -127,32 +111,14 @@ class Buffer;
class EmbeddedFile : public support::DocFileName
{
public:
/**
Embedding status of this DocFileName.
*/
enum STATUS {
// uninitialized/invalid status
NONE,
// If the external version of the file is available, it will be used
// to generate output, and be embedded to the saved lyx file.
// Otherwise, embedded version will be used.
AUTO,
// Always use embedded version. The file will be embedded even
// if the file is no longer referred by the document.
EMBEDDED,
// Do not embed this file, always use external version.
EXTERNAL
};
EmbeddedFile(std::string const & file, std::string const & inzip_name,
STATUS status, ParConstIterator const & pit);
bool embedded, ParConstIterator const & pit);
/// filename in the zip file, usually the relative path
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
/// embeddedFile() or absFilename() depending on embedding status
std::string availableFile(Buffer const * buf) const;
/// paragraph id
@ -160,9 +126,7 @@ public:
int const parID() const;
/// embedding status of this file
bool embedded() const { return status_ != EXTERNAL; }
STATUS status() const { return status_; }
void setStatus(STATUS status) { status_ = status; }
bool embedded() const { return embedded_; }
// A flag indicating whether or not this filename is valid.
// When lyx runs, InsetGraphics etc may be added or removed so filename
@ -175,12 +139,14 @@ public:
void invalidate() { valid_ = false; }
///
bool extract(Buffer const * buf) const;
///
bool embed(Buffer const * buf);
private:
/// filename in zip file
std::string inzip_name_;
/// the status of this docfile
STATUS status_;
bool embedded_;
///
bool valid_;
/// Current position of the item, used to locate the files
@ -205,8 +171,7 @@ public:
void enable(bool flag);
/// add a file item
void registerFile(std::string const & filename,
EmbeddedFile::STATUS status = EmbeddedFile::AUTO,
void registerFile(std::string const & filename, bool embed = false,
ParConstIterator const & pit = ParConstIterator());
/// scan the buffer and get a list of EmbeddedFile

View File

@ -18,7 +18,6 @@ namespace lyx {
namespace frontend {
static QString const INVALID_COLOR = "gray";
static QString const AUTO_COLOR = "green";
static QString const EMBEDDED_COLOR = "black";
static QString const EXTERNAL_COLOR = "blue";
@ -64,22 +63,15 @@ void GuiEmbeddedFilesDialog::on_filesLW_itemSelectionChanged()
controller().goTo(files[idx]);
}
EmbeddedFile::STATUS mode = EmbeddedFile::NONE;
bool mode = false;
for (; it != it_end; ++it) {
int idx = filesLW->row(*it);
if (mode == EmbeddedFile::NONE) {
mode = files[idx].status();
if (mode) {
mode = true;
continue;
}
if (mode != files[idx].status()) {
mode = EmbeddedFile::NONE;
break;
}
}
autoRB->setChecked(mode == EmbeddedFile::AUTO);
embeddedRB->setChecked(mode == EmbeddedFile::EMBEDDED);
externalRB->setChecked(mode == EmbeddedFile::EXTERNAL);
}
@ -103,9 +95,7 @@ void GuiEmbeddedFilesDialog::updateView()
QListWidgetItem * item = new QListWidgetItem(toqstr(it->inzipName()));
if (!it->valid())
item->setTextColor(INVALID_COLOR);
else if(it->status() == EmbeddedFile::AUTO)
item->setTextColor(AUTO_COLOR);
else if(it->status() == EmbeddedFile::EMBEDDED)
else if(it->embedded())
item->setTextColor(EMBEDDED_COLOR);
else
item->setTextColor(EXTERNAL_COLOR);
@ -124,7 +114,7 @@ void GuiEmbeddedFilesDialog::on_addPB_clicked()
docstring const file = controller().browseFile();
if (!file.empty()) {
EmbeddedFiles & files = controller().embeddedFiles();
files.registerFile(to_utf8(file), EmbeddedFile::EMBEDDED);
files.registerFile(to_utf8(file), true);
}
}
@ -157,7 +147,7 @@ void GuiEmbeddedFilesDialog::on_enableCB_toggled(bool enable)
}
void GuiEmbeddedFilesDialog::set_embedding_status(EmbeddedFile::STATUS status)
void GuiEmbeddedFilesDialog::set_embedding_status(bool embed)
{
EmbeddedFiles & files = controller().embeddedFiles();
QList<QListWidgetItem *> selection = filesLW->selectedItems();
@ -165,44 +155,29 @@ void GuiEmbeddedFilesDialog::set_embedding_status(EmbeddedFile::STATUS status)
it != selection.end(); ++it) {
int row = filesLW->row(*it);
// FIXME: mark buffer dirty
if (status != files[row].status())
files[row].setStatus(status);
if(status == EmbeddedFile::AUTO)
(*it)->setTextColor(AUTO_COLOR);
else if(status == EmbeddedFile::EMBEDDED)
if(embed)
(*it)->setTextColor(EMBEDDED_COLOR);
else
(*it)->setTextColor(EXTERNAL_COLOR);
}
if (status == EmbeddedFile::AUTO)
controller().setMessage("Switch to auto embedding");
else if (status == EmbeddedFile::EMBEDDED)
controller().setMessage("Switch to always embedding");
if (embed)
controller().setMessage("Embed file");
else
controller().setMessage("Switch to never embedding");
autoRB->setChecked(status == EmbeddedFile::AUTO);
embeddedRB->setChecked(status == EmbeddedFile::EMBEDDED);
externalRB->setChecked(status == EmbeddedFile::EXTERNAL);
controller().setMessage("Extract file");
// update bufferView
controller().dispatchParams();
}
void GuiEmbeddedFilesDialog::on_autoRB_clicked()
{
set_embedding_status(EmbeddedFile::AUTO);
}
void GuiEmbeddedFilesDialog::on_embeddedRB_clicked()
{
set_embedding_status(EmbeddedFile::EMBEDDED);
set_embedding_status(true);
}
void GuiEmbeddedFilesDialog::on_externalRB_clicked()
{
set_embedding_status(EmbeddedFile::EXTERNAL);
set_embedding_status(false);
}

View File

@ -37,7 +37,6 @@ public Q_SLOTS:
///
void on_enableCB_toggled(bool enable);
///
void on_autoRB_clicked();
void on_embeddedRB_clicked();
void on_externalRB_clicked();
///
@ -47,7 +46,7 @@ public Q_SLOTS:
private:
ControlEmbeddedFiles & controller() const;
void set_embedding_status(EmbeddedFile::STATUS);
void set_embedding_status(bool embed);
};
} // namespace frontend

View File

@ -496,7 +496,7 @@ bool InsetExternal::getStatus(Cursor & cur, FuncRequest const & cmd,
void InsetExternal::registerEmbeddedFiles(Buffer const &,
EmbeddedFiles & files, ParConstIterator const & pit) const
{
files.registerFile(params_.filename.absFilename(), EmbeddedFile::AUTO, pit);
files.registerFile(params_.filename.absFilename(), false, pit);
}

View File

@ -235,7 +235,7 @@ void InsetGraphics::registerEmbeddedFiles(Buffer const &,
EmbeddedFiles & files, ParConstIterator const & pit) const
{
files.registerFile(params().filename.absFilename(),
EmbeddedFile::AUTO, pit);
false, pit);
}

View File

@ -964,7 +964,7 @@ void InsetInclude::registerEmbeddedFiles(Buffer const & buffer,
// include and input are temprarily not considered.
if (isVerbatim(params_) || isListings(params_))
files.registerFile(includedFilename(buffer, params_).absFilename(),
EmbeddedFile::AUTO, pit);
false, pit);
}