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