]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormExternal.C
6c581b4db67671cd974c44b077a7d43acd10c9f6
[lyx.git] / src / frontends / xforms / FormExternal.C
1 /**
2  * \file FormExternal.C
3  * Copyright 2001 the LyX Team
4  * Read the file COPYING
5  *
6  * \author unknown
7  * \author John Levon
8  */
9
10 #include <config.h>
11 #include <utility>
12
13 #include FORMS_H_LOCATION
14
15 #ifdef __GNUG__
16 #pragma implementation
17 #endif
18
19 #include "debug.h"
20 #include "gettext.h"
21 #include "support/LAssert.h"
22 #include "lyx_gui_misc.h"
23 #include "Dialogs.h"
24 #include "LyXView.h"
25 #include "buffer.h"
26 #include "FormExternal.h"
27 #include "form_external.h"
28 #include "frontends/FileDialog.h"
29 #include "LString.h"
30 #include "support/filetools.h"
31
32 using std::pair;
33 using std::make_pair;
34 using std::endl;
35
36 FormExternal::FormExternal(LyXView * lv, Dialogs * d)
37         : FormBaseBD(lv, d, _("Edit external file")),
38         inset_(0), ih_(0)
39 {
40         d->showExternal.connect(slot(this, &FormExternal::showInset));
41 }
42
43
44 extern "C" void ExternalTemplateCB(FL_OBJECT * ob, long data)
45 {
46         FormExternal::templateCB(ob, data);
47 }
48
49
50 extern "C" void ExternalBrowseCB(FL_OBJECT * ob, long data)
51 {
52         FormExternal::browseCB(ob, data);
53 }
54
55
56 extern "C" void ExternalEditCB(FL_OBJECT * ob, long data)
57 {
58         FormExternal::editCB(ob, data);
59 }
60
61
62 extern "C" void ExternalViewCB(FL_OBJECT * ob, long data)
63 {
64         FormExternal::viewCB(ob, data);
65 }
66
67
68 extern "C" void ExternalUpdateCB(FL_OBJECT * ob, long data)
69 {
70         FormExternal::updateCB(ob, data);
71 }
72
73
74 FL_FORM * FormExternal::form() const
75 {
76         if (dialog_.get())
77                 return dialog_->form;
78         return 0;
79 }
80
81
82 void FormExternal::connect()
83 {
84         u_ = d_->updateBufferDependent.
85                  connect(slot(this, &FormExternal::updateSlot));
86         h_ = d_->hideBufferDependent.
87                  connect(slot(this, &FormExternal::hide));
88         FormBaseDeprecated::connect();
89 }
90
91
92 void FormExternal::disconnect()
93 {
94         inset_ = 0;
95         ih_.disconnect();
96         FormBaseBD::disconnect();
97 }
98
99
100 void FormExternal::updateSlot(bool switched)
101 {
102         if (switched)
103                 hide();
104         else
105                 update();
106 }
107
108
109 void FormExternal::showInset(InsetExternal * inset)
110 {
111         Assert(inset);
112
113         // If connected to another inset, disconnect from it.
114         if (inset_)
115                 ih_.disconnect();
116
117         inset_ = inset;
118         params_ = inset_->params();
119
120         ih_ = inset->hideDialog.connect(slot(this, &FormExternal::hide));
121         show();
122 }
123
124
125 void FormExternal::build()
126 {
127         dialog_.reset(build_external());
128
129         fl_addto_choice(dialog_->choice_template,
130                         getTemplatesComboString().c_str());
131
132         // Workaround dumb xforms sizing bug
133         minw_ = form()->w;
134         minh_ = form()->h;
135
136         bc_.setOK(dialog_->button_ok);
137         bc_.setCancel(dialog_->button_cancel);
138         bc_.refresh();
139
140         bc_.addReadOnly(dialog_->input_filename);
141         bc_.addReadOnly(dialog_->button_filenamebrowse);
142         bc_.addReadOnly(dialog_->input_parameters);
143 }
144
145
146 string const FormExternal::getTemplatesComboString() const
147 {
148         string result;
149         bool first = true;
150         ExternalTemplateManager::Templates::const_iterator i1, i2;
151         i1 = ExternalTemplateManager::get().getTemplates().begin();
152         i2 = ExternalTemplateManager::get().getTemplates().end();
153         for (; i1 != i2; ++i1) {
154                 if (!first)
155                         result += "|";
156                 else
157                         first = false;
158
159                 result += (*i1).second.lyxName;
160         }
161         return result;
162 }
163
164
165 int FormExternal::getTemplateComboNumber(string const & name) const
166 {
167         int i = 1;
168         ExternalTemplateManager::Templates::const_iterator i1, i2;
169         i1 = ExternalTemplateManager::get().getTemplates().begin();
170         i2 = ExternalTemplateManager::get().getTemplates().end();
171         for (; i1 != i2; ++i1) {
172                 if (i1->second.lyxName == name)
173                         return i;
174                 ++i;
175         }
176         // we can get here if a LyX document has a template not installed
177         // on this machine.
178         return 0;
179 }
180
181
182 ExternalTemplate FormExternal::getTemplate(int i) const
183 {
184         ExternalTemplateManager::Templates::const_iterator i1;
185         i1 = ExternalTemplateManager::get().getTemplates().begin();
186         for (int n = 1; n < i; ++n)
187                 ++i1;
188
189         return (*i1).second;
190 }
191
192
193 void FormExternal::update()
194 {
195         fl_set_input(dialog_->input_filename, params_.filename.c_str());
196         fl_set_input(dialog_->input_parameters, params_.parameters.c_str());
197
198         fl_set_choice(dialog_->choice_template, getTemplateComboNumber(params_.templ.lyxName));
199
200         updateComboChange();
201
202         bc_.valid();
203 }
204
205
206 void FormExternal::updateComboChange()
207 {
208         // Update the help text
209         fl_clear_browser(dialog_->browser_helptext);
210         fl_addto_browser(dialog_->browser_helptext, params_.templ.helpText.c_str());
211         fl_set_browser_topline(dialog_->browser_helptext, 0);
212
213         if (params_.templ.automaticProduction) {
214                 fl_deactivate_object(dialog_->button_update);
215                 fl_set_object_lcol(dialog_->button_update, FL_INACTIVE);
216         } else {
217                 fl_activate_object(dialog_->button_update);
218                 fl_set_object_lcol(dialog_->button_update, FL_BLACK);
219         }
220 }
221
222
223 bool FormExternal::input(FL_OBJECT *, long)
224 {
225         // FIXME: anything to do here ?
226         return true;
227 }
228
229
230 void FormExternal::apply()
231 {
232         Assert(inset_);
233
234         if (lv_->buffer()->isReadonly())
235                 return;
236
237         params_.filename = fl_get_input(dialog_->input_filename);
238         params_.parameters = fl_get_input(dialog_->input_parameters);
239         params_.templ = getTemplate(fl_get_choice(dialog_->choice_template));
240
241         inset_->setFromParams(params_);
242         lv_->view()->updateInset(inset_, true);
243 }
244
245
246 void FormExternal::templateCB(FL_OBJECT * ob, long)
247 {
248         FormExternal * form = static_cast<FormExternal*>(ob->form->u_vdata);
249
250         // set to the chosen template
251         form->params_.templ = form->getTemplate(fl_get_choice(form->dialog_->choice_template));
252
253         form->updateComboChange();
254 }
255
256
257 void FormExternal::browseCB(FL_OBJECT * ob, long)
258 {
259         FormExternal * form = static_cast<FormExternal*>(ob->form->u_vdata);
260
261         static string current_path;
262         static int once = 0;
263         
264         string p = fl_get_input(form->dialog_->input_filename);
265         string buf = MakeAbsPath(form->lv_->buffer()->fileName());
266         string buf2 = OnlyPath(buf);
267
268         if (!p.empty()) {
269                 buf = MakeAbsPath(p, buf2);
270                 buf = OnlyPath(buf);
271         } else {
272                 buf = OnlyPath(form->lv_->buffer()->fileName());
273         }
274     
275         FileDialog fileDlg(form->lv_, _("Select external file"),
276                 LFUN_SELECT_FILE_SYNC,
277                 make_pair(string(_("Document")), string(buf)));
278         
279         /// Determine the template file extension
280         ExternalTemplate const & et = form->params_.templ;
281
282         string regexp = et.fileRegExp;
283         if (regexp.empty())
284                 regexp = "*";
285
286         // FIXME: a temporary hack until the FileDialog interface is updated
287         regexp += "|";
288
289         while (1) {
290                 string const path = (once) ? current_path : buf;
291                 FileDialog::Result result = fileDlg.Select(path, regexp, fl_get_input(form->dialog_->input_filename));
292
293                 if (result.second.empty())
294                         return;
295
296                 string p = result.second;
297
298                 buf = MakeRelPath(p, buf2);
299                 current_path = OnlyPath(p);
300                 once = 1;
301                 
302                 if (contains(p, "#") || contains(p, "~") || contains(p, "$")
303                     || contains(p, "%")) {
304                         WriteAlert(_("Filename can't contain any "
305                                      "of these characters:"),
306                                    // xgettext:no-c-format
307                                    _("'#', '~', '$' or '%'."));
308                 } else
309                         break;
310         }
311
312         fl_set_input(form->dialog_->input_filename, buf.c_str());
313 }
314
315
316 void FormExternal::editCB(FL_OBJECT * ob, long)
317 {
318         FormExternal * form = static_cast<FormExternal*>(ob->form->u_vdata);
319
320         form->apply();
321         form->inset_->editExternal();
322 }
323
324
325 void FormExternal::viewCB(FL_OBJECT * ob, long)
326 {
327         FormExternal * form = static_cast<FormExternal*>(ob->form->u_vdata);
328         
329         form->apply();
330         form->inset_->viewExternal();
331 }
332
333
334 void FormExternal::updateCB(FL_OBJECT * ob, long)
335 {
336         FormExternal * form = static_cast<FormExternal*>(ob->form->u_vdata);
337         
338         form->apply();
339         form->inset_->updateExternal();
340 }