1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 1995 Matthias Ettrich
7 * Copyright 1995-2000 The LyX Team.
9 * ====================================================== */
14 #pragma implementation
17 #include FORMS_H_LOCATION
20 #include "insetexternal.h"
21 #include "ExternalTemplate.h"
22 #include "lyx_gui_misc.h" // CancelCloseBoxCB
23 #include "BufferView.h"
27 #include "LaTeXFeatures.h"
28 #include "support/filetools.h"
29 #include "support/lstrings.h"
30 #include "support/path.h"
31 #include "support/syscall.h"
36 InsetExternal::InsetExternal()
39 tempname = TmpFileName();
43 InsetExternal::~InsetExternal()
45 remove(tempname.c_str());
50 void ExternalTemplateCB(FL_OBJECT * ob, long data)
52 InsetExternal::templateCB(ob, data);
57 void ExternalBrowseCB(FL_OBJECT * ob, long data)
59 InsetExternal::browseCB(ob, data);
64 void ExternalEditCB(FL_OBJECT * ob, long data)
66 InsetExternal::editCB(ob, data);
71 void ExternalViewCB(FL_OBJECT * ob, long data)
73 InsetExternal::viewCB(ob, data);
78 void ExternalUpdateCB(FL_OBJECT * ob, long data)
80 InsetExternal::updateCB(ob, data);
85 void ExternalOKCB(FL_OBJECT * ob, long data)
87 InsetExternal::okCB(ob, data);
92 void ExternalCancelCB(FL_OBJECT * ob, long data)
94 InsetExternal::cancelCB(ob, data);
98 void InsetExternal::templateCB(FL_OBJECT * ob, long)
100 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
101 InsetExternal * inset = holder->inset;
102 ExternalTemplate et = inset->getTemplate(inset->getCurrentTemplate());
103 // Update the help text
104 fl_clear_browser(inset->form_external->helptext);
105 fl_addto_browser(inset->form_external->helptext, et.helpText.c_str());
106 fl_set_browser_topline(inset->form_external->helptext, 0);
110 void InsetExternal::browseCB(FL_OBJECT * ob, long)
112 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
113 InsetExternal * inset = holder->inset;
115 static string current_path;
119 string p = inset->filename;
120 string buf = MakeAbsPath(holder->view->buffer()->fileName());
121 string buf2 = OnlyPath(buf);
123 buf = MakeAbsPath(p, buf2);
126 buf = OnlyPath(holder->view->buffer()->fileName().c_str());
129 fileDlg.SetButton(0, _("Document"), buf);
131 /// Determine the template file extension
132 ExternalTemplate et = inset->getTemplate(inset->getCurrentTemplate());
133 string regexp = et.fileRegExp;
134 if (regexp.empty()) {
140 // ProhibitInput(current_view);
142 p = fileDlg.Select(_("External inset file"),
146 p = fileDlg.Select(_("External inset file"), buf,
149 // AllowInput(current_view);
151 if (p.empty()) return;
153 buf = MakeRelPath(p, buf2);
154 current_path = OnlyPath(p);
157 if (contains(p, "#") || contains(p, "~") || contains(p, "$")
158 || contains(p, "%")) {
159 WriteAlert(_("Filename can't contain any "
160 "of these characters:"),
161 // xgettext:no-c-format
162 _("'#', '~', '$' or '%'."));
167 if (inset->form_external)
168 fl_set_input(inset->form_external->filename, buf.c_str());
173 void InsetExternal::editCB(FL_OBJECT * ob, long)
175 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
176 InsetExternal * inset = holder->inset;
177 inset->doApply(holder->view);
178 inset->doEdit(holder->view);
182 void InsetExternal::viewCB(FL_OBJECT * ob, long)
184 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
185 InsetExternal * inset = holder->inset;
186 inset->doApply(holder->view);
187 inset->doView(holder->view);
191 void InsetExternal::updateCB(FL_OBJECT * ob, long)
193 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
194 InsetExternal * inset = holder->inset;
195 inset->doApply(holder->view);
196 inset->doUpdate(holder->view);
200 void InsetExternal::okCB(FL_OBJECT * ob, long data)
202 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
203 InsetExternal * inset = holder->inset;
204 inset->doApply(holder->view);
209 void InsetExternal::doApply(BufferView * bufview)
212 if (templatename != getCurrentTemplate()) {
213 templatename = getCurrentTemplate();
216 if (filename != fl_get_input(form_external->filename)) {
217 filename = fl_get_input(form_external->filename);
220 if (parameters != fl_get_input(form_external->parameters)) {
221 parameters = fl_get_input(form_external->parameters);
226 // The text might have change,
227 // so we should update the button look
228 bufview->updateInset(this, true);
233 void InsetExternal::cancelCB(FL_OBJECT * ob, long)
235 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
237 InsetExternal * inset = holder->inset;
238 // BufferView * bv = holder->view;
240 if (inset->form_external) {
241 fl_hide_form(inset->form_external->form_external);
242 fl_free_form(inset->form_external->form_external);
243 inset->form_external = 0;
248 char const * InsetExternal::EditMessage() const
250 ExternalTemplate const & et = getTemplate(templatename);
251 return doSubstitution(0, et.guiName).c_str();
255 void InsetExternal::Edit(BufferView * bv,
256 int /*x*/, int /*y*/, unsigned int /*button*/)
258 static int ow = -1, oh;
260 if (bv->buffer()->isReadonly())
261 WarnReadonly(bv->buffer()->fileName());
263 if (!form_external) {
264 form_external = create_form_form_external();
266 // form_external->ok->u_vdata = &holder;
267 form_external->form_external->u_vdata = &holder;
268 fl_set_form_atclose(form_external->form_external,
269 CancelCloseBoxCB, 0);
272 fl_addto_choice(form_external->templatechoice,
273 getTemplateString().c_str());
274 fl_set_input(form_external->filename, filename.c_str());
275 fl_set_input(form_external->parameters, parameters.c_str());
276 if (!templatename.empty()) {
277 fl_set_choice(form_external->templatechoice,
278 getTemplateNumber(templatename));
280 // Update the help text
281 templateCB(form_external->templatechoice, 0);
283 ExternalTemplate const & et = getTemplate(templatename);
284 if (et.automaticProduction) {
285 fl_deactivate_object(form_external->update);
286 fl_set_object_lcol(form_external->update, FL_INACTIVE);
288 fl_activate_object(form_external->update);
289 fl_set_object_lcol(form_external->update, FL_BLACK);
292 if (form_external->form_external->visible) {
293 fl_raise_form(form_external->form_external);
295 fl_show_form(form_external->form_external,
296 FL_PLACE_MOUSE | FL_FREE_SIZE,
297 FL_FULLBORDER, _("Insert external inset"));
299 ow = form_external->form_external->w;
300 oh = form_external->form_external->h;
302 fl_set_form_minsize(form_external->form_external, ow, oh);
307 void InsetExternal::Write(Buffer const *, std::ostream & os) const
309 os << "External " << templatename << ",\"" << filename
310 << "\",\"" << parameters << "\"\n";
314 void InsetExternal::Read(Buffer const *, LyXLex & lex)
317 string format = lex.GetString();
318 int pos1 = format.find(",");
319 templatename = format.substr(0, pos1);
320 int pos2 = format.find("\",\"", pos1);
321 filename = format.substr(pos1 + 2, pos2 - (pos1 + 2));
322 parameters = format.substr(pos2 + 3, format.length() - (pos2 + 4));
324 lyxerr << templatename << " " << filename << " " << parameters << endl;
328 int InsetExternal::write(string const & format,
329 Buffer const * buf, std::ostream & os) const
331 ExternalTemplate const & et = getTemplate(templatename);
332 ExternalTemplate::Formats::const_iterator cit =
333 et.formats.find(format);
334 if (cit == et.formats.end()) {
335 lyxerr << "External template format '" << format
336 << "' not specified in template " << templatename
341 if (et.automaticProduction) {
342 executeCommand(doSubstitution(buf,
343 (*cit).second.updateCommand),
347 os << doSubstitution(buf, (*cit).second.product);
352 int InsetExternal::Latex(Buffer const * buf,
353 std::ostream & os, bool, bool) const
355 return write("LaTeX", buf, os);
359 int InsetExternal::Ascii(Buffer const * buf, std::ostream & os) const
361 return write("Ascii", buf, os);
365 int InsetExternal::Linuxdoc(Buffer const * buf, std::ostream & os) const
367 return write("LinuxDoc", buf, os);
371 int InsetExternal::DocBook(Buffer const * buf, std::ostream & os) const
373 return write("DocBook", buf, os);
377 void InsetExternal::Validate(LaTeXFeatures & features) const
379 ExternalTemplate const & et = getTemplate(templatename);
380 ExternalTemplate::Formats::const_iterator cit =
381 et.formats.find("LaTeX");
382 if (cit == et.formats.end()) {
386 if (!(*cit).second.requirement.empty()) {
387 features.require((*cit).second.requirement);
389 if (!(*cit).second.preamble.empty()) {
390 features.externalPreambles += (*cit).second.preamble + "\n";
395 Inset * InsetExternal::Clone() const
397 InsetExternal * inset = new InsetExternal();
398 inset->templatename = templatename;
399 inset->filename = filename;
400 inset->parameters = parameters;
405 string InsetExternal::getScreenLabel() const
407 if (templatename.empty()) {
408 return _("External");
410 ExternalTemplate const & et = getTemplate(templatename);
411 return doSubstitution(0, et.guiName);
416 void InsetExternal::doUpdate(BufferView const * bv) const
418 ExternalTemplate const & et = getTemplate(getCurrentTemplate());
419 ExternalTemplate::Formats::const_iterator cit =
420 et.formats.find("LaTeX");
421 if (cit == et.formats.end())
424 executeCommand(doSubstitution(bv->buffer(),
425 (*cit).second.updateCommand),
430 void InsetExternal::doView(BufferView const * bv) const
433 ExternalTemplate const & et = getTemplate(getCurrentTemplate());
434 executeCommand(doSubstitution(bv->buffer(), et.viewCommand),
439 void InsetExternal::doEdit(BufferView const * bv) const
442 ExternalTemplate const & et = getTemplate(getCurrentTemplate());
443 executeCommand(doSubstitution(bv->buffer(), et.editCommand),
448 void InsetExternal::executeCommand(string const & s,
449 Buffer const * buffer) const
451 string buf = MakeAbsPath(buffer->fileName());
452 string path = OnlyPath(buf);
455 if (lyxerr.debugging()) {
456 lyxerr << "Executing '" << s << "' in '"
457 << path << "'" << endl;
459 one.startscript(Systemcalls::Wait, s);
463 void InsetExternal::automaticUpdate(BufferView const * bv) const
465 ExternalTemplate const & et = getTemplate(templatename);
466 if (et.automaticProduction) {
472 string InsetExternal::doSubstitution(Buffer const * buffer,
473 string const & s) const
476 string basename = ChangeExtension(filename, string());
477 result = subst(s, "$$FName", filename);
478 result = subst(result, "$$Basename", basename);
479 result = subst(result, "$$Parameters", parameters);
480 result = ReplaceEnvironmentPath(result);
481 result = subst(result, "$$Tempname", tempname);
482 result = subst(result, "$$Sysdir", system_lyxdir);
484 // Handle the $$Contents(filename) syntax
485 if (contains(result, "$$Contents(\"")) {
487 int pos = result.find("$$Contents(\"");
488 int end = result.find("\")", pos);
489 string file = result.substr(pos + 12, end - (pos + 12));
492 // Make sure we are in the directory of the buffer
493 string buf = MakeAbsPath(buffer->fileName());
494 string path = OnlyPath(buf);
496 contents = GetFileContents(file);
498 contents = GetFileContents(file);
500 result = subst(result,
501 ("$$Contents(\"" + file + "\")").c_str(),
509 string InsetExternal::getCurrentTemplate() const
511 return getTemplateName(fl_get_choice(form_external->templatechoice));
515 ExternalTemplate InsetExternal::getTemplate(string const & name) const
517 ExternalTemplateManager::Templates::const_iterator i =
518 ExternalTemplateManager::get().getTemplates().find(name);
519 // Make sure that the template exists in the map
520 if (i == ExternalTemplateManager::get().getTemplates().end()) {
521 lyxerr << "Unknown external material template: "
523 return ExternalTemplate();
529 int InsetExternal::getTemplateNumber(string const & name) const
532 ExternalTemplateManager::Templates::const_iterator i1, i2;
533 i1 = ExternalTemplateManager::get().getTemplates().begin();
534 i2 = ExternalTemplateManager::get().getTemplates().end();
535 for (; i1 != i2; ++i1) {
536 if ((*i1).second.lyxName == name)
540 // This should never happen
546 string InsetExternal::getTemplateName(int i) const
548 ExternalTemplateManager::Templates::const_iterator i1;
549 i1 = ExternalTemplateManager::get().getTemplates().begin();
550 for (int n = 1; n < i; ++n) {
553 return (*i1).second.lyxName;
557 string InsetExternal::getTemplateString() const
561 ExternalTemplateManager::Templates::const_iterator i1, i2;
562 i1 = ExternalTemplateManager::get().getTemplates().begin();
563 i2 = ExternalTemplateManager::get().getTemplates().end();
564 for (; i1 != i2; ++i1) {
570 result += (*i1).second.lyxName;