X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsetexternal.C;h=fd5fe30017f1c40deb2e1380df6d4912eb95d9e1;hb=26f1a5bfcae4b7fd7b946a1884c396d842b24925;hp=1d0590da69effe6453f1a481810c55821b6b680a;hpb=e7401bd8f2310213b4b765c01676459f37adb530;p=lyx.git diff --git a/src/insets/insetexternal.C b/src/insets/insetexternal.C index 1d0590da69..fd5fe30017 100644 --- a/src/insets/insetexternal.C +++ b/src/insets/insetexternal.C @@ -1,484 +1,284 @@ -/* This file is part of - * ====================================================== - * - * LyX, The Document Processor - * - * Copyright 1995 Matthias Ettrich - * Copyright 1995-2000 The LyX Team. +/** + * \file insetexternal.C + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. * - * ====================================================== */ + * \author Asger Alstrup Nielsen + * + * Full author contact details are available in file CREDITS + */ #include -#ifdef __GNUG__ -#pragma implementation -#endif - -#include FORMS_H_LOCATION -#include #include "insetexternal.h" #include "ExternalTemplate.h" -#include "lyx_gui_misc.h" // CancelCloseBoxCB #include "BufferView.h" #include "buffer.h" -#include "filedlg.h" +#include "funcrequest.h" #include "lyx_main.h" #include "LaTeXFeatures.h" +#include "gettext.h" +#include "debug.h" +#include "lyxlex.h" + +#include "frontends/LyXView.h" +#include "frontends/Dialogs.h" + #include "support/filetools.h" #include "support/lstrings.h" #include "support/path.h" -#include "support/syscall.h" - -using std::endl; - - -InsetExternal::InsetExternal() - : form_external(0) -{ - tempname = TmpFileName(); -} - +#include "support/systemcall.h" +#include "support/FileInfo.h" -InsetExternal::~InsetExternal() -{ - lyx::unlink(tempname); -} - - -extern "C" -void ExternalTemplateCB(FL_OBJECT * ob, long data) -{ - InsetExternal::templateCB(ob, data); -} - - -extern "C" -void ExternalBrowseCB(FL_OBJECT * ob, long data) -{ - InsetExternal::browseCB(ob, data); -} - - -extern "C" -void ExternalEditCB(FL_OBJECT * ob, long data) -{ - InsetExternal::editCB(ob, data); -} +#include +#include -extern "C" -void ExternalViewCB(FL_OBJECT * ob, long data) -{ - InsetExternal::viewCB(ob, data); -} +using std::ostream; +using std::endl; -extern "C" -void ExternalUpdateCB(FL_OBJECT * ob, long data) +InsetExternal::InsetExternal() + : view_(0) { - InsetExternal::updateCB(ob, data); + tempname_ = lyx::tempName(string(), "lyxext"); + //ExternalTemplateManager::Templates::const_iterator i1; + params_.templ = ExternalTemplateManager::get().getTemplates().begin()->second; } -extern "C" -void ExternalOKCB(FL_OBJECT * ob, long data) +InsetExternal::~InsetExternal() { - InsetExternal::okCB(ob, data); + lyx::unlink(tempname_); + InsetExternalMailer mailer(*this); + mailer.hideDialog(); } -extern "C" -void ExternalCancelCB(FL_OBJECT * ob, long data) +InsetExternal::Params const & InsetExternal::params() const { - InsetExternal::cancelCB(ob, data); + return params_; } -void InsetExternal::templateCB(FL_OBJECT * ob, long) +dispatch_result InsetExternal::localDispatch(FuncRequest const & cmd) { - Holder * holder = static_cast(ob->form->u_vdata); - InsetExternal * inset = holder->inset; - ExternalTemplate et = inset->getTemplate(inset->getCurrentTemplate()); - // Update the help text - fl_clear_browser(inset->form_external->helptext); - fl_addto_browser(inset->form_external->helptext, et.helpText.c_str()); - fl_set_browser_topline(inset->form_external->helptext, 0); -} + dispatch_result result = UNDISPATCHED; + switch (cmd.action) { + case LFUN_INSET_MODIFY: { + InsetExternal::Params p; + InsetExternalMailer::string2params(cmd.argument, p); + if (p.filename.empty()) + break; -void InsetExternal::browseCB(FL_OBJECT * ob, long) -{ - Holder * holder = static_cast(ob->form->u_vdata); - InsetExternal * inset = holder->inset; - - static string current_path; - static int once = 0; - LyXFileDlg fileDlg; - - string p = inset->filename; - string buf = MakeAbsPath(holder->view->buffer()->fileName()); - string buf2 = OnlyPath(buf); - if (!p.empty()) { - buf = MakeAbsPath(p, buf2); - buf = OnlyPath(buf); - } else { - buf = OnlyPath(holder->view->buffer()->fileName()); - } - - fileDlg.SetButton(0, _("Document"), buf); - - /// Determine the template file extension - ExternalTemplate et = inset->getTemplate(inset->getCurrentTemplate()); - string regexp = et.fileRegExp; - if (regexp.empty()) { - regexp = "*"; + setFromParams(p); + cmd.view()->updateInset(this); + result = DISPATCHED; } + break; - bool error = false; - do { - if (once) { - p = fileDlg.Select(_("External inset file"), - current_path, - regexp, string()); - } else { - p = fileDlg.Select(_("External inset file"), buf, - regexp, string()); - } - - if (p.empty()) return; - - buf = MakeRelPath(p, buf2); - current_path = OnlyPath(p); - once = 1; - - if (contains(p, "#") || contains(p, "~") || contains(p, "$") - || contains(p, "%")) { - WriteAlert(_("Filename can't contain any " - "of these characters:"), - // xgettext:no-c-format - _("'#', '~', '$' or '%'.")); - error = true; - } - } while (error); - - if (inset->form_external) - fl_set_input(inset->form_external->filename, buf.c_str()); - -} + case LFUN_INSET_DIALOG_UPDATE: { + InsetExternalMailer mailer(*this); + mailer.updateDialog(cmd.view()); + } + break; + case LFUN_MOUSE_RELEASE: + edit(cmd.view(), cmd.x, cmd.y, cmd.button()); + break; -void InsetExternal::editCB(FL_OBJECT * ob, long) -{ - Holder * holder = static_cast(ob->form->u_vdata); - InsetExternal * inset = holder->inset; - inset->doApply(holder->view); - inset->doEdit(holder->view); -} - + default: + break; + } -void InsetExternal::viewCB(FL_OBJECT * ob, long) -{ - Holder * holder = static_cast(ob->form->u_vdata); - InsetExternal * inset = holder->inset; - inset->doApply(holder->view); - inset->doView(holder->view); + return result; } -void InsetExternal::updateCB(FL_OBJECT * ob, long) +void InsetExternal::setFromParams(Params const & p) { - Holder * holder = static_cast(ob->form->u_vdata); - InsetExternal * inset = holder->inset; - inset->doApply(holder->view); - inset->doUpdate(holder->view); + params_.filename = p.filename; + params_.parameters = p.parameters; + params_.templ = p.templ; } -void InsetExternal::okCB(FL_OBJECT * ob, long data) +string const InsetExternal::editMessage() const { - Holder * holder = static_cast(ob->form->u_vdata); - InsetExternal * inset = holder->inset; - inset->doApply(holder->view); - cancelCB(ob,data); + return doSubstitution(0, params_.templ.guiName); } -void InsetExternal::doApply(BufferView * bufview) +void InsetExternal::edit(BufferView * bv, int, int, mouse_button::state) { - bool update = false; - if (templatename != getCurrentTemplate()) { - templatename = getCurrentTemplate(); - update = true; - } - if (filename != fl_get_input(form_external->filename)) { - filename = fl_get_input(form_external->filename); - update = true; - } - if (parameters != fl_get_input(form_external->parameters)) { - parameters = fl_get_input(form_external->parameters); - update = true; - } - - if (update) { - // The text might have change, - // so we should update the button look - bufview->updateInset(this, true); - } + InsetExternalMailer mailer(*this); + mailer.showDialog(bv); } -void InsetExternal::cancelCB(FL_OBJECT * ob, long) +void InsetExternal::edit(BufferView * bv, bool) { - Holder * holder = static_cast(ob->form->u_vdata); - - InsetExternal * inset = holder->inset; - // BufferView * bv = holder->view; - - if (inset->form_external) { - fl_hide_form(inset->form_external->form_external); - fl_free_form(inset->form_external->form_external); - inset->form_external = 0; - } + edit(bv, 0, 0, mouse_button::none); } -string const InsetExternal::EditMessage() const +void InsetExternal::write(Buffer const *, ostream & os) const { - ExternalTemplate const & et = getTemplate(templatename); - return doSubstitution(0, et.guiName); + os << "External " << params_.templ.lyxName << ",\"" + << params_.filename << "\",\"" << params_.parameters << "\"\n"; } -void InsetExternal::Edit(BufferView * bv, - int /*x*/, int /*y*/, unsigned int /*button*/) +void InsetExternal::read(Buffer const *, LyXLex & lex) { - static int ow = -1, oh; - - if (bv->buffer()->isReadonly()) - WarnReadonly(bv->buffer()->fileName()); - - if (!form_external) { - form_external = create_form_form_external(); - holder.inset = this; - // form_external->ok->u_vdata = &holder; - form_external->form_external->u_vdata = &holder; - fl_set_form_atclose(form_external->form_external, - CancelCloseBoxCB, 0); - } - holder.view = bv; - fl_addto_choice(form_external->templatechoice, - getTemplateString().c_str()); - fl_set_input(form_external->filename, filename.c_str()); - fl_set_input(form_external->parameters, parameters.c_str()); - if (!templatename.empty()) { - fl_set_choice(form_external->templatechoice, - getTemplateNumber(templatename)); - } - // Update the help text - templateCB(form_external->templatechoice, 0); + string format; + string token; - ExternalTemplate const & et = getTemplate(templatename); - if (et.automaticProduction) { - fl_deactivate_object(form_external->update); - fl_set_object_lcol(form_external->update, FL_INACTIVE); + // Read inset data from lex and store in format + if (lex.eatLine()) { + format = lex.getString(); } else { - fl_activate_object(form_external->update); - fl_set_object_lcol(form_external->update, FL_BLACK); + lex.printError("InsetExternal: Parse error: `$$Token'"); } - if (form_external->form_external->visible) { - fl_raise_form(form_external->form_external); - } else { - fl_show_form(form_external->form_external, - FL_PLACE_MOUSE | FL_FREE_SIZE, - FL_FULLBORDER, _("Insert external inset")); - if (ow < 0) { - ow = form_external->form_external->w; - oh = form_external->form_external->h; - } - fl_set_form_minsize(form_external->form_external, ow, oh); + while (lex.isOK()) { + lex.nextToken(); + token = lex.getString(); + if (token == "\\end_inset") + break; + } + if (token != "\\end_inset") { + lex.printError("Missing \\end_inset at this point. " + "Read: `$$Token'"); } -} - - -void InsetExternal::Write(Buffer const *, std::ostream & os) const -{ - os << "External " << templatename << ",\"" << filename - << "\",\"" << parameters << "\"\n"; -} - -void InsetExternal::Read(Buffer const *, LyXLex & lex) -{ - lex.EatLine(); - string const format = lex.GetString(); - string::size_type const pos1 = format.find(","); - templatename = format.substr(0, pos1); + // Parse string format... + string::size_type const pos1 = format.find(','); + params_.templ = ExternalTemplateManager::get().getTemplateByName(format.substr(0, pos1)); string::size_type const pos2 = format.find("\",\"", pos1); - filename = format.substr(pos1 + 2, pos2 - (pos1 + 2)); - parameters = format.substr(pos2 + 3, format.length() - (pos2 + 4)); + params_.filename = format.substr(pos1 + 2, pos2 - (pos1 + 2)); + params_.parameters = format.substr(pos2 + 3, format.length() - (pos2 + 4)); - lyxerr << templatename << " " << filename << " " << parameters << endl; + lyxerr[Debug::INFO] << "InsetExternal::Read: " << params_.templ.lyxName + << ' ' << params_.filename + << ' ' << params_.parameters << endl; } int InsetExternal::write(string const & format, - Buffer const * buf, std::ostream & os) const + Buffer const * buf, ostream & os) const { - ExternalTemplate const & et = getTemplate(templatename); + ExternalTemplate const & et = params_.templ; ExternalTemplate::Formats::const_iterator cit = et.formats.find(format); if (cit == et.formats.end()) { lyxerr << "External template format '" << format - << "' not specified in template " << templatename - << endl; + << "' not specified in template " + << params_.templ.lyxName << endl; return 0; } - - if (et.automaticProduction) { - executeCommand(doSubstitution(buf, - (*cit).second.updateCommand), - buf); - } - - os << doSubstitution(buf, (*cit).second.product); - return 0; // CHECK + + updateExternal(format, buf); + os << doSubstitution(buf, cit->second.product); + return 0; // CHECK (FIXME check what ? - jbl) } -int InsetExternal::Latex(Buffer const * buf, - std::ostream & os, bool, bool) const +int InsetExternal::latex(Buffer const * buf, + ostream & os, bool, bool) const { return write("LaTeX", buf, os); } -int InsetExternal::Ascii(Buffer const * buf, std::ostream & os, int) const +int InsetExternal::ascii(Buffer const * buf, ostream & os, int) const { return write("Ascii", buf, os); } -int InsetExternal::Linuxdoc(Buffer const * buf, std::ostream & os) const +int InsetExternal::linuxdoc(Buffer const * buf, ostream & os) const { return write("LinuxDoc", buf, os); } -int InsetExternal::DocBook(Buffer const * buf, std::ostream & os) const +int InsetExternal::docbook(Buffer const * buf, ostream & os, bool) const { return write("DocBook", buf, os); } -void InsetExternal::Validate(LaTeXFeatures & features) const +void InsetExternal::validate(LaTeXFeatures & features) const { - ExternalTemplate const & et = getTemplate(templatename); + ExternalTemplate const & et = params_.templ; ExternalTemplate::Formats::const_iterator cit = et.formats.find("LaTeX"); - if (cit == et.formats.end()) { + + if (cit == et.formats.end()) return; + + if (!cit->second.requirement.empty()) { + features.require(cit->second.requirement); } - - if (!(*cit).second.requirement.empty()) { - features.require((*cit).second.requirement); - } - if (!(*cit).second.preamble.empty()) { - features.externalPreambles += (*cit).second.preamble + "\n"; + if (!cit->second.preamble.empty()) { + features.addExternalPreamble(cit->second.preamble + "\n"); } } -Inset * InsetExternal::Clone(Buffer const &) const +Inset * InsetExternal::clone(Buffer const &, bool same_id) const { - InsetExternal * inset = new InsetExternal(); - inset->templatename = templatename; - inset->filename = filename; - inset->parameters = parameters; + InsetExternal * inset = new InsetExternal; + inset->params_ = params_; + inset->view_ = view_; + if (same_id) + inset->id_ = id_; return inset; } -string const InsetExternal::getScreenLabel() const +string const InsetExternal::getScreenLabel(Buffer const *) const { - if (templatename.empty()) { + ExternalTemplate const & et = params_.templ; + if (et.guiName.empty()) return _("External"); - } else { - ExternalTemplate const & et = getTemplate(templatename); + else return doSubstitution(0, et.guiName); - } -} - - -void InsetExternal::doUpdate(BufferView const * bv) const -{ - ExternalTemplate const & et = getTemplate(getCurrentTemplate()); - ExternalTemplate::Formats::const_iterator cit = - et.formats.find("LaTeX"); - if (cit == et.formats.end()) - return; - - executeCommand(doSubstitution(bv->buffer(), - (*cit).second.updateCommand), - bv->buffer()); -} - - -void InsetExternal::doView(BufferView const * bv) const -{ - automaticUpdate(bv); - ExternalTemplate const & et = getTemplate(getCurrentTemplate()); - executeCommand(doSubstitution(bv->buffer(), et.viewCommand), - bv->buffer()); -} - - -void InsetExternal::doEdit(BufferView const * bv) const -{ - automaticUpdate(bv); - ExternalTemplate const & et = getTemplate(getCurrentTemplate()); - executeCommand(doSubstitution(bv->buffer(), et.editCommand), - bv->buffer()); } void InsetExternal::executeCommand(string const & s, Buffer const * buffer) const { - string buf = MakeAbsPath(buffer->fileName()); - string path = OnlyPath(buf); - Path p(path); - Systemcalls one; + Path p(buffer->filePath()); + Systemcall one; if (lyxerr.debugging()) { lyxerr << "Executing '" << s << "' in '" - << path << "'" << endl; - } - one.startscript(Systemcalls::Wait, s); -} - - -void InsetExternal::automaticUpdate(BufferView const * bv) const -{ - ExternalTemplate const & et = getTemplate(templatename); - if (et.automaticProduction) { - doUpdate(bv); + << buffer->filePath() << '\'' << endl; } + one.startscript(Systemcall::Wait, s); } string const InsetExternal::doSubstitution(Buffer const * buffer, - string const & s) const + string const & s) const { string result; - string const basename = ChangeExtension(filename, string()); - result = subst(s, "$$FName", filename); + string const basename = ChangeExtension(params_.filename, string()); + string filepath; + if (buffer && !buffer->tmppath.empty() && !buffer->niceFile) { + filepath = buffer->filePath(); + } + result = subst(s, "$$FName", params_.filename); result = subst(result, "$$Basename", basename); - result = subst(result, "$$Parameters", parameters); - result = ReplaceEnvironmentPath(result); - result = subst(result, "$$Tempname", tempname); + result = subst(result, "$$Parameters", params_.parameters); + result = subst(result, "$$FPath", filepath); + result = subst(result, "$$Tempname", tempname_); result = subst(result, "$$Sysdir", system_lyxdir); - + // Handle the $$Contents(filename) syntax if (contains(result, "$$Contents(\"")) { @@ -488,9 +288,7 @@ string const InsetExternal::doSubstitution(Buffer const * buffer, string contents; if (buffer) { // Make sure we are in the directory of the buffer - string const buf = MakeAbsPath(buffer->fileName()); - string const path = OnlyPath(buf); - Path p(path); + Path p(buffer->filePath()); contents = GetFileContents(file); } else { contents = GetFileContents(file); @@ -504,68 +302,122 @@ string const InsetExternal::doSubstitution(Buffer const * buffer, } -string const InsetExternal::getCurrentTemplate() const +void InsetExternal::updateExternal() const { - return getTemplateName(fl_get_choice(form_external->templatechoice)); + updateExternal("LaTeX", view_->buffer()); } - -ExternalTemplate const InsetExternal::getTemplate(string const & name) const +void InsetExternal::updateExternal(string const & format, + Buffer const * buf) const { - ExternalTemplateManager::Templates::iterator i = - ExternalTemplateManager::get().getTemplates().find(name); - // Make sure that the template exists in the map - if (i == ExternalTemplateManager::get().getTemplates().end()) { - lyxerr << "Unknown external material template: " - << name << endl; - return ExternalTemplate(); + ExternalTemplate const & et = params_.templ; + ExternalTemplate::Formats::const_iterator cit = + et.formats.find(format); + + if (cit == et.formats.end() || + cit->second.updateCommand.empty() || + !et.automaticProduction) + return; + + if (!cit->second.updateResult.empty()) { + string const resultfile = doSubstitution(buf, + cit->second.updateResult); + FileInfo fi(params_.filename); + FileInfo fi2(resultfile); + if (fi2.exist() && fi.exist() && + difftime(fi2.getModificationTime(), + fi.getModificationTime()) >= 0) { + lyxerr[Debug::FILES] << resultfile + << " is up to date" << endl; + return; + } } - return (*i).second; + + executeCommand(doSubstitution(buf, cit->second.updateCommand), buf); } -int InsetExternal::getTemplateNumber(string const & name) const +void InsetExternal::viewExternal() const { - int i = 1; - ExternalTemplateManager::Templates::const_iterator i1, i2; - i1 = ExternalTemplateManager::get().getTemplates().begin(); - i2 = ExternalTemplateManager::get().getTemplates().end(); - for (; i1 != i2; ++i1) { - if ((*i1).second.lyxName == name) - return i; - ++i; - } - // This should never happen - Assert(false); - return 0; + ExternalTemplate const & et = params_.templ; + if (et.viewCommand.empty()) + return; + + updateExternal(); + executeCommand(doSubstitution(view_->buffer(), + et.viewCommand), + view_->buffer()); } -string const InsetExternal::getTemplateName(int i) const +void InsetExternal::editExternal() const { - ExternalTemplateManager::Templates::const_iterator i1; - i1 = ExternalTemplateManager::get().getTemplates().begin(); - for (int n = 1; n < i; ++n) { - ++i1; - } - return (*i1).second.lyxName; + ExternalTemplate const & et = params_.templ; + if (et.editCommand.empty()) + return; + + updateExternal(); + executeCommand(doSubstitution(view_->buffer(), + et.editCommand), + view_->buffer()); } -string const InsetExternal::getTemplateString() const +string const InsetExternalMailer::name_("external"); + +InsetExternalMailer::InsetExternalMailer(InsetExternal & inset) + : inset_(inset) +{} + + +string const InsetExternalMailer::inset2string() const { - string result; - bool first = true; - ExternalTemplateManager::Templates::const_iterator i1, i2; - i1 = ExternalTemplateManager::get().getTemplates().begin(); - i2 = ExternalTemplateManager::get().getTemplates().end(); - for (; i1 != i2; ++i1) { - if (!first) { - result += "|"; - } else { - first = false; - } - result += (*i1).second.lyxName; + return params2string(inset_.params()); +} + + +void InsetExternalMailer::string2params(string const & in, + InsetExternal::Params & params) +{ + params = InsetExternal::Params(); + + istringstream data(in); + LyXLex lex(0,0); + lex.setStream(data); + + if (lex.isOK()) { + lex.next(); + string const token = lex.getString(); + if (token != name_) + return; } - return result; + + // This is part of the inset proper that is usually swallowed + // by Buffer::readInset + if (lex.isOK()) { + lex.next(); + string const token = lex.getString(); + if (token != "External") + return; + } + + if (lex.isOK()) { + InsetExternal inset; + inset.read(0, lex); + params = inset.params(); + } +} + + +string const +InsetExternalMailer::params2string(InsetExternal::Params const & params) +{ + InsetExternal inset; + inset.setFromParams(params); + ostringstream data; + data << name_ << ' '; + inset.write(0, data); + data << "\\end_inset\n"; + + return data.str(); }