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, getTemplateString().c_str());
273 fl_set_input(form_external->filename, filename.c_str());
274 fl_set_input(form_external->parameters, parameters.c_str());
275 if (!templatename.empty()) {
276 fl_set_choice(form_external->templatechoice,
277 getTemplateNumber(templatename));
279 // Update the help text
280 templateCB(form_external->templatechoice, 0);
282 ExternalTemplate const & et = getTemplate(templatename);
283 if (et.automaticProduction) {
284 fl_deactivate_object(form_external->update);
285 fl_set_object_lcol(form_external->update, FL_INACTIVE);
287 fl_activate_object(form_external->update);
288 fl_set_object_lcol(form_external->update, FL_BLACK);
291 if (form_external->form_external->visible) {
292 fl_raise_form(form_external->form_external);
294 fl_show_form(form_external->form_external,
295 FL_PLACE_MOUSE | FL_FREE_SIZE,
296 FL_FULLBORDER, _("Insert external inset"));
298 ow = form_external->form_external->w;
299 oh = form_external->form_external->h;
301 fl_set_form_minsize(form_external->form_external, ow, oh);
306 void InsetExternal::Write(Buffer const *, std::ostream & os) const
308 os << "External " << templatename << ",\"" << filename
309 << "\",\"" << parameters << "\"\n";
313 void InsetExternal::Read(Buffer const *, LyXLex & lex)
316 string format = lex.GetString();
317 int pos1 = format.find(",");
318 templatename = format.substr(0, pos1);
319 int pos2 = format.find("\",\"", pos1);
320 filename = format.substr(pos1 + 2, pos2 - (pos1 + 2));
321 parameters = format.substr(pos2 + 3, format.length() - (pos2 + 4));
323 lyxerr << templatename << " " << filename << " " << parameters << endl;
327 int InsetExternal::write(string const & format,
328 Buffer const * buf, std::ostream & os) const
330 ExternalTemplate const & et = getTemplate(templatename);
331 ExternalTemplate::Formats::const_iterator cit =
332 et.formats.find(format);
333 if (cit == et.formats.end()) {
334 lyxerr << "External template format '" << format
335 << "' not specified in template " << templatename
340 if (et.automaticProduction) {
341 executeCommand(doSubstitution(buf,
342 (*cit).second.updateCommand),
346 os << doSubstitution(buf, (*cit).second.product);
351 int InsetExternal::Latex(Buffer const * buf,
352 std::ostream & os, bool, bool) const
354 return write("LaTeX", buf, os);
358 int InsetExternal::Ascii(Buffer const * buf, std::ostream & os) const
360 return write("Ascii", buf, os);
364 int InsetExternal::Linuxdoc(Buffer const * buf, std::ostream & os) const
366 return write("LinuxDoc", buf, os);
370 int InsetExternal::DocBook(Buffer const * buf, std::ostream & os) const
372 return write("DocBook", buf, os);
376 void InsetExternal::Validate(LaTeXFeatures & features) const
378 ExternalTemplate const & et = getTemplate(templatename);
379 ExternalTemplate::Formats::const_iterator cit =
380 et.formats.find("LaTeX");
381 if (cit == et.formats.end()) {
385 if (!(*cit).second.requirement.empty()) {
386 features.require((*cit).second.requirement);
388 if (!(*cit).second.preamble.empty()) {
389 features.externalPreambles += (*cit).second.preamble + "\n";
394 Inset * InsetExternal::Clone() const
396 InsetExternal * inset = new InsetExternal();
397 inset->templatename = templatename;
398 inset->filename = filename;
399 inset->parameters = parameters;
404 string InsetExternal::getScreenLabel() const
406 if (templatename.empty()) {
407 return _("External");
409 ExternalTemplate const & et = getTemplate(templatename);
410 return doSubstitution(0, et.guiName);
415 void InsetExternal::doUpdate(BufferView const * bv) const
417 ExternalTemplate const & et = getTemplate(getCurrentTemplate());
418 ExternalTemplate::Formats::const_iterator cit =
419 et.formats.find("LaTeX");
420 if (cit == et.formats.end())
423 executeCommand(doSubstitution(bv->buffer(),
424 (*cit).second.updateCommand),
429 void InsetExternal::doView(BufferView const * bv) const
432 ExternalTemplate const & et = getTemplate(getCurrentTemplate());
433 executeCommand(doSubstitution(bv->buffer(), et.viewCommand),
438 void InsetExternal::doEdit(BufferView const * bv) const
441 ExternalTemplate const & et = getTemplate(getCurrentTemplate());
442 executeCommand(doSubstitution(bv->buffer(), et.editCommand),
447 void InsetExternal::executeCommand(string const & s,
448 Buffer const * buffer) const
450 string buf = MakeAbsPath(buffer->fileName());
451 string path = OnlyPath(buf);
454 if (lyxerr.debugging()) {
455 lyxerr << "Executing '" << s << "' in '"
456 << path << "'" << endl;
458 one.startscript(Systemcalls::Wait, s);
462 void InsetExternal::automaticUpdate(BufferView const * bv) const
464 ExternalTemplate const & et = getTemplate(templatename);
465 if (et.automaticProduction) {
471 string InsetExternal::doSubstitution(Buffer const * buffer,
472 string const & s) const
475 string basename = ChangeExtension(filename, string());
476 result = subst(s, "$$FName", filename);
477 result = subst(result, "$$Basename", basename);
478 result = subst(result, "$$Parameters", parameters);
479 result = ReplaceEnvironmentPath(result);
480 result = subst(result, "$$Tempname", tempname);
481 result = subst(result, "$$Sysdir", system_lyxdir);
483 // Handle the $$Contents(filename) syntax
484 if (contains(result, "$$Contents(\"")) {
486 int pos = result.find("$$Contents(\"");
487 int end = result.find("\")", pos);
488 string file = result.substr(pos + 12, end - (pos + 12));
491 // Make sure we are in the directory of the buffer
492 string buf = MakeAbsPath(buffer->fileName());
493 string path = OnlyPath(buf);
495 contents = GetFileContents(file);
497 contents = GetFileContents(file);
499 result = subst(result,
500 ("$$Contents(\"" + file + "\")").c_str(),
508 string InsetExternal::getCurrentTemplate() const
510 return getTemplateName(fl_get_choice(form_external->templatechoice));
514 ExternalTemplate InsetExternal::getTemplate(string const & name) const
516 ExternalTemplateManager::Templates::const_iterator i =
517 ExternalTemplateManager::get().getTemplates().find(name);
518 // Make sure that the template exists in the map
519 if (i == ExternalTemplateManager::get().getTemplates().end()) {
520 lyxerr << "Unknown external material template: "
522 return ExternalTemplate();
528 int InsetExternal::getTemplateNumber(string const & name) const
531 ExternalTemplateManager::Templates::const_iterator i1, i2;
532 i1 = ExternalTemplateManager::get().getTemplates().begin();
533 i2 = ExternalTemplateManager::get().getTemplates().end();
534 for (; i1 != i2; ++i1) {
535 if ((*i1).second.lyxName == name)
539 // This should never happen
545 string InsetExternal::getTemplateName(int i) const
547 ExternalTemplateManager::Templates::const_iterator i1;
548 i1 = ExternalTemplateManager::get().getTemplates().begin();
549 for (int n = 1; n < i; ++n) {
552 return (*i1).second.lyxName;
556 string InsetExternal::getTemplateString() const
560 ExternalTemplateManager::Templates::const_iterator i1, i2;
561 i1 = ExternalTemplateManager::get().getTemplates().begin();
562 i2 = ExternalTemplateManager::get().getTemplates().end();
563 for (; i1 != i2; ++i1) {
569 result += (*i1).second.lyxName;