]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiExternal.cpp
9bcf779077c4d9abff6d5a2bf576b94ea046c319
[lyx.git] / src / frontends / qt4 / GuiExternal.cpp
1 /**
2  * \file GuiExternal.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  * \author Angus Leeming
8  * \author Asger Alstrup
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "GuiExternal.h"
16
17 #include "FuncRequest.h"
18 #include "support/gettext.h"
19 #include "Length.h"
20 #include "LyXRC.h"
21
22 #include "insets/ExternalSupport.h"
23 #include "insets/ExternalTemplate.h"
24 #include "insets/InsetExternal.h"
25
26 #include "graphics/GraphicsCache.h"
27 #include "graphics/GraphicsCacheItem.h"
28 #include "graphics/GraphicsImage.h"
29
30 #include "support/convert.h"
31 #include "support/filetools.h"
32 #include "support/lstrings.h"
33 #include "support/lyxlib.h"
34 #include "support/os.h"
35
36 #include "LengthCombo.h"
37 #include "qt_helpers.h"
38 #include "Validator.h"
39
40 #include <QCheckBox>
41 #include <QLineEdit>
42 #include <QPushButton>
43 #include <QTabWidget>
44 #include <QTextBrowser>
45
46 using namespace std;
47 using namespace lyx::support;
48
49 namespace lyx {
50 namespace frontend {
51
52 using namespace external;
53
54 namespace {
55
56 RotationDataType origins[] = {
57         RotationData::DEFAULT,
58         RotationData::TOPLEFT,
59         RotationData::BOTTOMLEFT,
60         RotationData::BASELINELEFT,
61         RotationData::CENTER,
62         RotationData::TOPCENTER,
63         RotationData::BOTTOMCENTER,
64         RotationData::BASELINECENTER,
65         RotationData::TOPRIGHT,
66         RotationData::BOTTOMRIGHT,
67         RotationData::BASELINERIGHT
68 };
69
70
71 // These are the strings, corresponding to the above, that the GUI should
72 // use. Note that they can/should be translated.
73 char const * const origin_gui_strs[] = {
74         N_("Default"),
75         N_("Top left"), N_("Bottom left"), N_("Baseline left"),
76         N_("Center"), N_("Top center"), N_("Bottom center"), N_("Baseline center"),
77         N_("Top right"), N_("Bottom right"), N_("Baseline right")
78 };
79
80 external::Template getTemplate(int i)
81 {
82         external::TemplateManager::Templates::const_iterator i1
83                 = external::TemplateManager::get().getTemplates().begin();
84         advance(i1, i);
85         return i1->second;
86 }
87
88 } // namespace anon
89
90
91 GuiExternal::GuiExternal(GuiView & lv)
92         : GuiDialog(lv, "external", qt_("External Material")), bbChanged_(false)
93 {
94         setupUi(this);
95
96         connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
97         connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
98         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
99
100         connect(displayCB, SIGNAL(toggled(bool)),
101                 showCO, SLOT(setEnabled(bool)));
102         connect(displayCB, SIGNAL(toggled(bool)),
103                 displayscaleED, SLOT(setEnabled(bool)));
104         connect(showCO, SIGNAL(activated(QString)),
105                 this, SLOT(change_adaptor()));
106         connect(originCO, SIGNAL(activated(int)),
107                 this, SLOT(change_adaptor()));
108         connect(aspectratioCB, SIGNAL(stateChanged(int)),
109                 this, SLOT(change_adaptor()));
110         connect(browsePB, SIGNAL(clicked()),
111                 this, SLOT(browseClicked()));
112         connect(externalCO, SIGNAL(activated(QString)),
113                 this, SLOT(templateChanged()));
114         connect(extraED, SIGNAL(textChanged(QString)),
115                 this, SLOT(extraChanged(QString)));
116         connect(extraFormatCO, SIGNAL(activated(QString)),
117                 this, SLOT(formatChanged(QString)));
118         connect(widthUnitCO, SIGNAL(activated(int)),
119                 this, SLOT(widthUnitChanged()));
120         connect(heightUnitCO, SIGNAL(selectionChanged(lyx::Length::UNIT)),
121                 this, SLOT(change_adaptor()));
122         connect(displayCB, SIGNAL(stateChanged(int)),
123                 this, SLOT(change_adaptor()));
124         connect(displayscaleED, SIGNAL(textChanged(QString)),
125                 this, SLOT(change_adaptor()));
126         connect(angleED, SIGNAL(textChanged(QString)),
127                 this, SLOT(change_adaptor()));
128         connect(widthED, SIGNAL(textChanged(QString)),
129                 this, SLOT(sizeChanged()));
130         connect(heightED, SIGNAL(textChanged(QString)),
131                 this, SLOT(sizeChanged()));
132         connect(fileED, SIGNAL(textChanged(QString)),
133                 this, SLOT(change_adaptor()));
134         connect(clipCB, SIGNAL(stateChanged(int)),
135                 this, SLOT(change_adaptor()));
136         connect(getbbPB, SIGNAL(clicked()), this, SLOT(getbbClicked()));
137         connect(xrED, SIGNAL(textChanged(QString)), this, SLOT(bbChanged()));
138         connect(ytED, SIGNAL(textChanged(QString)), this, SLOT(bbChanged()));
139         connect(xlED, SIGNAL(textChanged(QString)), this, SLOT(bbChanged()));
140         connect(ybED, SIGNAL(textChanged(QString)), this, SLOT(bbChanged()));
141         connect(draftCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
142
143         QIntValidator * validator = new QIntValidator(displayscaleED);
144         validator->setBottom(1);
145         displayscaleED->setValidator(validator);
146
147         angleED->setValidator(new QDoubleValidator(-360, 360, 2, angleED));
148
149         xlED->setValidator(new QIntValidator(xlED));
150         ybED->setValidator(new QIntValidator(ybED));
151         xrED->setValidator(new QIntValidator(xrED));
152         ytED->setValidator(new QIntValidator(ytED));
153
154         widthED->setValidator(unsignedLengthValidator(widthED));
155         heightED->setValidator(unsignedLengthValidator(heightED));
156
157         setFocusProxy(fileED);
158
159         bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
160
161         bc().setOK(okPB);
162         bc().setApply(applyPB);
163         bc().setCancel(closePB);
164
165         bc().addReadOnly(fileED);
166         bc().addReadOnly(browsePB);
167         bc().addReadOnly(externalCO);
168         bc().addReadOnly(draftCB);
169         bc().addReadOnly(displayscaleED);
170         bc().addReadOnly(showCO);
171         bc().addReadOnly(displayCB);
172         bc().addReadOnly(angleED);
173         bc().addReadOnly(originCO);
174         bc().addReadOnly(heightUnitCO);
175         bc().addReadOnly(heightED);
176         bc().addReadOnly(aspectratioCB);
177         bc().addReadOnly(widthUnitCO);
178         bc().addReadOnly(widthED);
179         bc().addReadOnly(clipCB);
180         bc().addReadOnly(getbbPB);
181         bc().addReadOnly(ytED);
182         bc().addReadOnly(xlED);
183         bc().addReadOnly(xrED);
184         bc().addReadOnly(ybED);
185         bc().addReadOnly(extraFormatCO);
186         bc().addReadOnly(extraED);
187
188         bc().addCheckedLineEdit(angleED, angleLA);
189         bc().addCheckedLineEdit(displayscaleED, scaleLA);
190         bc().addCheckedLineEdit(heightED, heightLA);
191         bc().addCheckedLineEdit(widthED, widthLA);
192         bc().addCheckedLineEdit(xlED, lbLA);
193         bc().addCheckedLineEdit(ybED, lbLA);
194         bc().addCheckedLineEdit(xrED, rtLA);
195         bc().addCheckedLineEdit(ytED, rtLA);
196         bc().addCheckedLineEdit(fileED, fileLA);
197
198         external::TemplateManager::Templates::const_iterator i1, i2;
199         i1 = external::TemplateManager::get().getTemplates().begin();
200         i2 = external::TemplateManager::get().getTemplates().end();
201         for (; i1 != i2; ++i1)
202                 externalCO->addItem(qt_(i1->second.lyxName));
203
204         // Fill the origins combo
205         for (size_t i = 0; i != sizeof(origins) / sizeof(origins[0]); ++i)
206                 originCO->addItem(qt_(origin_gui_strs[i]));
207
208         // Fill the width combo
209         widthUnitCO->addItem(qt_("Scale%"));
210         for (int i = 0; i < num_units; i++)
211                 widthUnitCO->addItem(qt_(unit_name_gui[i]));
212 }
213
214
215 bool GuiExternal::activateAspectratio() const
216 {
217         if (widthUnitCO->currentIndex() == 0)
218                 return false;
219
220         string const wstr = fromqstr(widthED->text());
221         if (wstr.empty())
222                 return false;
223         bool const wIsDbl = isStrDbl(wstr);
224         if (wIsDbl && float_equal(convert<double>(wstr), 0.0, 0.05))
225                 return false;
226         Length l;
227         if (!wIsDbl && (!isValidLength(wstr, &l) || l.zero()))
228                 return false;
229
230         string const hstr = fromqstr(heightED->text());
231         if (hstr.empty())
232                 return false;
233         bool const hIsDbl = isStrDbl(hstr);
234         if (hIsDbl && float_equal(convert<double>(hstr), 0.0, 0.05))
235                 return false;
236         if (!hIsDbl && (!isValidLength(hstr, &l) || l.zero()))
237                 return false;
238
239         return true;
240 }
241
242
243 void GuiExternal::bbChanged()
244 {
245         bbChanged_ = true;
246         changed();
247 }
248
249
250 void GuiExternal::browseClicked()
251 {
252         int const choice =  externalCO->currentIndex();
253         QString const template_name = toqstr(getTemplate(choice).lyxName);
254         QString const str = browse(fileED->text(), template_name);
255         if (!str.isEmpty()) {
256                 fileED->setText(str);
257                 changed();
258         }
259 }
260
261
262 void GuiExternal::change_adaptor()
263 {
264         changed();
265 }
266
267
268 void GuiExternal::extraChanged(const QString & text)
269 {
270         extra_[extraFormatCO->currentText()] = text;
271         changed();
272 }
273
274
275 void GuiExternal::formatChanged(const QString & format)
276 {
277         extraED->setText(extra_[format]);
278 }
279
280
281 void GuiExternal::getbbClicked()
282 {
283         xlED->setText("0");
284         ybED->setText("0");
285         xrED->setText("0");
286         ytED->setText("0");
287
288         string const filename = fromqstr(fileED->text());
289         if (filename.empty())
290                 return;
291
292         FileName const abs_file(support::makeAbsPath(filename, fromqstr(bufferFilepath())));
293
294         // try to get it from the file, if possible
295         string bb = readBB_from_PSFile(abs_file);
296         if (bb.empty()) {
297                 // we don't, so ask the Graphics Cache if it has loaded the file
298                 int width = 0;
299                 int height = 0;
300
301                 graphics::Cache & gc = graphics::Cache::get();
302                 if (gc.inCache(abs_file)) {
303                         graphics::Image const * image = gc.item(abs_file)->image();
304
305                         if (image) {
306                                 width  = image->width();
307                                 height = image->height();
308                         }
309                 }
310                 bb = "0 0 " + convert<string>(width) + ' ' + convert<string>(height);
311         }
312
313         xlED->setText(toqstr(token(bb, ' ', 0)));
314         ybED->setText(toqstr(token(bb, ' ', 1)));
315         xrED->setText(toqstr(token(bb, ' ', 2)));
316         ytED->setText(toqstr(token(bb, ' ', 3)));
317
318         bbChanged_ = false;
319 }
320
321
322 void GuiExternal::sizeChanged()
323 {
324         aspectratioCB->setEnabled(activateAspectratio());
325         changed();
326 }
327
328
329 void GuiExternal::templateChanged()
330 {
331         updateTemplate();
332         changed();
333 }
334
335
336 void GuiExternal::widthUnitChanged()
337 {
338         bool useHeight = (widthUnitCO->currentIndex() > 0);
339
340         if (useHeight)
341                 widthED->setValidator(unsignedLengthValidator(widthED));
342         else
343                 widthED->setValidator(new QDoubleValidator(0, 1000, 2, widthED));
344
345         heightED->setEnabled(useHeight);
346         heightUnitCO->setEnabled(useHeight);
347         changed();
348 }
349
350
351 static Length::UNIT defaultUnit()
352 {
353         Length::UNIT default_unit = Length::CM;
354         switch (lyxrc.default_papersize) {
355         case PAPER_USLETTER:
356         case PAPER_USLEGAL:
357         case PAPER_USEXECUTIVE:
358                 default_unit = Length::IN;
359                 break;
360         default:
361                 break;
362         }
363         return default_unit;
364 }
365
366
367 static void setDisplay(
368         QCheckBox & displayCB, QComboBox & showCO, QLineEdit & scaleED,
369         external::DisplayType display, unsigned int scale, bool read_only)
370 {
371         int item = 0;
372         switch (display) {
373         case external::DefaultDisplay:
374                 item = 0;
375                 break;
376         case external::MonochromeDisplay:
377                 item = 1;
378                 break;
379         case external::GrayscaleDisplay:
380                 item = 2;
381                 break;
382         case external::ColorDisplay:
383                 item = 3;
384                 break;
385         case external::PreviewDisplay:
386                 item = 4;
387                 break;
388         case external::NoDisplay:
389                 item = 0;
390                 break;
391         }
392
393         showCO.setCurrentIndex(item);
394         bool const no_display = display == external::NoDisplay;
395         showCO.setEnabled(!no_display && !read_only);
396         displayCB.setChecked(!no_display);
397         scaleED.setEnabled(!no_display && !read_only);
398         scaleED.setText(QString::number(scale));
399 }
400
401
402 static external::DisplayType display(QCheckBox const & displayCB,
403         QComboBox const & showCO)
404 {
405         if (!displayCB.isChecked())
406                 return external::NoDisplay;
407         switch (showCO.currentIndex()) {
408         default:
409         case 0:
410                 return external::DefaultDisplay;
411         case 1:
412                 return external::MonochromeDisplay;
413         case 2:
414                 return external::GrayscaleDisplay;
415         case 3:
416                 return external::ColorDisplay;
417         case 4:
418                 return external::PreviewDisplay;
419         }
420 }
421
422
423 static void setRotation(QLineEdit & angleED, QComboBox & originCO,
424         external::RotationData const & data)
425 {
426         originCO.setCurrentIndex(int(data.origin()));
427         angleED.setText(toqstr(data.angle));
428 }
429
430
431 static void getRotation(external::RotationData & data,
432         QLineEdit const & angleED, QComboBox const & originCO)
433 {
434         typedef external::RotationData::OriginType OriginType;
435
436         data.origin(static_cast<OriginType>(originCO.currentIndex()));
437         data.angle = fromqstr(angleED.text());
438 }
439
440
441 static void setSize(QLineEdit & widthED, QComboBox & widthUnitCO,
442         QLineEdit & heightED, LengthCombo & heightUnitCO,
443         QCheckBox & aspectratioCB,
444         external::ResizeData const & data)
445 {
446         bool using_scale = data.usingScale();
447         string scale = data.scale;
448         if (data.no_resize()) {
449                 // Everything is zero, so default to this!
450                 using_scale = true;
451                 scale = "100";
452         }
453
454         if (using_scale) {
455                 widthED.setText(toqstr(scale));
456                 widthUnitCO.setCurrentIndex(0);
457         } else {
458                 widthED.setText(QString::number(data.width.value()));
459                 // Because 'Scale' is position 0...
460                 // Note also that width cannot be zero here, so
461                 // we don't need to worry about the default unit.
462                 widthUnitCO.setCurrentIndex(data.width.unit() + 1);
463         }
464
465         string const h = data.height.zero() ? string() : data.height.asString();
466         Length::UNIT default_unit = data.width.zero() ?
467                 defaultUnit() : data.width.unit();
468         lengthToWidgets(&heightED, &heightUnitCO, h, default_unit);
469
470         heightED.setEnabled(!using_scale);
471         heightUnitCO.setEnabled(!using_scale);
472
473         aspectratioCB.setChecked(data.keepAspectRatio);
474
475         bool const disable_aspectRatio = using_scale ||
476                 data.width.zero() || data.height.zero();
477         aspectratioCB.setEnabled(!disable_aspectRatio);
478 }
479
480
481 static void getSize(external::ResizeData & data,
482         QLineEdit const & widthED, QComboBox const & widthUnitCO,
483         QLineEdit const & heightED, LengthCombo const & heightUnitCO,
484         QCheckBox const & aspectratioCB)
485 {
486         string const width = fromqstr(widthED.text());
487
488         if (widthUnitCO.currentIndex() > 0) {
489                 // Subtract one, because scale is 0.
490                 int const unit = widthUnitCO.currentIndex() - 1;
491
492                 Length w;
493                 if (isValidLength(width, &w))
494                         data.width = w;
495                 else if (isStrDbl(width))
496                         data.width = Length(convert<double>(width),
497                                            static_cast<Length::UNIT>(unit));
498                 else
499                         data.width = Length();
500
501                 data.scale = string();
502
503         } else {
504                 // scaling instead of a width
505                 data.scale = width;
506                 data.width = Length();
507         }
508
509         data.height = Length(widgetsToLength(&heightED, &heightUnitCO));
510
511         data.keepAspectRatio = aspectratioCB.isChecked();
512 }
513
514
515 void setCrop(QCheckBox & clipCB,
516         QLineEdit & xlED, QLineEdit & ybED,
517         QLineEdit & xrED, QLineEdit & ytED,
518         external::ClipData const & data)
519 {
520         clipCB.setChecked(data.clip);
521         graphics::BoundingBox const & bbox = data.bbox;
522         xlED.setText(QString::number(bbox.xl));
523         ybED.setText(QString::number(bbox.yb));
524         xrED.setText(QString::number(bbox.xr));
525         ytED.setText(QString::number(bbox.yt));
526 }
527
528
529 static void getCrop(external::ClipData & data,
530         QCheckBox const & clipCB,
531         QLineEdit const & xlED, QLineEdit const & ybED,
532         QLineEdit const & xrED, QLineEdit const & ytED,
533         bool bb_changed)
534 {
535         data.clip = clipCB.isChecked();
536
537         if (!bb_changed)
538                 return;
539
540         data.bbox.xl = xlED.text().toInt();
541         data.bbox.yb = ybED.text().toInt();
542         data.bbox.xr = xrED.text().toInt();
543         data.bbox.yt = ytED.text().toInt();
544 }
545
546
547 void GuiExternal::updateContents()
548 {
549         tab->setCurrentIndex(0);
550
551         string const name =
552                 params_.filename.outputFilename(fromqstr(bufferFilepath()));
553         fileED->setText(toqstr(name));
554
555         int index = -1;
556         external::TemplateManager::Templates::const_iterator i1, i2;
557         i1 = external::TemplateManager::get().getTemplates().begin();
558         i2 = external::TemplateManager::get().getTemplates().end();
559         for (int i = 0; i1 != i2; ++i1, ++i) {
560                 if (i1->second.lyxName == params_.templatename()) {
561                         index = i;
562                         break;
563                 }
564         }
565
566         externalCO->setCurrentIndex(index);
567         updateTemplate();
568
569         draftCB->setChecked(params_.draft);
570
571         setDisplay(*displayCB, *showCO, *displayscaleED,
572                    params_.display, params_.lyxscale, isBufferReadonly());
573
574         setRotation(*angleED, *originCO, params_.rotationdata);
575
576         setSize(*widthED, *widthUnitCO, *heightED, *heightUnitCO,
577                 *aspectratioCB, params_.resizedata);
578
579         setCrop(*clipCB, *xlED, *ybED, *xrED, *ytED, params_.clipdata);
580         bbChanged_ = !params_.clipdata.bbox.empty();
581
582         isValid();
583 }
584
585
586 void GuiExternal::updateTemplate()
587 {
588         external::Template templ = getTemplate(externalCO->currentIndex());
589         externalTB->setPlainText(qt_(templ.helpText));
590
591         // Ascertain which (if any) transformations the template supports
592         // and disable tabs hosting unsupported transforms.
593         typedef vector<external::TransformID> TransformIDs;
594         TransformIDs const transformIds = templ.transformIds;
595         TransformIDs::const_iterator tr_begin = transformIds.begin();
596         TransformIDs::const_iterator const tr_end = transformIds.end();
597
598         bool found = std::find(tr_begin, tr_end, external::Rotate) != tr_end;
599         tab->setTabEnabled(tab->indexOf(rotatetab), found);
600         found = std::find(tr_begin, tr_end, external::Resize) != tr_end;
601         tab->setTabEnabled(tab->indexOf(scaletab), found);
602
603         found = std::find(tr_begin, tr_end, external::Clip) != tr_end;
604         tab->setTabEnabled(tab->indexOf(croptab), found);
605
606         found = std::find(tr_begin, tr_end, external::Extra) != tr_end;
607         tab->setTabEnabled(tab->indexOf(optionstab), found);
608
609         if (!found)
610                 return;
611
612         // Ascertain whether the template has any formats supporting
613         // the 'Extra' option
614         extra_.clear();
615         extraED->clear();
616         extraFormatCO->clear();
617
618         external::Template::Formats::const_iterator it  = templ.formats.begin();
619         external::Template::Formats::const_iterator end = templ.formats.end();
620         for (; it != end; ++it) {
621                 if (it->second.option_transformers.find(external::Extra) ==
622                     it->second.option_transformers.end())
623                         continue;
624                 string const format = it->first;
625                 string const opt = params_.extradata.get(format);
626                 extraFormatCO->addItem(toqstr(format));
627                 extra_[toqstr(format)] = toqstr(opt);
628         }
629
630         bool const enabled = extraFormatCO->count()  > 0;
631
632         tab->setTabEnabled(tab->indexOf(optionstab), enabled);
633         extraED->setEnabled(enabled && !isBufferReadonly());
634         extraFormatCO->setEnabled(enabled);
635
636         if (enabled) {
637                 extraFormatCO->setCurrentIndex(0);
638                 extraED->setText(extra_[extraFormatCO->currentText()]);
639         }
640 }
641
642
643 void GuiExternal::applyView()
644 {
645         params_.filename.set(fromqstr(fileED->text()), fromqstr(bufferFilepath()));
646         params_.settemplate(getTemplate(externalCO->currentIndex()).lyxName);
647
648         params_.draft = draftCB->isChecked();
649         params_.lyxscale = displayscaleED->text().toInt();
650         params_.display = display(*displayCB, *showCO);
651
652         if (tab->isTabEnabled(tab->indexOf(rotatetab)))
653                 getRotation(params_.rotationdata, *angleED, *originCO);
654
655         if (tab->isTabEnabled(tab->indexOf(scaletab)))
656                 getSize(params_.resizedata, *widthED, *widthUnitCO,
657                         *heightED, *heightUnitCO, *aspectratioCB);
658
659         if (tab->isTabEnabled(tab->indexOf(croptab)))
660                 getCrop(params_.clipdata, *clipCB, *xlED, *ybED,
661                         *xrED, *ytED, bbChanged_);
662
663         if (tab->isTabEnabled(tab->indexOf(optionstab))) {
664                 MapType::const_iterator it = extra_.begin();
665                 MapType::const_iterator const end = extra_.end();
666                 for (; it != end; ++it)
667                         params_.extradata.set(fromqstr(it.key()), fromqstr(it.value().trimmed()));
668         }
669 }
670
671
672 bool GuiExternal::initialiseParams(string const & data)
673 {
674         InsetExternal::string2params(data, buffer(), params_);
675         return true;
676 }
677
678
679 void GuiExternal::clearParams()
680 {
681         params_ = InsetExternalParams();
682 }
683
684
685 void GuiExternal::dispatchParams()
686 {
687         string const lfun = InsetExternal::params2string(params_, buffer());
688         dispatch(FuncRequest(getLfun(), lfun));
689 }
690
691
692 static QStringList templateFilters(QString const & template_name)
693 {
694         /// Determine the template file extension
695         external::TemplateManager const & etm =
696                 external::TemplateManager::get();
697         external::Template const * const et_ptr =
698                 etm.getTemplateByName(fromqstr(template_name));
699
700         return fileFilters(et_ptr ? toqstr(et_ptr->fileRegExp) : QString());
701 }
702
703
704 QString GuiExternal::browse(QString const & input,
705                                      QString const & template_name) const
706 {
707         QString const title = qt_("Select external file");
708         QString const bufpath = bufferFilepath();
709         QStringList const filter = templateFilters(template_name);
710
711         QString const label1 = qt_("Documents|#o#O");
712         QString const dir1 = toqstr(lyxrc.document_path);
713
714         return browseRelFile(input, bufpath, title, filter, false, label1, dir1);
715 }
716
717
718 Dialog * createGuiExternal(GuiView & lv) { return new GuiExternal(lv); }
719
720
721 } // namespace frontend
722 } // namespace lyx
723
724 #include "GuiExternal_moc.cpp"