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"
35 InsetExternal::InsetExternal()
38 tempname = TmpFileName();
41 InsetExternal::~InsetExternal() {
42 remove(tempname.c_str());
46 extern "C" void ExternalTemplateCB(FL_OBJECT * ob, long data)
48 InsetExternal::templateCB(ob, data);
52 extern "C" void ExternalBrowseCB(FL_OBJECT * ob, long data)
54 InsetExternal::browseCB(ob, data);
58 extern "C" void ExternalEditCB(FL_OBJECT * ob, long data)
60 InsetExternal::editCB(ob, data);
64 extern "C" void ExternalViewCB(FL_OBJECT * ob, long data)
66 InsetExternal::viewCB(ob, data);
70 extern "C" void ExternalUpdateCB(FL_OBJECT * ob, long data)
72 InsetExternal::updateCB(ob, data);
76 extern "C" void ExternalOKCB(FL_OBJECT * ob, long data)
78 InsetExternal::okCB(ob, data);
82 extern "C" void ExternalCancelCB(FL_OBJECT * ob, long data)
84 InsetExternal::cancelCB(ob, data);
88 void InsetExternal::templateCB(FL_OBJECT * ob, long)
90 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
91 InsetExternal * inset = holder->inset;
92 ExternalTemplate et = inset->getTemplate(inset->getCurrentTemplate());
93 // Update the help text
94 fl_clear_browser(inset->form_external->helptext);
95 fl_addto_browser(inset->form_external->helptext, et.helpText.c_str());
96 fl_set_browser_topline(inset->form_external->helptext, 0);
100 void InsetExternal::browseCB(FL_OBJECT * ob, long)
102 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
103 InsetExternal * inset = holder->inset;
105 static string current_path;
109 string p = inset->filename;
110 string buf = MakeAbsPath(holder->view->buffer()->fileName());
111 string buf2 = OnlyPath(buf);
113 buf = MakeAbsPath(p, buf2);
116 buf = OnlyPath(holder->view->buffer()->fileName().c_str());
119 fileDlg.SetButton(0, _("Document"), buf);
121 /// Determine the template file extension
122 ExternalTemplate et = inset->getTemplate(inset->getCurrentTemplate());
123 string regexp = et.fileRegExp;
124 if (regexp.empty()) {
130 // ProhibitInput(current_view);
132 p = fileDlg.Select(_("External inset file"),
136 p = fileDlg.Select(_("External inset file"), buf,
139 // AllowInput(current_view);
141 if (p.empty()) return;
143 buf = MakeRelPath(p, buf2);
144 current_path = OnlyPath(p);
147 if (contains(p, "#") || contains(p, "~") || contains(p, "$")
148 || contains(p, "%")) {
149 WriteAlert(_("Filename can't contain any "
150 "of these characters:"),
151 // xgettext:no-c-format
152 _("'#', '~', '$' or '%'."));
157 if (inset->form_external)
158 fl_set_input(inset->form_external->filename, buf.c_str());
163 void InsetExternal::editCB(FL_OBJECT * ob, long)
165 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
166 InsetExternal * inset = holder->inset;
167 inset->doApply(holder->view);
168 inset->doEdit(holder->view);
172 void InsetExternal::viewCB(FL_OBJECT * ob, long)
174 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
175 InsetExternal * inset = holder->inset;
176 inset->doApply(holder->view);
177 inset->doView(holder->view);
181 void InsetExternal::updateCB(FL_OBJECT * ob, long)
183 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
184 InsetExternal * inset = holder->inset;
185 inset->doApply(holder->view);
186 inset->doUpdate(holder->view);
190 void InsetExternal::okCB(FL_OBJECT * ob, long data)
192 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
193 InsetExternal * inset = holder->inset;
194 inset->doApply(holder->view);
199 void InsetExternal::doApply(BufferView * bufview)
202 if (templatename != getCurrentTemplate()) {
203 templatename = getCurrentTemplate();
206 if (filename != fl_get_input(form_external->filename)) {
207 filename = fl_get_input(form_external->filename);
210 if (parameters != fl_get_input(form_external->parameters)) {
211 parameters = fl_get_input(form_external->parameters);
216 // The text might have change, so we should update the button look
217 bufview->updateInset(this, true);
222 void InsetExternal::cancelCB(FL_OBJECT * ob, long)
224 Holder * holder = static_cast<Holder*>(ob->form->u_vdata);
226 InsetExternal * inset = holder->inset;
227 // BufferView * bv = holder->view;
229 if (inset->form_external) {
230 fl_hide_form(inset->form_external->form_external);
231 fl_free_form(inset->form_external->form_external);
232 inset->form_external = 0;
237 const char * InsetExternal::EditMessage() const
239 ExternalTemplate const & et = getTemplate(templatename);
240 return doSubstitution(0, et.guiName).c_str();
244 void InsetExternal::Edit(BufferView * bv,
245 int /*x*/, int /*y*/, unsigned int /*button*/)
247 static int ow = -1, oh;
249 if (bv->buffer()->isReadonly())
250 WarnReadonly(bv->buffer()->fileName());
252 if (!form_external) {
253 form_external = create_form_form_external();
255 // form_external->ok->u_vdata = &holder;
256 form_external->form_external->u_vdata = &holder;
257 fl_set_form_atclose(form_external->form_external,
258 CancelCloseBoxCB, 0);
261 fl_addto_choice(form_external->templatechoice, getTemplateString().c_str());
262 fl_set_input(form_external->filename, filename.c_str());
263 fl_set_input(form_external->parameters, parameters.c_str());
264 if (!templatename.empty()) {
265 fl_set_choice(form_external->templatechoice, getTemplateNumber(templatename));
267 // Update the help text
268 templateCB(form_external->templatechoice, 0);
270 ExternalTemplate const & et = getTemplate(templatename);
271 if (et.automaticProduction) {
272 fl_deactivate_object(form_external->update);
273 fl_set_object_lcol(form_external->update, FL_INACTIVE);
275 fl_activate_object(form_external->update);
276 fl_set_object_lcol(form_external->update, FL_BLACK);
279 if (form_external->form_external->visible) {
280 fl_raise_form(form_external->form_external);
282 fl_show_form(form_external->form_external,
283 FL_PLACE_MOUSE | FL_FREE_SIZE,
284 FL_FULLBORDER, _("Insert external inset"));
286 ow = form_external->form_external->w;
287 oh = form_external->form_external->h;
289 fl_set_form_minsize(form_external->form_external, ow, oh);
294 void InsetExternal::Write(Buffer const *, std::ostream & os) const
296 os << "External " << templatename << ",\"" << filename
297 << "\",\"" << parameters << "\"\n";
301 void InsetExternal::Read(Buffer const *, LyXLex & lex)
304 string format = lex.GetString();
305 int pos1 = format.find(",");
306 templatename = format.substr(0, pos1);
307 int pos2 = format.find("\",\"", pos1);
308 filename = format.substr(pos1 + 2, pos2 - (pos1 + 2));
309 parameters = format.substr(pos2 + 3, format.length() - (pos2 + 4));
311 lyxerr << templatename << " " << filename << " " << parameters << endl;
314 int InsetExternal::write(string const & format, Buffer const * buf,
315 std::ostream & os) const {
316 ExternalTemplate const & et = getTemplate(templatename);
317 ExternalTemplate::Formats::const_iterator cit =
318 et.formats.find(format);
319 if (et.automaticProduction) {
320 executeCommand(doSubstitution(buf, (*cit).second.updateCommand), buf);
323 os << doSubstitution(buf, (*cit).second.product);
328 int InsetExternal::Latex(Buffer const * buf, std::ostream & os, bool, bool) const
330 return write("LaTeX", buf, os);
334 int InsetExternal::Ascii(Buffer const * buf, std::ostream & os) const
336 return write("Ascii", buf, os);
340 int InsetExternal::Linuxdoc(Buffer const * buf, std::ostream & os) const
342 return write("LinuxDoc", buf, os);
346 int InsetExternal::DocBook(Buffer const * buf, std::ostream & os) const
348 return write("DocBook", buf, os);
352 void InsetExternal::Validate(LaTeXFeatures & features) const
354 ExternalTemplate const & et = getTemplate(templatename);
355 ExternalTemplate::Formats::const_iterator cit =
356 et.formats.find("LaTeX");
357 if (!(*cit).second.requirement.empty()) {
358 features.require((*cit).second.requirement);
360 if (!(*cit).second.preamble.empty()) {
361 features.externalPreambles += (*cit).second.preamble + "\n";
366 Inset * InsetExternal::Clone() const
368 InsetExternal * inset = new InsetExternal();
369 inset->templatename = templatename;
370 inset->filename = filename;
371 inset->parameters = parameters;
376 string InsetExternal::getScreenLabel() const
378 if (templatename.empty()) {
379 return _("External");
381 ExternalTemplate const & et = getTemplate(templatename);
382 return doSubstitution(0, et.guiName);
387 void InsetExternal::doUpdate(BufferView const * bv) const
389 ExternalTemplate const & et = getTemplate(getCurrentTemplate());
390 ExternalTemplate::Formats::const_iterator cit =
391 et.formats.find("LaTeX");
392 executeCommand(doSubstitution(bv->buffer(), (*cit).second.updateCommand), bv->buffer());
396 void InsetExternal::doView(BufferView const * bv) const
399 ExternalTemplate const & et = getTemplate(getCurrentTemplate());
400 executeCommand(doSubstitution(bv->buffer(), et.viewCommand), bv->buffer());
404 void InsetExternal::doEdit(BufferView const * bv) const
407 ExternalTemplate const & et = getTemplate(getCurrentTemplate());
408 executeCommand(doSubstitution(bv->buffer(),et.editCommand), bv->buffer());
412 void InsetExternal::executeCommand(string const & s, Buffer const * buffer) const
414 string buf = MakeAbsPath(buffer->fileName());
415 string path = OnlyPath(buf);
418 if (lyxerr.debugging()) {
419 lyxerr << "Executing '" << s << "' in '" << path << "'" << endl;
421 one.startscript(Systemcalls::Wait, s);
425 void InsetExternal::automaticUpdate(BufferView const * bv) const
427 ExternalTemplate const & et = getTemplate(templatename);
428 if (et.automaticProduction) {
434 string InsetExternal::doSubstitution(Buffer const * buffer, string const & s) const
437 string basename = ChangeExtension(filename, string());
438 result = subst(s, "$$FName", filename);
439 result = subst(result, "$$Basename", basename);
440 result = subst(result, "$$Parameters", parameters);
441 result = ReplaceEnvironmentPath(result);
442 result = subst(result, "$$Tempname", tempname);
443 result = subst(result, "$$Sysdir", system_lyxdir);
445 // Handle the $$Contents(filename) syntax
446 if (contains(result, "$$Contents(\"")) {
448 int pos = result.find("$$Contents(\"");
449 int end = result.find("\")", pos);
450 string file = result.substr(pos + 12, end - (pos + 12));
453 // Make sure we are in the directory of the buffer
454 string buf = MakeAbsPath(buffer->fileName());
455 string path = OnlyPath(buf);
457 contents = GetFileContents(file);
459 contents = GetFileContents(file);
461 result = subst(result, ("$$Contents(\"" + file + "\")").c_str(), contents);
468 string InsetExternal::getCurrentTemplate() const
470 return getTemplateName(fl_get_choice(form_external->templatechoice));
474 ExternalTemplate InsetExternal::getTemplate(string const & name) const
476 ExternalTemplateManager::Templates::const_iterator i =
477 ExternalTemplateManager::get().getTemplates().find(name);
478 // Make sure that the template exists in the map
479 if (i == ExternalTemplateManager::get().getTemplates().end()) {
480 lyxerr << "Unknown external material template!" << endl;
481 return ExternalTemplate();
487 int InsetExternal::getTemplateNumber(string const & name) const
490 ExternalTemplateManager::Templates::const_iterator i1, i2;
491 i1 = ExternalTemplateManager::get().getTemplates().begin();
492 i2 = ExternalTemplateManager::get().getTemplates().end();
493 for (; i1 != i2; ++i1) {
494 if ((*i1).second.lyxName == name)
498 // This should never happen
504 string InsetExternal::getTemplateName(int i) const
506 ExternalTemplateManager::Templates::const_iterator i1;
507 i1 = ExternalTemplateManager::get().getTemplates().begin();
508 for (int n = 1; n < i; ++n) {
511 return (*i1).second.lyxName;
515 string InsetExternal::getTemplateString() const
519 ExternalTemplateManager::Templates::const_iterator i1, i2;
520 i1 = ExternalTemplateManager::get().getTemplates().begin();
521 i2 = ExternalTemplateManager::get().getTemplates().end();
522 for (; i1 != i2; ++i1) {
528 result += (*i1).second.lyxName;