X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Finsets%2FInsetExternal.cpp;h=ea2c0c41767df2ee1d309efba77a8230b750be1e;hb=7f461f4392a19cf488dec005d2f12cfea83655d9;hp=9b51d7b23277fe900152e0c403cd0928f6474dc8;hpb=ed858d73e57ce7aa89e38c1bc4d799362edb0227;p=lyx.git diff --git a/src/insets/InsetExternal.cpp b/src/insets/InsetExternal.cpp index 9b51d7b232..ea2c0c4176 100644 --- a/src/insets/InsetExternal.cpp +++ b/src/insets/InsetExternal.cpp @@ -18,23 +18,28 @@ #include "insets/RenderPreview.h" #include "Buffer.h" +#include "BufferView.h" #include "Cursor.h" -#include "debug.h" #include "DispatchResult.h" #include "Exporter.h" #include "FuncStatus.h" #include "FuncRequest.h" -#include "gettext.h" #include "LaTeXFeatures.h" -#include "LyX.h" #include "Lexer.h" +#include "LyX.h" // use_gui #include "LyXRC.h" #include "MetricsInfo.h" #include "OutputParams.h" +#include "frontends/alert.h" +#include "frontends/Application.h" + #include "graphics/PreviewLoader.h" +#include "support/debug.h" +#include "support/ExceptionMessage.h" #include "support/filetools.h" +#include "support/gettext.h" #include "support/lstrings.h" #include "support/lyxlib.h" #include "support/convert.h" @@ -44,12 +49,8 @@ #include -using std::string; -using std::istringstream; -using std::ostream; -using std::ostringstream; -using std::vector; - +using namespace std; +using namespace lyx::support; namespace { @@ -64,15 +65,17 @@ string defaultTemplateName; namespace lyx { +namespace Alert = frontend::Alert; + namespace external { TempName::TempName() { - support::FileName const tempname(support::tempName(support::FileName(), "lyxext")); + FileName const tempname = FileName::tempName("lyxext"); // FIXME: This is unsafe - support::unlink(tempname); + tempname.removeFile(); // must have an extension for the converter code to work correctly. - tempname_ = support::FileName(tempname.absFilename() + ".tmp"); + tempname_ = FileName(tempname.absFilename() + ".tmp"); } @@ -84,12 +87,11 @@ TempName::TempName(TempName const &) TempName::~TempName() { - support::unlink(tempname_); + tempname_.removeFile(); } -TempName & -TempName::operator=(TempName const & other) +TempName & TempName::operator=(TempName const & other) { if (this != &other) tempname_ = TempName()(); @@ -152,7 +154,7 @@ void clearIfNotFound(T & data, external::TransformID value, const_iterator it = ids.begin(); const_iterator end = ids.end(); - it = std::find(it, end, value); + it = find(it, end, value); if (it == end) data = T(); } @@ -181,16 +183,15 @@ void InsetExternalParams::settemplate(string const & name) } -void InsetExternalParams::write(Buffer const & buffer, ostream & os) const +void InsetExternalParams::write(Buffer const & buf, ostream & os) const { os << "External\n" << "\ttemplate " << templatename() << '\n'; - if (!filename.empty()) - os << "\tfilename " - << filename.outputFilename(buffer.filePath()) - << '\n'; - + if (!filename.empty()) { + os << "\tfilename " << filename.outputFilename(buf.filePath()) << '\n'; + os << "\tembed " << (filename.embedded() ? filename.inzipName() : "\"\"") << '\n'; + } if (display != defaultDisplayType) os << "\tdisplay " << external::displayTranslator().find(display) @@ -223,7 +224,6 @@ void InsetExternalParams::write(Buffer const & buffer, ostream & os) const } if (!resizedata.no_resize()) { - using support::float_equal; double const scl = convert(resizedata.scale); if (!float_equal(scl, 0.0, 0.05)) { if (!float_equal(scl, 100.0, 0.05)) @@ -245,9 +245,10 @@ void InsetExternalParams::write(Buffer const & buffer, ostream & os) const bool InsetExternalParams::read(Buffer const & buffer, Lexer & lex) { - enum ExternalTags { + enum { EX_TEMPLATE = 1, EX_FILENAME, + EX_EMBED, EX_DISPLAY, EX_LYXSCALE, EX_DRAFT, @@ -263,12 +264,13 @@ bool InsetExternalParams::read(Buffer const & buffer, Lexer & lex) EX_END }; - keyword_item external_tags[] = { + LexerKeyword external_tags[] = { { "\\end_inset", EX_END }, { "boundingBox", EX_BOUNDINGBOX }, { "clip", EX_CLIP }, { "display", EX_DISPLAY}, { "draft", EX_DRAFT}, + { "embed", EX_EMBED}, { "extra", EX_EXTRA }, { "filename", EX_FILENAME}, { "height", EX_HEIGHT }, @@ -281,7 +283,7 @@ bool InsetExternalParams::read(Buffer const & buffer, Lexer & lex) { "width", EX_WIDTH } }; - PushPopHelper pph(lex, external_tags, EX_END); + PushPopHelper pph(lex, external_tags); bool found_end = false; bool read_error = false; @@ -299,6 +301,14 @@ bool InsetExternalParams::read(Buffer const & buffer, Lexer & lex) filename.set(name, buffer.filePath()); break; } + + case EX_EMBED: { + lex.next(); + string const name = lex.getString(); + filename.setInzipName(name); + filename.setEmbed(!name.empty()); + break; + } case EX_DISPLAY: { lex.next(); @@ -373,8 +383,7 @@ bool InsetExternalParams::read(Buffer const & buffer, Lexer & lex) break; default: - lex.printError("ExternalInset::read: " - "Wrong tag: $$Token"); + lex.printError("ExternalInset::read: Wrong tag: $$Token"); read_error = true; break; } @@ -398,9 +407,11 @@ bool InsetExternalParams::read(Buffer const & buffer, Lexer & lex) } -InsetExternal::InsetExternal() +InsetExternal::InsetExternal(Buffer & buf) : renderer_(new RenderButton) -{} +{ + Inset::setBuffer(buf); +} InsetExternal::InsetExternal(InsetExternal const & other) @@ -411,21 +422,32 @@ InsetExternal::InsetExternal(InsetExternal const & other) {} -Inset * InsetExternal::clone() const +InsetExternal::~InsetExternal() { - return new InsetExternal(*this); + hideDialogs("external", this); } -InsetExternal::~InsetExternal() +void InsetExternal::setBuffer(Buffer & buffer) { - InsetExternalMailer(*this).hideDialog(); + if (buffer_) { + try { + // a file may not be copied successfully when, e.g. buffer_ + // has already been closed. + params_.filename = params_.filename.copyTo(buffer); + } catch (ExceptionMessage const & message) { + Alert::error(message.title_, message.details_); + // failed to embed + params_.filename.setEmbed(false); + } + } + Inset::setBuffer(buffer); } void InsetExternal::statusChanged() const { - LyX::cref().updateInset(this); + updateFrontend(); } @@ -434,28 +456,30 @@ void InsetExternal::doDispatch(Cursor & cur, FuncRequest & cmd) switch (cmd.action) { case LFUN_EXTERNAL_EDIT: { - Buffer const & buffer = cur.buffer(); - InsetExternalParams p; - InsetExternalMailer::string2params(to_utf8(cmd.argument()), buffer, p); - external::editExternal(p, buffer); + InsetExternalParams p = params(); + if (!cmd.argument().empty()) + string2params(to_utf8(cmd.argument()), buffer(), p); + external::editExternal(p, buffer()); break; } case LFUN_INSET_MODIFY: { - Buffer const & buffer = cur.buffer(); InsetExternalParams p; - InsetExternalMailer::string2params(to_utf8(cmd.argument()), buffer, p); - setParams(p, buffer); + string2params(to_utf8(cmd.argument()), buffer(), p); + setParams(p); break; } case LFUN_INSET_DIALOG_UPDATE: - InsetExternalMailer(*this).updateDialog(&cur.bv()); + cur.bv().updateDialog("external", + params2string(params(), cur.bv().buffer())); break; case LFUN_MOUSE_RELEASE: - if (!cur.selection()) - InsetExternalMailer(*this).showDialog(&cur.bv()); + if (!cur.selection() && cmd.button() == mouse_button::button1) + cur.bv().showDialog("external", + params2string(params(), cur.bv().buffer()), + this); break; default: @@ -481,24 +505,34 @@ bool InsetExternal::getStatus(Cursor & cur, FuncRequest const & cmd, } -void InsetExternal::edit(Cursor & cur, bool) +void InsetExternal::registerEmbeddedFiles(EmbeddedFileList & files) const { - InsetExternalMailer(*this).showDialog(&cur.bv()); + files.registerFile(params_.filename, this, buffer()); } -bool InsetExternal::metrics(MetricsInfo & mi, Dimension & dim) const +void InsetExternal::updateEmbeddedFile(EmbeddedFile const & file) +{ + params_.filename = file; +} + + +void InsetExternal::edit(Cursor & cur, bool, EntryDirection) +{ + cur.bv().showDialog("external", + params2string(params(), cur.bv().buffer()), + this); +} + + +void InsetExternal::metrics(MetricsInfo & mi, Dimension & dim) const { renderer_->metrics(mi, dim); - bool const changed = dim_ != dim; - dim_ = dim; - return changed; } void InsetExternal::draw(PainterInfo & pi, int x, int y) const { - setPosCache(pi, x, y); renderer_->draw(pi, x, y); } @@ -536,7 +570,8 @@ graphics::Params get_grfx_params(InsetExternalParams const & eparams) { graphics::Params gparams; - gparams.filename = eparams.filename; + gparams.filename = eparams.filename.availableFile(); + gparams.icon = eparams.filename.embedded() ? "pin.png" : ""; gparams.scale = eparams.lyxscale; if (eparams.clipdata.clip) gparams.bb = eparams.clipdata.bbox; @@ -559,10 +594,10 @@ graphics::Params get_grfx_params(InsetExternalParams const & eparams) gparams.display = graphics::NoDisplay; break; default: - BOOST_ASSERT(false); + LASSERT(false, /**/); } if (gparams.display == graphics::DefaultDisplay) - gparams.display = lyxrc.display_graphics; + gparams.display = graphics::DisplayType(lyxrc.display_graphics); // Override the above if we're not using a gui if (!use_gui) gparams.display = graphics::NoDisplay; @@ -571,14 +606,14 @@ graphics::Params get_grfx_params(InsetExternalParams const & eparams) } -docstring const getScreenLabel(InsetExternalParams const & params, +docstring screenLabel(InsetExternalParams const & params, Buffer const & buffer) { external::Template const * const ptr = external::getTemplatePtr(params); if (!ptr) // FIXME UNICODE - return support::bformat((_("External template %1$s is not installed")), + return bformat((_("External template %1$s is not installed")), from_utf8(params.templatename())); // FIXME UNICODE docstring gui = _(ptr->guiName); @@ -586,21 +621,51 @@ docstring const getScreenLabel(InsetExternalParams const & params, to_utf8(gui), false)); } -void add_preview_and_start_loading(RenderMonitoredPreview &, - InsetExternal const &, - Buffer const &); - } // namespace anon +static bool isPreviewWanted(InsetExternalParams const & params) +{ + return params.display == external::PreviewDisplay && + params.filename.isReadableFile(); +} + + +static docstring latexString(InsetExternal const & inset) +{ + odocstringstream os; + // We don't need to set runparams.encoding since it is not used by + // latex(). + OutputParams runparams(0); + runparams.flavor = OutputParams::LATEX; + inset.latex(os, runparams); + return os.str(); +} + + +static void add_preview_and_start_loading(RenderMonitoredPreview & renderer, + InsetExternal const & inset, + Buffer const & buffer) +{ + InsetExternalParams const & params = inset.params(); + + if (RenderPreview::status() != LyXRC::PREVIEW_OFF && + isPreviewWanted(params)) { + renderer.setAbsFile(params.filename); + docstring const snippet = latexString(inset); + renderer.addPreview(snippet, buffer); + renderer.startLoading(buffer); + } +} + + InsetExternalParams const & InsetExternal::params() const { return params_; } -void InsetExternal::setParams(InsetExternalParams const & p, - Buffer const & buffer) +void InsetExternal::setParams(InsetExternalParams const & p) { params_ = p; @@ -616,10 +681,11 @@ void InsetExternal::setParams(InsetExternalParams const & p, button_ptr = renderer_->asButton(); } - button_ptr->update(getScreenLabel(params_, buffer), true); + button_ptr->update(screenLabel(params_, buffer()), true); break; + } - } case RENDERGRAPHIC: { + case RENDERGRAPHIC: { RenderGraphic * graphic_ptr = renderer_->asGraphic(); if (!graphic_ptr) { renderer_.reset(new RenderGraphic(this)); @@ -629,8 +695,9 @@ void InsetExternal::setParams(InsetExternalParams const & p, graphic_ptr->update(get_grfx_params(params_)); break; + } - } case RENDERPREVIEW: { + case RENDERPREVIEW: { RenderMonitoredPreview * preview_ptr = renderer_->asMonitoredPreview(); if (!preview_ptr) { @@ -642,7 +709,7 @@ void InsetExternal::setParams(InsetExternalParams const & p, if (preview_ptr->monitoring()) preview_ptr->stopMonitoring(); - add_preview_and_start_loading(*preview_ptr, *this, buffer); + add_preview_and_start_loading(*preview_ptr, *this, buffer()); break; } @@ -652,40 +719,41 @@ void InsetExternal::setParams(InsetExternalParams const & p, void InsetExternal::fileChanged() const { - Buffer const * const buffer_ptr = LyX::cref().updateInset(this); - if (!buffer_ptr) + Buffer const * const buffer = updateFrontend(); + if (!buffer) return; RenderMonitoredPreview * const ptr = renderer_->asMonitoredPreview(); - BOOST_ASSERT(ptr); + LASSERT(ptr, /**/); - Buffer const & buffer = *buffer_ptr; - ptr->removePreview(buffer); - add_preview_and_start_loading(*ptr, *this, buffer); + ptr->removePreview(*buffer); + add_preview_and_start_loading(*ptr, *this, *buffer); } -void InsetExternal::write(Buffer const & buffer, ostream & os) const +void InsetExternal::write(ostream & os) const { - params_.write(buffer, os); + params_.write(buffer(), os); } -void InsetExternal::read(Buffer const & buffer, Lexer & lex) +void InsetExternal::read(Lexer & lex) { InsetExternalParams params; - if (params.read(buffer, lex)) - setParams(params, buffer); + if (params.read(buffer(), lex)) { + // exception handling is not needed as long as embedded files are in place. + params.filename.enable(buffer().embedded(), buffer(), false); + setParams(params); + } } -int InsetExternal::latex(Buffer const & buf, odocstream & os, - OutputParams const & runparams) const +int InsetExternal::latex(odocstream & os, OutputParams const & runparams) const { if (params_.draft) { // FIXME UNICODE os << "\\fbox{\\ttfamily{}" - << from_utf8(params_.filename.outputFilename(buf.filePath())) + << from_utf8(params_.filename.outputFilename(buffer().filePath())) << "}\n"; return 1; } @@ -711,35 +779,35 @@ int InsetExternal::latex(Buffer const & buf, odocstream & os, if (cit != et.formats.end()) { return external::writeExternal(params_, "PDFLaTeX", - buf, os, + buffer(), os, *(runparams.exportdata), external_in_tmpdir, dryrun); } } - return external::writeExternal(params_, "LaTeX", buf, os, + return external::writeExternal(params_, "LaTeX", buffer(), os, *(runparams.exportdata), external_in_tmpdir, dryrun); } -int InsetExternal::plaintext(Buffer const & buf, odocstream & os, +int InsetExternal::plaintext(odocstream & os, OutputParams const & runparams) const { os << '\n'; // output external material on a new line - external::writeExternal(params_, "Ascii", buf, os, + external::writeExternal(params_, "Ascii", buffer(), os, *(runparams.exportdata), false, runparams.dryrun || runparams.inComment); return PLAINTEXT_NEWLINE; } -int InsetExternal::docbook(Buffer const & buf, odocstream & os, +int InsetExternal::docbook(odocstream & os, OutputParams const & runparams) const { - return external::writeExternal(params_, "DocBook", buf, os, + return external::writeExternal(params_, "DocBook", buffer(), os, *(runparams.exportdata), false, runparams.dryrun || runparams.inComment); } @@ -793,112 +861,58 @@ void InsetExternal::validate(LaTeXFeatures & features) const } -// -// preview stuff -// - -namespace { - -bool preview_wanted(InsetExternalParams const & params) -{ - return params.display == external::PreviewDisplay && - support::isFileReadable(params.filename); -} - - -docstring const latex_string(InsetExternal const & inset, Buffer const & buffer) -{ - odocstringstream os; - // We don't need to set runparams.encoding since it is not used by - // latex(). - OutputParams runparams(0); - runparams.flavor = OutputParams::LATEX; - inset.latex(buffer, os, runparams); - return os.str(); -} - - -void add_preview_and_start_loading(RenderMonitoredPreview & renderer, - InsetExternal const & inset, - Buffer const & buffer) -{ - InsetExternalParams const & params = inset.params(); - - if (RenderPreview::status() != LyXRC::PREVIEW_OFF && - preview_wanted(params)) { - renderer.setAbsFile(params.filename); - docstring const snippet = latex_string(inset, buffer); - renderer.addPreview(snippet, buffer); - renderer.startLoading(buffer); - } -} - -} // namespace anon - - void InsetExternal::addPreview(graphics::PreviewLoader & ploader) const { RenderMonitoredPreview * const ptr = renderer_->asMonitoredPreview(); if (!ptr) return; - if (preview_wanted(params())) { + if (isPreviewWanted(params())) { ptr->setAbsFile(params_.filename); - docstring const snippet = latex_string(*this, ploader.buffer()); + docstring const snippet = latexString(*this); ptr->addPreview(snippet, ploader); } } -/// Mailer stuff - -string const InsetExternalMailer::name_("external"); - -InsetExternalMailer::InsetExternalMailer(InsetExternal & inset) - : inset_(inset) -{} - - -string const InsetExternalMailer::inset2string(Buffer const & buffer) const -{ - return params2string(inset_.params(), buffer); -} - - -void InsetExternalMailer::string2params(string const & in, - Buffer const & buffer, - InsetExternalParams & params) +void InsetExternal::string2params(string const & in, Buffer const & buffer, + InsetExternalParams & params) { params = InsetExternalParams(); if (in.empty()) return; istringstream data(in); - Lexer lex(0,0); + Lexer lex; lex.setStream(data); string name; lex >> name; - if (!lex || name != name_) - return print_mailer_error("InsetExternalMailer", in, 1, name_); + if (!lex || name != "external") { + LYXERR0("InsetExternal::string2params(" << in << ")\n" + "Expected arg 1 to be \"external\"\n"); + return; + } // This is part of the inset proper that is usually swallowed // by Text::readInset string id; lex >> id; - if (!lex || id != "External") - return print_mailer_error("InsetBoxMailer", in, 2, "External"); + if (!lex || id != "External") { + LYXERR0("InsetExternal::string2params(" << in << ")\n" + "Expected arg 2 to be \"External\"\n"); + return; + } params.read(buffer, lex); } -string const -InsetExternalMailer::params2string(InsetExternalParams const & params, - Buffer const & buffer) +string InsetExternal::params2string(InsetExternalParams const & params, + Buffer const & buffer) { ostringstream data; - data << name_ << ' '; + data << "external" << ' '; params.write(buffer, data); data << "\\end_inset\n"; return data.str();