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