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