3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
10 * Full author contact details are available in file CREDITS
16 #pragma implementation
19 #include "QtLyXView.h"
20 #include "ControlGraphics.h"
21 #include "controllers/helper_funcs.h"
22 #include "support/lstrings.h"
23 #include "support/FileInfo.h"
24 #include "support/filetools.h"
25 #include "insets/insetgraphicsParams.h"
27 #include "lengthcombo.h"
29 #include "lengthcommon.h"
30 #include "lyxlength.h"
33 #include <qlineedit.h>
34 #include <qpushbutton.h>
35 #include <qcheckbox.h>
36 #include <qradiobutton.h>
37 #include <qcombobox.h>
38 #include <qgroupbox.h>
39 #include <qbuttongroup.h>
42 #include "QGraphicsDialog.h"
43 #include "QGraphics.h"
48 typedef Qt2CB<ControlGraphics, Qt2DB<QGraphicsDialog> > base_class;
51 QGraphics::QGraphics()
52 : base_class(_("Graphics"))
57 void QGraphics::build_dialog()
59 dialog_.reset(new QGraphicsDialog(this));
61 bc().setOK(dialog_->okPB);
62 bc().setApply(dialog_->applyPB);
63 bc().setRestore(dialog_->restorePB);
64 bc().setCancel(dialog_->closePB);
66 bc().addReadOnly(dialog_->rotateGB);
67 bc().addReadOnly(dialog_->latexoptions);
68 bc().addReadOnly(dialog_->subfigure);
69 bc().addReadOnly(dialog_->subcaption);
70 bc().addReadOnly(dialog_->filenameL);
71 bc().addReadOnly(dialog_->filename);
72 bc().addReadOnly(dialog_->browsePB);
73 bc().addReadOnly(dialog_->unzipCB);
74 bc().addReadOnly(dialog_->filename);
75 bc().addReadOnly(dialog_->lbX);
76 bc().addReadOnly(dialog_->lbY);
77 bc().addReadOnly(dialog_->rtX);
78 bc().addReadOnly(dialog_->rtY);
79 bc().addReadOnly(dialog_->lbXunit);
80 bc().addReadOnly(dialog_->lbYunit);
81 bc().addReadOnly(dialog_->rtXunit);
82 bc().addReadOnly(dialog_->rtYunit);
83 bc().addReadOnly(dialog_->draftCB);
84 bc().addReadOnly(dialog_->clip);
85 bc().addReadOnly(dialog_->unzipCB);
86 bc().addReadOnly(dialog_->subfigure);
87 bc().addReadOnly(dialog_->subcaption);
88 bc().addReadOnly(dialog_->showCB);
89 bc().addReadOnly(dialog_->width);
90 bc().addReadOnly(dialog_->height);
91 bc().addReadOnly(dialog_->displayCB);
92 bc().addReadOnly(dialog_->displayscale);
93 bc().addReadOnly(dialog_->widthUnit);
94 bc().addReadOnly(dialog_->heightUnit);
95 bc().addReadOnly(dialog_->aspectratio);
96 bc().addReadOnly(dialog_->angle);
97 bc().addReadOnly(dialog_->origin);
98 bc().addReadOnly(dialog_->latexoptions);
99 bc().addReadOnly(dialog_->getPB);
101 using namespace frnt;
102 vector<RotationOriginPair> origindata = getRotationOriginData();
103 vector<string> const origin_lang = getFirst(origindata);
104 origin_ltx = getSecond(origindata);
106 for (vector<string>::const_iterator it = origin_lang.begin();
107 it != origin_lang.end(); ++it) {
108 dialog_->origin->insertItem((*it).c_str(), -1);
111 // clear and fill in the comboboxes
112 vector<string> const bb_units = getBBUnits();
113 dialog_->lbXunit->clear();
114 dialog_->lbYunit->clear();
115 dialog_->rtXunit->clear();
116 dialog_->rtYunit->clear();
117 for (vector<string>::const_iterator it = bb_units.begin();
118 it != bb_units.end(); ++it) {
119 dialog_->lbXunit->insertItem((*it).c_str(), -1);
120 dialog_->lbYunit->insertItem((*it).c_str(), -1);
121 dialog_->rtXunit->insertItem((*it).c_str(), -1);
122 dialog_->rtYunit->insertItem((*it).c_str(), -1);
130 // returns the number of the string s in the vector v
131 int getItemNo(vector<string> v, string const & s) {
132 vector<string>::const_iterator cit =
133 find(v.begin(), v.end(), s);
135 return int(cit - v.begin());
140 // returns the number of the unit in the array unit_name,
141 // which is defined in lengthcommon.C
142 int getUnitNo(string const & s) {
144 while (i < num_units && s != unit_name[i])
146 return (i < num_units) ? i : 0;
152 void QGraphics::update_contents()
154 InsetGraphicsParams & igp = controller().params();
156 // set the right default unit
157 string unitDefault("cm");
158 switch (lyxrc.default_papersize) {
159 case BufferParams::PAPER_DEFAULT: break;
161 case BufferParams::PAPER_USLETTER:
162 case BufferParams::PAPER_LEGALPAPER:
163 case BufferParams::PAPER_EXECUTIVEPAPER:
167 case BufferParams::PAPER_A3PAPER:
168 case BufferParams::PAPER_A4PAPER:
169 case BufferParams::PAPER_A5PAPER:
170 case BufferParams::PAPER_B5PAPER:
175 dialog_->filename->setText(igp.filename.c_str());
177 // set the bounding box values
178 if (igp.bb.empty()) {
179 controller().bbChanged = false;
180 string const bb = controller().readBB(igp.filename);
181 // the values from the file always have the point-unit
182 dialog_->lbX->setText(token(bb, ' ', 0).c_str());
183 dialog_->lbY->setText(token(bb, ' ', 1).c_str());
184 dialog_->rtX->setText(token(bb, ' ', 2).c_str());
185 dialog_->rtY->setText(token(bb, ' ', 3).c_str());
187 // get the values from the inset
188 controller().bbChanged = true;
189 vector<string> const bb_units = frnt::getBBUnits();
191 string const xl(token(igp.bb,' ',0));
192 string const yl(token(igp.bb,' ',1));
193 string const xr(token(igp.bb,' ',2));
194 string const yr(token(igp.bb,' ',3));
195 if (isValidLength(xl, &anyLength)) {
196 dialog_->lbX->setText(tostr(anyLength.value()).c_str());
197 string const unit(unit_name[anyLength.unit()]);
198 dialog_->lbXunit->setCurrentItem(getItemNo(bb_units, unit));
200 dialog_->lbX->setText(xl.c_str());
202 if (isValidLength(yl, &anyLength)) {
203 dialog_->lbY->setText(tostr(anyLength.value()).c_str());
204 string const unit(unit_name[anyLength.unit()]);
205 dialog_->lbYunit->setCurrentItem(getItemNo(bb_units, unit));
207 dialog_->lbY->setText(xl.c_str());
209 if (isValidLength(xr, &anyLength)) {
210 dialog_->rtX->setText(tostr(anyLength.value()).c_str());
211 string const unit(unit_name[anyLength.unit()]);
212 dialog_->rtXunit->setCurrentItem(getItemNo(bb_units, unit));
214 dialog_->rtX->setText(xl.c_str());
216 if (isValidLength(yr, &anyLength)) {
217 dialog_->rtY->setText(tostr(anyLength.value()).c_str());
218 string const unit(unit_name[anyLength.unit()]);
219 dialog_->rtYunit->setCurrentItem(getItemNo(bb_units, unit));
221 dialog_->rtY->setText(xl.c_str());
225 // Update the draft and clip mode
226 dialog_->draftCB->setChecked(igp.draft);
227 dialog_->clip->setChecked(igp.clip);
228 dialog_->unzipCB->setChecked(igp.noUnzip);
230 // Update the subcaption check button and input field
231 dialog_->subfigure->setChecked(igp.subcaption);
232 dialog_->subcaption->setText(igp.subcaptionText.c_str());
235 switch (igp.display) {
236 case grfx::DefaultDisplay: item = 0; break;
237 case grfx::MonochromeDisplay: item = 1; break;
238 case grfx::GrayscaleDisplay: item = 2; break;
239 case grfx::ColorDisplay: item = 3; break;
240 case grfx::NoDisplay: item = 0; break;
242 dialog_->showCB->setCurrentItem(item);
243 dialog_->showCB->setEnabled(igp.display != grfx::NoDisplay && !readOnly());
244 dialog_->displayCB->setChecked(igp.display != grfx::NoDisplay);
245 dialog_->displayscale->setEnabled(igp.display != grfx::NoDisplay && !readOnly());
246 dialog_->displayscale->setText(tostr(igp.lyxscale).c_str());
248 // the output section
249 // set the length combo boxes
250 // only the width has the possibility for scale%. The original
251 // units are defined in lengthcommon.C
252 dialog_->widthUnit->insertItem("Scale%");
253 for (int i = 0; i < num_units; i++) {
254 dialog_->widthUnit->insertItem(unit_name[i], -1);
255 dialog_->heightUnit->insertItem(unit_name[i], -1);
257 if (!lyx::float_equal(igp.scale, 0.0, 0.05)) {
258 // there is a scale value > 0.05
259 dialog_->width->setText(tostr(igp.scale).c_str());
260 dialog_->widthUnit->setCurrentItem(0);
262 // no scale means default width/height
263 dialog_->width->setText(tostr(igp.width.value()).c_str());
264 string const widthUnit = (igp.width.value() > 0.0) ?
265 unit_name[igp.width.unit()] : unitDefault;
266 // +1 instead of the "Scale%" option
267 dialog_->widthUnit->setCurrentItem(getUnitNo(widthUnit) + 1);
269 dialog_->height->setText(tostr(igp.height.value()).c_str());
270 string const heightUnit = (igp.height.value() > 0.0) ?
271 unit_name[igp.height.unit()] : unitDefault;
272 dialog_->heightUnit->setCurrentItem(getUnitNo(heightUnit));
274 // enable height input in case of non "Scale%" as width-unit
275 bool use_height = (dialog_->widthUnit->currentItem() > 0);
276 dialog_->height->setEnabled(use_height);
277 dialog_->heightUnit->setEnabled(use_height);
279 dialog_->aspectratio->setChecked(igp.keepAspectRatio);
281 dialog_->angle->setText(tostr(igp.rotateAngle).c_str());
283 if (!igp.rotateOrigin.empty())
284 dialog_->origin->setCurrentItem(
285 ::getItemNo(origin_ltx, igp.rotateOrigin));
288 dialog_->latexoptions->setText(igp.special.c_str());
292 void QGraphics::apply()
294 InsetGraphicsParams & igp = controller().params();
296 igp.filename = dialog_->filename->text();
299 if (!controller().bbChanged) {
300 // don't write anything
302 } else if (dialog_->clip->isChecked()) {
304 string lbX(dialog_->lbX->text());
305 string lbY(dialog_->lbY->text());
306 string rtX(dialog_->rtX->text());
307 string rtY(dialog_->rtY->text());
312 bb = lbX + dialog_->lbXunit->currentText().latin1() + ' ';
316 bb += (lbY + dialog_->lbYunit->currentText().latin1() + ' ');
320 bb += (rtX + dialog_->rtXunit->currentText().latin1() + ' ');
324 bb += (rtY + dialog_->rtYunit->currentText().latin1());
328 igp.draft = dialog_->draftCB->isChecked();
329 igp.clip = dialog_->clip->isChecked();
330 igp.subcaption = dialog_->subfigure->isChecked();
331 igp.subcaptionText = dialog_->subcaption->text();
333 switch (dialog_->showCB->currentItem()) {
334 case 0: igp.display = grfx::DefaultDisplay; break;
335 case 1: igp.display = grfx::MonochromeDisplay; break;
336 case 2: igp.display = grfx::GrayscaleDisplay; break;
337 case 3: igp.display = grfx::ColorDisplay; break;
341 if (!dialog_->displayCB->isChecked())
342 igp.display = grfx::NoDisplay;
344 string value(dialog_->width->text());
345 if (dialog_->widthUnit->currentItem() > 0) {
346 // width/height combination
347 string const unit(dialog_->widthUnit->currentText());
348 igp.width = LyXLength(value + unit);
351 // scaling instead of a width
352 igp.scale = strToDbl(value);
353 igp.width = LyXLength();
355 value = string(dialog_->height->text());
356 string const unit = string(dialog_->heightUnit->currentText());
357 igp.height = LyXLength(value + unit);
359 igp.keepAspectRatio = dialog_->aspectratio->isChecked();
361 igp.noUnzip = dialog_->unzipCB->isChecked();
363 igp.lyxscale = strToInt(string(dialog_->displayscale->text()));
365 igp.rotateAngle = strToDbl(string(dialog_->angle->text()));
366 while (igp.rotateAngle < -360.0)
367 igp.rotateAngle += 360.0;
368 while (igp.rotateAngle > 360.0)
369 igp.rotateAngle -= 360.0;
371 // save the latex name for the origin. If it is the default
372 // then origin_ltx returns ""
373 igp.rotateOrigin = origin_ltx[dialog_->origin->currentItem()];
375 // more latex options
376 igp.special = dialog_->latexoptions->text();
380 void QGraphics::getBB()
382 string const filename(dialog_->filename->text());
383 if (!filename.empty()) {
384 string const bb(controller().readBB(filename));
386 dialog_->lbX->setText(token(bb, ' ', 0).c_str());
387 dialog_->lbY->setText(token(bb, ' ', 1).c_str());
388 dialog_->rtX->setText(token(bb, ' ', 2).c_str());
389 dialog_->rtY->setText(token(bb, ' ', 3).c_str());
390 // the default units for the bb values when reading
392 dialog_->lbXunit->setCurrentItem(0);
393 dialog_->lbYunit->setCurrentItem(0);
394 dialog_->rtXunit->setCurrentItem(0);
395 dialog_->rtYunit->setCurrentItem(0);
397 controller().bbChanged = false;
402 bool QGraphics::isValid()
404 // FIXME: we need more here.
405 // why?? LaTeX needs a filename, the rest is user-specific (Herbert)
406 return !string(dialog_->filename->text().latin1()).empty();