]> git.lyx.org Git - lyx.git/blob - src/frontends/qt2/QGraphics.C
another compile fix from herbert
[lyx.git] / src / frontends / qt2 / QGraphics.C
1 /**
2  * \file QGraphics.C
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 Voss
9  *
10  * Full author contact details are available in file CREDITS
11  */
12
13 #include <config.h>
14
15 #ifdef __GNUG__
16 #pragma implementation
17 #endif
18
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"
26 #include "lyxrc.h"
27 #include "lengthcombo.h"
28 #include "gettext.h"
29 #include "lengthcommon.h"
30 #include "lyxlength.h"
31 #include "debug.h"
32
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>
40 #include <qlabel.h>
41
42 #include "QGraphicsDialog.h"
43 #include "QGraphics.h"
44 #include "Qt2BC.h"
45
46 using std::vector;
47
48 typedef Qt2CB<ControlGraphics, Qt2DB<QGraphicsDialog> > base_class;
49
50
51 QGraphics::QGraphics()
52         : base_class(_("Graphics"))
53 {
54 }
55
56
57 void QGraphics::build_dialog()
58 {
59         dialog_.reset(new QGraphicsDialog(this));
60
61         bc().setOK(dialog_->okPB);
62         bc().setApply(dialog_->applyPB);
63         bc().setRestore(dialog_->restorePB);
64         bc().setCancel(dialog_->closePB);
65
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);
100  
101         using namespace frnt;
102         vector<RotationOriginPair> origindata = getRotationOriginData();
103         vector<string> const origin_lang = getFirst(origindata);
104         origin_ltx = getSecond(origindata);
105         // build the list
106         for (vector<string>::const_iterator it = origin_lang.begin();
107             it != origin_lang.end(); ++it) {
108                 dialog_->origin->insertItem((*it).c_str(), -1);
109         } 
110  
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);
123         }
124         
125 }
126
127
128 namespace {
129  
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);
134         if (cit != v.end())
135                 return int(cit - v.begin());
136  
137         return 0;
138 }
139  
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) {
143         int i = 0;
144         while (i < num_units && s != unit_name[i])
145                 ++i;
146         return (i < num_units) ? i : 0;
147 }
148  
149 }
150
151
152 void QGraphics::update_contents()
153 {
154         InsetGraphicsParams & igp = controller().params();
155
156         // set the right default unit
157         string unitDefault("cm");
158         switch (lyxrc.default_papersize) {
159                 case BufferParams::PAPER_DEFAULT: break;
160
161                 case BufferParams::PAPER_USLETTER:
162                 case BufferParams::PAPER_LEGALPAPER:
163                 case BufferParams::PAPER_EXECUTIVEPAPER:
164                         unitDefault = "in";
165                         break;
166
167                 case BufferParams::PAPER_A3PAPER:
168                 case BufferParams::PAPER_A4PAPER:
169                 case BufferParams::PAPER_A5PAPER:
170                 case BufferParams::PAPER_B5PAPER:
171                         unitDefault = "cm";
172                         break;
173         }
174
175         dialog_->filename->setText(igp.filename.c_str());
176
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());
186         } else {
187                 // get the values from the inset
188                 controller().bbChanged = true;
189                 vector<string> const bb_units = frnt::getBBUnits();
190                 LyXLength anyLength;
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));
199                 } else {
200                         dialog_->lbX->setText(xl.c_str());
201                 }
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));
206                 } else {
207                         dialog_->lbY->setText(xl.c_str());
208                 }
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));
213                 } else {
214                         dialog_->rtX->setText(xl.c_str());
215                 }
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));
220                 } else {
221                         dialog_->rtY->setText(xl.c_str());
222                 }
223         }
224
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);
229
230         // Update the subcaption check button and input field
231         dialog_->subfigure->setChecked(igp.subcaption);
232         dialog_->subcaption->setText(igp.subcaptionText.c_str());
233
234         int item = 0;
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;
241         }
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());
247
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);
256         }
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);
261         } else {
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);
268         }
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));
273
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);
278
279         dialog_->aspectratio->setChecked(igp.keepAspectRatio);
280
281         dialog_->angle->setText(tostr(igp.rotateAngle).c_str());
282
283         if (!igp.rotateOrigin.empty())
284                 dialog_->origin->setCurrentItem(
285                         ::getItemNo(origin_ltx, igp.rotateOrigin));
286
287         //// latex section 
288         dialog_->latexoptions->setText(igp.special.c_str());
289 }
290
291
292 void QGraphics::apply()
293 {
294         InsetGraphicsParams & igp = controller().params();
295
296         igp.filename = dialog_->filename->text();
297
298         // the bb section
299         if (!controller().bbChanged) {
300                 // don't write anything         
301                 igp.bb.erase();
302         } else if (dialog_->clip->isChecked()) {
303                 string bb;
304                 string lbX(dialog_->lbX->text());
305                 string lbY(dialog_->lbY->text());
306                 string rtX(dialog_->rtX->text());
307                 string rtY(dialog_->rtY->text());
308
309                 if (lbX.empty())
310                         bb = "0 ";
311                 else
312                         bb = lbX + dialog_->lbXunit->currentText().latin1() + ' ';
313                 if (lbY.empty())
314                         bb += "0 ";
315                 else 
316                         bb += (lbY + dialog_->lbYunit->currentText().latin1() + ' ');
317                 if (rtX.empty())
318                         bb += "0 ";
319                 else 
320                         bb += (rtX + dialog_->rtXunit->currentText().latin1() + ' ');
321                 if (rtY.empty())
322                         bb += "0";
323                 else 
324                         bb += (rtY + dialog_->rtYunit->currentText().latin1());
325                 igp.bb = bb;
326         }
327
328         igp.draft = dialog_->draftCB->isChecked();
329         igp.clip = dialog_->clip->isChecked();
330         igp.subcaption = dialog_->subfigure->isChecked();
331         igp.subcaptionText = dialog_->subcaption->text();
332
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;
338                 default:;
339         }
340
341         if (!dialog_->displayCB->isChecked())
342                 igp.display = grfx::NoDisplay;
343
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); 
349                 igp.scale = 0.0; 
350         } else {
351                 // scaling instead of a width
352                 igp.scale = strToDbl(value); 
353                 igp.width = LyXLength(); 
354         }
355         value = string(dialog_->height->text());
356         string const unit = string(dialog_->heightUnit->currentText());
357         igp.height = LyXLength(value + unit);
358
359         igp.keepAspectRatio = dialog_->aspectratio->isChecked();
360
361         igp.noUnzip = dialog_->unzipCB->isChecked();
362
363         igp.lyxscale = strToInt(string(dialog_->displayscale->text()));
364
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;
370
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()];
374         
375         // more latex options
376         igp.special = dialog_->latexoptions->text();
377 }
378
379
380 void QGraphics::getBB()
381 {
382         string const filename(dialog_->filename->text());
383         if (!filename.empty()) {
384                 string const bb(controller().readBB(filename));
385                 if (!bb.empty()) {
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
391                         // it from the file
392                         dialog_->lbXunit->setCurrentItem(0);
393                         dialog_->lbYunit->setCurrentItem(0);
394                         dialog_->rtXunit->setCurrentItem(0);
395                         dialog_->rtYunit->setCurrentItem(0);
396                 }
397                 controller().bbChanged = false;
398         }
399 }
400
401
402 bool QGraphics::isValid()
403 {
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();
407 }