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