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