]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiGraphics.cpp
577dc77214649a54fa26607013cb472068bc0b7e
[lyx.git] / src / frontends / qt4 / GuiGraphics.cpp
1 /**
2  * \file GuiGraphics.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 Edwin Leuven
8  * \author Herbert Voß
9  * \author Richard Heck
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #include <config.h>
15
16 #include "GuiGraphics.h"
17
18 #include "ControlGraphics.h"
19 #include "debug.h"
20 #include "LengthCombo.h"
21 #include "lengthcommon.h"
22 #include "LyXRC.h"
23 #include "qt_helpers.h"
24 #include "Validator.h"
25
26 #include "insets/InsetGraphicsParams.h"
27
28 #include "support/convert.h"
29 #include "support/lstrings.h"
30 #include "support/lyxlib.h"
31 #include "support/os.h"
32
33 #include <boost/bind.hpp>
34
35 #include <QCheckBox>
36 #include <QCloseEvent>
37 #include <QLabel>
38 #include <QLineEdit>
39 #include <QPushButton>
40 #include <QValidator>
41
42 #include <algorithm>
43 #include <cmath>
44
45 using lyx::support::float_equal;
46 using lyx::support::token;
47
48 using lyx::support::os::internal_path;
49
50 #ifndef CXX_GLOBAL_CSTD
51 using std::floor;
52 #endif
53
54 using std::vector;
55 using std::string;
56
57
58 namespace lyx {
59 namespace frontend {
60
61
62 template<class Pair>
63 std::vector<typename Pair::first_type> const
64 getFirst(std::vector<Pair> const & pr)
65 {
66         std::vector<typename Pair::first_type> tmp(pr.size());
67         std::transform(pr.begin(), pr.end(), tmp.begin(),
68                        boost::bind(&Pair::first, _1));
69         return tmp;
70 }
71
72 ///
73 template<class Pair>
74 std::vector<typename Pair::second_type> const
75 getSecond(std::vector<Pair> const & pr)
76 {
77          std::vector<typename Pair::second_type> tmp(pr.size());
78          std::transform(pr.begin(), pr.end(), tmp.begin(),
79                                          boost::bind(&Pair::second, _1));
80          return tmp;
81 }
82
83 GuiGraphicsDialog::GuiGraphicsDialog(LyXView & lv)
84         : GuiDialog(lv, "graphics")
85 {
86         setupUi(this);
87         setViewTitle(_("Graphics"));
88         setController(new ControlGraphics(*this));
89
90         //main buttons
91         connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
92         connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
93         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
94         connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
95
96         //graphics pane
97         connect(filename, SIGNAL(textChanged(const QString &)),
98                 this, SLOT(change_adaptor()));
99         connect(WidthCB, SIGNAL( clicked()),
100                 this, SLOT(change_adaptor()));
101         connect(HeightCB, SIGNAL( clicked()),
102                 this, SLOT(change_adaptor()));
103         connect(Width, SIGNAL(textChanged(const QString &)),
104                 this, SLOT(change_adaptor()));
105         connect(Height, SIGNAL(textChanged(const QString &)),
106                 this, SLOT(change_adaptor()));
107         connect(heightUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
108                 this, SLOT(change_adaptor()));
109         connect(widthUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
110                 this, SLOT(change_adaptor()));
111         connect(aspectratio, SIGNAL(stateChanged(int)),
112                 this, SLOT(change_adaptor()));
113         connect(angle, SIGNAL(textChanged(const QString &)),
114                 this, SLOT(change_adaptor()));
115         connect(origin, SIGNAL(activated(int)),
116                 this, SLOT(change_adaptor()));
117         connect(scaleCB, SIGNAL(clicked()),
118                 this, SLOT(change_adaptor()));
119         connect(Scale, SIGNAL(textChanged(const QString &)),
120                 this, SLOT(change_adaptor()));
121         connect(rotateOrderCB, SIGNAL(clicked()),
122                 this, SLOT(change_adaptor()));
123
124         filename->setValidator(new PathValidator(true, filename));
125         setFocusProxy(filename);
126
127         QDoubleValidator * scaleValidator = new DoubleAutoValidator(Scale);
128         scaleValidator->setBottom(0);
129         scaleValidator->setDecimals(256); //I guess that will do
130         Scale->setValidator(scaleValidator);
131         Height->setValidator(unsignedLengthAutoValidator(Height));
132         Width->setValidator(unsignedLengthAutoValidator(Width));
133         angle->setValidator(new QDoubleValidator(-360, 360, 2, angle));
134
135         //clipping pane
136         connect(clip, SIGNAL(stateChanged(int)),
137                 this, SLOT(change_adaptor()));
138         connect(lbY, SIGNAL(textChanged(const QString&)),
139                 this, SLOT(change_bb()));
140         connect(lbYunit, SIGNAL(activated(int)),
141                 this, SLOT(change_bb()));
142         connect(rtY, SIGNAL(textChanged(const QString&)),
143                 this, SLOT(change_bb()));
144         connect(rtYunit, SIGNAL(activated(int)),
145                 this, SLOT(change_bb()));
146         connect(lbX, SIGNAL(textChanged(const QString&)),
147                 this, SLOT(change_bb()));
148         connect(lbXunit, SIGNAL(activated(int)),
149                 this, SLOT(change_bb()));
150         connect(rtX, SIGNAL(textChanged(const QString&)),
151                 this, SLOT(change_bb()));
152         connect(rtXunit, SIGNAL(activated(int)),
153                 this, SLOT(change_bb()));
154         connect(getPB, SIGNAL(clicked()),
155                 this, SLOT(change_adaptor()));
156
157         lbX->setValidator(new QDoubleValidator(lbX));
158         lbY->setValidator(new QDoubleValidator(lbY));
159         rtX->setValidator(new QDoubleValidator(rtX));
160         rtY->setValidator(new QDoubleValidator(rtY));
161
162         //extra options pane
163         connect(latexoptions, SIGNAL(textChanged(const QString&)),
164                 this, SLOT(change_adaptor()));
165         connect(draftCB, SIGNAL(stateChanged(int)),
166                 this, SLOT(change_adaptor()));
167         connect(unzipCB, SIGNAL(stateChanged(int)),
168                 this, SLOT(change_adaptor()));
169         // FIXME: we should connect to clicked() when we move to Qt 4.2 because
170         // the toggled(bool) signal is also trigged when we update the widgets
171         // (rgh-4/07) this isn't as much or a problem as it was, because we're now
172         // using blockSignals() to keep from triggering that signal when we call
173         // setChecked(). Note, too, that clicked() would get called whenever it
174         // is clicked, even right clicked (I think), not just whenever it is
175         // toggled.
176         connect(subfigure, SIGNAL(toggled(bool)),
177                 this, SLOT(change_adaptor()));
178         connect(subcaption, SIGNAL(textChanged(const QString&)),
179                 this, SLOT(change_adaptor()));
180         connect(displayGB, SIGNAL(toggled(bool)),
181                 this, SLOT(change_adaptor()));
182         connect(showCB, SIGNAL(currentIndexChanged(int)),
183                 this, SLOT(change_adaptor()));
184         connect(displayscale, SIGNAL(textChanged(const QString&)),
185                 this, SLOT(change_adaptor()));
186         displayscale->setValidator(new QIntValidator(displayscale));
187
188         bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
189         bc().setOK(okPB);
190         bc().setApply(applyPB);
191         bc().setRestore(restorePB);
192         bc().setCancel(closePB);
193
194         bc().addReadOnly(latexoptions);
195         bc().addReadOnly(subfigure);
196         bc().addReadOnly(filenameL);
197         bc().addReadOnly(filename);
198         bc().addReadOnly(browsePB);
199         bc().addReadOnly(unzipCB);
200         bc().addReadOnly(bbFrame);
201         bc().addReadOnly(draftCB);
202         bc().addReadOnly(clip);
203         bc().addReadOnly(unzipCB);
204         bc().addReadOnly(displayGB);
205         bc().addReadOnly(sizeGB);
206         bc().addReadOnly(rotationGB);
207         bc().addReadOnly(latexoptions);
208         bc().addReadOnly(getPB);
209         bc().addReadOnly(rotateOrderCB);
210
211         // initialize the length validator
212         bc().addCheckedLineEdit(Scale, scaleCB);
213         bc().addCheckedLineEdit(Width, WidthCB);
214         bc().addCheckedLineEdit(Height, HeightCB);
215         bc().addCheckedLineEdit(displayscale, scaleLA);
216         bc().addCheckedLineEdit(angle, angleL);
217         bc().addCheckedLineEdit(lbX, xL);
218         bc().addCheckedLineEdit(lbY, yL);
219         bc().addCheckedLineEdit(rtX, xL_2);
220         bc().addCheckedLineEdit(rtY, yL_2);
221         bc().addCheckedLineEdit(filename, filenameL);
222 }
223
224
225 ControlGraphics & GuiGraphicsDialog::controller()
226 {
227         return static_cast<ControlGraphics &>(GuiDialog::controller());
228 }
229
230
231 void GuiGraphicsDialog::change_adaptor()
232 {
233         changed();
234 }
235
236
237 void GuiGraphicsDialog::change_bb()
238 {
239         controller().bbChanged = true;
240         LYXERR(Debug::GRAPHICS)
241                 << "[controller().bb_Changed set to true]\n";
242         changed();
243 }
244
245
246 void GuiGraphicsDialog::closeEvent(QCloseEvent * e)
247 {
248         slotClose();
249         e->accept();
250 }
251
252
253 void GuiGraphicsDialog::on_browsePB_clicked()
254 {
255         docstring const str =
256                 controller().browse(qstring_to_ucs4(filename->text()));
257         if(!str.empty()){
258                 filename->setText(toqstr(str));
259                 changed();
260         }
261 }
262
263
264 void GuiGraphicsDialog::on_getPB_clicked()
265 {
266         getBB();
267 }
268
269
270 void GuiGraphicsDialog::on_editPB_clicked()
271 {
272         controller().editGraphics();
273 }
274
275
276 void GuiGraphicsDialog::on_filename_textChanged(const QString & filename)
277 {
278         editPB->setDisabled(filename.isEmpty());
279 }
280
281
282 void GuiGraphicsDialog::setAutoText()
283 {
284         if (scaleCB->isChecked())
285                 return;
286         if (!Scale->isEnabled() && Scale->text() != "100")
287                 Scale->setText(QString("auto"));
288
289         setAutoTextCB(WidthCB, Width, widthUnit);
290         setAutoTextCB(HeightCB, Height, heightUnit);
291 }
292
293
294 void GuiGraphicsDialog::on_scaleCB_toggled(bool setScale)
295 {
296         Scale->setEnabled(setScale);
297         if (setScale) {
298                 Scale->setText("100");
299                 Scale->setFocus(Qt::OtherFocusReason);
300         }
301
302         WidthCB->setDisabled(setScale);
303         WidthCB->blockSignals(true);
304         WidthCB->setChecked(false);
305         WidthCB->blockSignals(false);
306         Width->setEnabled(false);
307         widthUnit->setEnabled(false);
308
309         HeightCB->setDisabled(setScale);
310         HeightCB->blockSignals(true);
311         HeightCB->setChecked(false);
312         HeightCB->blockSignals(false);
313         Height->setEnabled(false);
314         heightUnit->setEnabled(false);
315
316         aspectratio->setDisabled(true);
317         aspectratio->setChecked(true);
318
319         rotateOrderCB->setEnabled((WidthCB->isChecked() ||
320                                  HeightCB->isChecked() ||
321                                  scaleCB->isChecked()) &&
322                                  (angle->text() != "0"));
323
324         setAutoText();
325 }
326
327
328 void GuiGraphicsDialog::on_WidthCB_toggled(bool setWidth)
329 {
330         Width->setEnabled(setWidth);
331         widthUnit->setEnabled(setWidth);
332         if (setWidth)
333                 Width->setFocus(Qt::OtherFocusReason);
334
335         bool const setHeight = HeightCB->isChecked();
336         aspectratio->setEnabled(setWidth && setHeight);
337         aspectratio->blockSignals(true);
338         aspectratio->setChecked(!(setWidth && setHeight));
339         aspectratio->blockSignals(false);
340
341         scaleCB->setEnabled(!setWidth && !setHeight);
342         //already will be unchecked, so don't need to do that
343         Scale->setEnabled((!setWidth && !setHeight) //=scaleCB->isEnabled()
344                         && scaleCB->isChecked()); //should be false, but let's check
345         rotateOrderCB->setEnabled((setWidth || setHeight ||
346                                  scaleCB->isChecked()) &&
347                                  (angle->text() != "0"));
348
349         setAutoText();
350 }
351
352
353 void GuiGraphicsDialog::on_HeightCB_toggled(bool setHeight)
354 {
355         Height->setEnabled(setHeight);
356         heightUnit->setEnabled(setHeight);
357         if (setHeight)
358                 Height->setFocus(Qt::OtherFocusReason);
359
360         bool const setWidth = WidthCB->isChecked();
361         aspectratio->setEnabled(setWidth && setHeight);
362         aspectratio->blockSignals(true);
363         aspectratio->setChecked(!(setWidth && setHeight));
364         aspectratio->blockSignals(false);
365
366         scaleCB->setEnabled(!setWidth && !setHeight);
367         //already unchecked
368         Scale->setEnabled((!setWidth && !setHeight) //=scaleCB->isEnabled()
369                 && scaleCB->isChecked()); //should be false
370         rotateOrderCB->setEnabled((setWidth || setHeight ||
371                                  scaleCB->isChecked()) &&
372                                  (angle->text() != "0"));
373
374         setAutoText();
375 }
376
377
378 void GuiGraphicsDialog::on_angle_textChanged(const QString & filename)
379 {
380         rotateOrderCB->setEnabled((WidthCB->isChecked() ||
381                                  HeightCB->isChecked() ||
382                                  scaleCB->isChecked()) &&
383                                  (filename != "0"));
384 }
385
386 // returns the number of the string s in the vector v
387 static int getItemNo(const vector<string> & v, string const & s)
388 {
389         vector<string>::const_iterator cit =
390                     find(v.begin(), v.end(), s);
391         return (cit != v.end()) ? int(cit - v.begin()) : 0;
392 }
393
394
395 void GuiGraphicsDialog::updateContents()
396 {
397         // clear and fill in the comboboxes
398         vector<string> const bb_units = frontend::getBBUnits();
399         lbXunit->clear();
400         lbYunit->clear();
401         rtXunit->clear();
402         rtYunit->clear();
403         for (vector<string>::const_iterator it = bb_units.begin();
404             it != bb_units.end(); ++it) {
405                 lbXunit->addItem(toqstr(*it));
406                 lbYunit->addItem(toqstr(*it));
407                 rtXunit->addItem(toqstr(*it));
408                 rtYunit->addItem(toqstr(*it));
409         }
410
411         InsetGraphicsParams & igp = controller().params();
412
413         // set the right default unit
414         Length::UNIT unitDefault = Length::CM;
415         switch (lyxrc.default_papersize) {
416                 case PAPER_USLETTER:
417                 case PAPER_USLEGAL:
418                 case PAPER_USEXECUTIVE:
419                         unitDefault = Length::IN;
420                         break;
421                 default:
422                         break;
423         }
424
425         string const name =
426                 igp.filename.outputFilename(controller().bufferFilepath());
427         filename->setText(toqstr(name));
428
429         // set the bounding box values
430         if (igp.bb.empty()) {
431                 string const bb = controller().readBB(igp.filename.absFilename());
432                 // the values from the file always have the bigpoint-unit bp
433                 lbX->setText(toqstr(token(bb, ' ', 0)));
434                 lbY->setText(toqstr(token(bb, ' ', 1)));
435                 rtX->setText(toqstr(token(bb, ' ', 2)));
436                 rtY->setText(toqstr(token(bb, ' ', 3)));
437                 lbXunit->setCurrentIndex(0);
438                 lbYunit->setCurrentIndex(0);
439                 rtXunit->setCurrentIndex(0);
440                 rtYunit->setCurrentIndex(0);
441                 controller().bbChanged = false;
442         } else {
443                 // get the values from the inset
444                 Length anyLength;
445                 string const xl(token(igp.bb, ' ', 0));
446                 string const yl(token(igp.bb, ' ', 1));
447                 string const xr(token(igp.bb, ' ', 2));
448                 string const yr(token(igp.bb, ' ', 3));
449                 if (isValidLength(xl, &anyLength)) {
450                         lbX->setText(toqstr(convert<string>(anyLength.value())));
451                         string const unit(unit_name[anyLength.unit()]);
452                         lbXunit->setCurrentIndex(getItemNo(bb_units, unit));
453                 } else {
454                         lbX->setText(toqstr(xl));
455                 }
456                 if (isValidLength(yl, &anyLength)) {
457                         lbY->setText(toqstr(convert<string>(anyLength.value())));
458                         string const unit(unit_name[anyLength.unit()]);
459                         lbYunit->setCurrentIndex(getItemNo(bb_units, unit));
460                 } else {
461                         lbY->setText(toqstr(xl));
462                 }
463                 if (isValidLength(xr, &anyLength)) {
464                         rtX->setText(toqstr(convert<string>(anyLength.value())));
465                         string const unit(unit_name[anyLength.unit()]);
466                         rtXunit->setCurrentIndex(getItemNo(bb_units, unit));
467                 } else {
468                         rtX->setText(toqstr(xl));
469                 }
470                 if (isValidLength(yr, &anyLength)) {
471                         rtY->setText(toqstr(convert<string>(anyLength.value())));
472                         string const unit(unit_name[anyLength.unit()]);
473                         rtYunit->setCurrentIndex(getItemNo(bb_units, unit));
474                 } else {
475                         rtY->setText(toqstr(xl));
476                 }
477                 controller().bbChanged = true;
478         }
479
480         // Update the draft and clip mode
481         draftCB->setChecked(igp.draft);
482         clip->setChecked(igp.clip);
483         unzipCB->setChecked(igp.noUnzip);
484
485         // Update the subcaption check button and input field
486         subfigure->setChecked(igp.subcaption);
487         subcaption->setText(toqstr(igp.subcaptionText));
488
489         int item = 0;
490         switch (igp.display) {
491                 case graphics::DefaultDisplay: item = 0; break;
492                 case graphics::MonochromeDisplay: item = 1; break;
493                 case graphics::GrayscaleDisplay: item = 2; break;
494                 case graphics::ColorDisplay: item = 3; break;
495                 case graphics::NoDisplay: item = 0; break;
496         }
497         showCB->setCurrentIndex(item);
498         displayscale->setText(toqstr(convert<string>(igp.lyxscale)));
499         displayGB->setChecked(igp.display != graphics::NoDisplay);
500
501         // the output section (width/height)
502
503         Scale->setText(toqstr(igp.scale));
504         //igp.scale defaults to 100, so we treat it as empty
505         bool const scaleChecked = !igp.scale.empty() && igp.scale != "100";
506         scaleCB->blockSignals(true);
507         scaleCB->setChecked(scaleChecked);
508         scaleCB->blockSignals(false);
509         Scale->setEnabled(scaleChecked);
510
511         lengthAutoToWidgets(Width, widthUnit, igp.width,
512                 unitDefault);
513         bool const widthChecked = !Width->text().isEmpty() &&
514                 Width->text() != "auto";
515         WidthCB->blockSignals(true);
516         WidthCB->setChecked(widthChecked);
517         WidthCB->blockSignals(false);
518         Width->setEnabled(widthChecked);
519         widthUnit->setEnabled(widthChecked);
520
521         lengthAutoToWidgets(Height, heightUnit, igp.height,
522                 unitDefault);
523         bool const heightChecked = !Height->text().isEmpty()
524                 && Height->text() != "auto";
525         HeightCB->blockSignals(true);
526         HeightCB->setChecked(heightChecked);
527         HeightCB->blockSignals(false);
528         Height->setEnabled(heightChecked);
529         heightUnit->setEnabled(heightChecked);
530
531         scaleCB->setEnabled(!widthChecked && !heightChecked);
532         WidthCB->setEnabled(!scaleChecked);
533         HeightCB->setEnabled(!scaleChecked);
534         aspectratio->setEnabled(widthChecked && heightChecked);
535
536         setAutoText();
537
538         angle->setText(toqstr(igp.rotateAngle));
539         rotateOrderCB->setChecked(igp.scaleBeforeRotation);
540
541         rotateOrderCB->setEnabled( (widthChecked || heightChecked || scaleChecked)
542                 && igp.rotateAngle != "0");
543
544         origin->clear();
545
546         vector<RotationOriginPair> origindata = getRotationOriginData();
547         vector<docstring> const origin_lang = getFirst(origindata);
548         origin_ltx = getSecond(origindata);
549
550         for (vector<docstring>::const_iterator it = origin_lang.begin();
551             it != origin_lang.end(); ++it)
552                 origin->addItem(toqstr(*it));
553
554         if (!igp.rotateOrigin.empty())
555                 origin->setCurrentIndex(
556                         getItemNo(origin_ltx, igp.rotateOrigin));
557         else
558                 origin->setCurrentIndex(0);
559
560         // disable edit button when no filename is present
561         editPB->setDisabled(filename->text().isEmpty());
562
563         //// latex section
564         latexoptions->setText(toqstr(igp.special));
565 }
566
567
568 void GuiGraphicsDialog::applyView()
569 {
570         InsetGraphicsParams & igp = controller().params();
571
572         igp.filename.set(internal_path(fromqstr(filename->text())),
573                          controller().bufferFilepath());
574
575         // the bb section
576         igp.bb.erase();
577         if (controller().bbChanged) {
578                 string bb;
579                 string lbXs = fromqstr(lbX->text());
580                 string lbYs = fromqstr(lbY->text());
581                 string rtXs = fromqstr(rtX->text());
582                 string rtYs = fromqstr(rtY->text());
583                 int bb_sum =
584                         convert<int>(lbXs) + convert<int>(lbYs) +
585                         convert<int>(rtXs) + convert<int>(rtXs);
586                 if (bb_sum) {
587                         if (lbXs.empty())
588                                 bb = "0 ";
589                         else
590                                 bb = lbXs + fromqstr(lbXunit->currentText()) + ' ';
591                         if (lbYs.empty())
592                                 bb += "0 ";
593                         else
594                                 bb += (lbYs + fromqstr(lbYunit->currentText()) + ' ');
595                         if (rtXs.empty())
596                                 bb += "0 ";
597                         else
598                                 bb += (rtXs + fromqstr(rtXunit->currentText()) + ' ');
599                         if (rtYs.empty())
600                                 bb += '0';
601                         else
602                                 bb += (rtYs + fromqstr(rtYunit->currentText()));
603                         igp.bb = bb;
604                 }
605         }
606
607         igp.draft = draftCB->isChecked();
608         igp.clip = clip->isChecked();
609         igp.subcaption = subfigure->isChecked();
610         igp.subcaptionText = fromqstr(subcaption->text());
611
612         switch (showCB->currentIndex()) {
613                 case 0: igp.display = graphics::DefaultDisplay; break;
614                 case 1: igp.display = graphics::MonochromeDisplay; break;
615                 case 2: igp.display = graphics::GrayscaleDisplay; break;
616                 case 3: igp.display = graphics::ColorDisplay; break;
617                 default:;
618         }
619
620         if (!displayGB->isChecked())
621                 igp.display = graphics::NoDisplay;
622
623         //the graphics section
624         if (scaleCB->isChecked() && !Scale->text().isEmpty()) {
625                 igp.scale = fromqstr(Scale->text());
626                 igp.width = Length("0pt");
627                 igp.height = Length("0pt");
628                 igp.keepAspectRatio = false;
629         } else {
630                 igp.scale = string();
631                 igp.width = WidthCB->isChecked() ?
632                         //Note that this works even if Width is "auto", since in
633                         //that case we get "0pt".
634                         Length(widgetsToLength(Width, widthUnit)):
635                         Length("0pt");
636                 igp.height = HeightCB->isChecked() ?
637                         Length(widgetsToLength(Height, heightUnit)) :
638                         Length("0pt");
639                 igp.keepAspectRatio = aspectratio->isEnabled() &&
640                         aspectratio->isChecked() &&
641                         igp.width.value() > 0 && igp.height.value() > 0;
642         }
643
644         igp.noUnzip = unzipCB->isChecked();
645         igp.lyxscale = displayscale->text().toInt();
646         igp.rotateAngle = fromqstr(angle->text());
647
648         double rotAngle = convert<double>(igp.rotateAngle);
649         if (std::abs(rotAngle) > 360.0) {
650                 rotAngle -= 360.0 * floor(rotAngle / 360.0);
651                 igp.rotateAngle = convert<string>(rotAngle);
652         }
653
654         // save the latex name for the origin. If it is the default
655         // then origin_ltx returns ""
656         igp.rotateOrigin = origin_ltx[origin->currentIndex()];
657         igp.scaleBeforeRotation = rotateOrderCB->isChecked();
658
659         // more latex options
660         igp.special = fromqstr(latexoptions->text());
661 }
662
663
664 void GuiGraphicsDialog::getBB()
665 {
666         string const fn = fromqstr(filename->text());
667         if (!fn.empty()) {
668                 string const bb = controller().readBB(fn);
669                 if (!bb.empty()) {
670                         lbX->setText(toqstr(token(bb, ' ', 0)));
671                         lbY->setText(toqstr(token(bb, ' ', 1)));
672                         rtX->setText(toqstr(token(bb, ' ', 2)));
673                         rtY->setText(toqstr(token(bb, ' ', 3)));
674                         // the default units for the bb values when reading
675                         // it from the file
676                         lbXunit->setCurrentIndex(0);
677                         lbYunit->setCurrentIndex(0);
678                         rtXunit->setCurrentIndex(0);
679                         rtYunit->setCurrentIndex(0);
680                 }
681                 controller().bbChanged = false;
682         }
683 }
684
685
686 bool GuiGraphicsDialog::isValid()
687 {
688         return !filename->text().isEmpty();
689 }
690
691 } // namespace frontend
692 } // namespace lyx
693
694
695 #include "GuiGraphics_moc.cpp"
696