2 * \file GuiGraphics.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Angus Leeming
10 * \author Richard Heck
12 * Full author contact details are available in file CREDITS.
17 #include "GuiGraphics.h"
19 #include "LengthCombo.h"
22 #include "qt_helpers.h"
23 #include "Validator.h"
25 #include "FuncRequest.h"
27 #include "graphics/GraphicsCache.h"
28 #include "graphics/GraphicsCacheItem.h"
29 #include "graphics/GraphicsImage.h"
31 #include "insets/InsetGraphicsParams.h"
33 #include "support/convert.h"
34 #include "support/debug.h"
35 #include "support/FileFilterList.h"
36 #include "support/filetools.h"
37 #include "support/gettext.h"
38 #include "support/lstrings.h"
39 #include "support/os.h"
40 #include "support/Package.h"
41 #include "support/types.h"
46 #include <QPushButton>
53 using namespace lyx::support;
58 //FIXME setAutoTextCB should really take an argument, as indicated, that
59 //determines what text is to be written for "auto". But making
60 //that work involves more extensive revisions than we now want
61 //to make, since "auto" also appears in updateContents() (see
63 //The right way to do this, I think, would be to define a class
64 //checkedLengthSet (and a partnering labeledLengthSete) that encapsulated
65 //the checkbox, line edit, and length combo together, and then made e.g.
66 //lengthToWidgets, widgetsToLength, etc, all public methods of that class.
67 //Perhaps even the validator could be exposed through it.
69 * sets a checkbox-line edit-length combo group, using "text" if the
70 * checkbox is unchecked and clearing the line edit if it previously
73 static void setAutoTextCB(QCheckBox * checkBox, QLineEdit * lineEdit,
74 LengthCombo * lengthCombo/*, string text = "auto"*/)
76 if (!checkBox->isChecked())
77 lengthToWidgets(lineEdit, lengthCombo,
78 "auto", lengthCombo->currentLengthItem());
79 else if (lineEdit->text() == "auto")
80 lengthToWidgets(lineEdit, lengthCombo, string(),
81 lengthCombo->currentLengthItem());
86 vector<typename Pair::first_type> getFirst(vector<Pair> const & pr)
88 size_t const n = pr.size();
89 vector<typename Pair::first_type> tmp(n);
90 for (size_t i = 0; i != n; ++i)
98 vector<typename Pair::second_type> getSecond(vector<Pair> const & pr)
100 size_t const n = pr.size();
101 vector<typename Pair::second_type> tmp(n);
102 for (size_t i = 0; i != n; ++i)
103 tmp[i] = pr[i].second;
108 /// The (tranlated) GUI string and it's LaTeX equivalent.
109 typedef pair<docstring, string> RotationOriginPair;
111 vector<RotationOriginPair> getRotationOriginData();
114 GuiGraphics::GuiGraphics(GuiView & lv)
115 : GuiDialog(lv, "graphics", qt_("Graphics"))
120 connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
121 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
122 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
123 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
126 connect(filename, SIGNAL(textChanged(const QString &)),
127 this, SLOT(change_adaptor()));
128 connect(WidthCB, SIGNAL( clicked()),
129 this, SLOT(change_adaptor()));
130 connect(HeightCB, SIGNAL( clicked()),
131 this, SLOT(change_adaptor()));
132 connect(Width, SIGNAL(textChanged(const QString &)),
133 this, SLOT(change_adaptor()));
134 connect(Height, SIGNAL(textChanged(const QString &)),
135 this, SLOT(change_adaptor()));
136 connect(heightUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
137 this, SLOT(change_adaptor()));
138 connect(widthUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
139 this, SLOT(change_adaptor()));
140 connect(aspectratio, SIGNAL(stateChanged(int)),
141 this, SLOT(change_adaptor()));
142 connect(angle, SIGNAL(textChanged(const QString &)),
143 this, SLOT(change_adaptor()));
144 connect(origin, SIGNAL(activated(int)),
145 this, SLOT(change_adaptor()));
146 connect(scaleCB, SIGNAL(clicked()),
147 this, SLOT(change_adaptor()));
148 connect(Scale, SIGNAL(textChanged(const QString &)),
149 this, SLOT(change_adaptor()));
150 connect(rotateOrderCB, SIGNAL(clicked()),
151 this, SLOT(change_adaptor()));
153 filename->setValidator(new PathValidator(true, filename));
154 setFocusProxy(filename);
156 QDoubleValidator * scaleValidator = new DoubleAutoValidator(Scale);
157 scaleValidator->setBottom(0);
158 scaleValidator->setDecimals(256); //I guess that will do
159 Scale->setValidator(scaleValidator);
160 Height->setValidator(unsignedLengthAutoValidator(Height));
161 Width->setValidator(unsignedLengthAutoValidator(Width));
162 angle->setValidator(new QDoubleValidator(-360, 360, 2, angle));
165 connect(clip, SIGNAL(stateChanged(int)),
166 this, SLOT(change_adaptor()));
167 connect(lbY, SIGNAL(textChanged(const QString&)),
168 this, SLOT(change_bb()));
169 connect(lbYunit, SIGNAL(activated(int)),
170 this, SLOT(change_bb()));
171 connect(rtY, SIGNAL(textChanged(const QString&)),
172 this, SLOT(change_bb()));
173 connect(rtYunit, SIGNAL(activated(int)),
174 this, SLOT(change_bb()));
175 connect(lbX, SIGNAL(textChanged(const QString&)),
176 this, SLOT(change_bb()));
177 connect(lbXunit, SIGNAL(activated(int)),
178 this, SLOT(change_bb()));
179 connect(rtX, SIGNAL(textChanged(const QString&)),
180 this, SLOT(change_bb()));
181 connect(rtXunit, SIGNAL(activated(int)),
182 this, SLOT(change_bb()));
183 connect(getPB, SIGNAL(clicked()),
184 this, SLOT(change_adaptor()));
186 lbX->setValidator(new QDoubleValidator(lbX));
187 lbY->setValidator(new QDoubleValidator(lbY));
188 rtX->setValidator(new QDoubleValidator(rtX));
189 rtY->setValidator(new QDoubleValidator(rtY));
192 connect(latexoptions, SIGNAL(textChanged(const QString&)),
193 this, SLOT(change_adaptor()));
194 connect(draftCB, SIGNAL(stateChanged(int)),
195 this, SLOT(change_adaptor()));
196 connect(unzipCB, SIGNAL(stateChanged(int)),
197 this, SLOT(change_adaptor()));
198 // FIXME: we should connect to clicked() when we move to Qt 4.2 because
199 // the toggled(bool) signal is also trigged when we update the widgets
200 // (rgh-4/07) this isn't as much or a problem as it was, because we're now
201 // using blockSignals() to keep from triggering that signal when we call
202 // setChecked(). Note, too, that clicked() would get called whenever it
203 // is clicked, even right clicked (I think), not just whenever it is
205 connect(displayGB, SIGNAL(toggled(bool)),
206 this, SLOT(change_adaptor()));
207 connect(showCB, SIGNAL(currentIndexChanged(int)),
208 this, SLOT(change_adaptor()));
209 connect(displayscale, SIGNAL(textChanged(const QString&)),
210 this, SLOT(change_adaptor()));
211 displayscale->setValidator(new QIntValidator(displayscale));
213 bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
215 bc().setApply(applyPB);
216 bc().setRestore(restorePB);
217 bc().setCancel(closePB);
219 bc().addReadOnly(latexoptions);
220 bc().addReadOnly(filenameL);
221 bc().addReadOnly(filename);
222 bc().addReadOnly(browsePB);
223 bc().addReadOnly(unzipCB);
224 bc().addReadOnly(bbFrame);
225 bc().addReadOnly(draftCB);
226 bc().addReadOnly(clip);
227 bc().addReadOnly(unzipCB);
228 bc().addReadOnly(displayGB);
229 bc().addReadOnly(sizeGB);
230 bc().addReadOnly(rotationGB);
231 bc().addReadOnly(latexoptions);
232 bc().addReadOnly(getPB);
233 bc().addReadOnly(rotateOrderCB);
235 // initialize the length validator
236 bc().addCheckedLineEdit(Scale, scaleCB);
237 bc().addCheckedLineEdit(Width, WidthCB);
238 bc().addCheckedLineEdit(Height, HeightCB);
239 bc().addCheckedLineEdit(displayscale, scaleLA);
240 bc().addCheckedLineEdit(angle, angleL);
241 bc().addCheckedLineEdit(lbX, xL);
242 bc().addCheckedLineEdit(lbY, yL);
243 bc().addCheckedLineEdit(rtX, xL_2);
244 bc().addCheckedLineEdit(rtY, yL_2);
245 bc().addCheckedLineEdit(filename, filenameL);
249 void GuiGraphics::change_adaptor()
255 void GuiGraphics::change_bb()
258 LYXERR(Debug::GRAPHICS, "[bb_Changed set to true]");
263 void GuiGraphics::on_browsePB_clicked()
265 QString const str = browse(filename->text());
266 if (!str.isEmpty()) {
267 filename->setText(str);
273 void GuiGraphics::on_getPB_clicked()
279 void GuiGraphics::on_filename_textChanged(const QString & filename)
281 EmbeddedFile file = EmbeddedFile(fromqstr(filename), fromqstr(bufferFilepath()));
285 void GuiGraphics::setAutoText()
287 if (scaleCB->isChecked())
289 if (!Scale->isEnabled() && Scale->text() != "100")
290 Scale->setText(QString("auto"));
292 setAutoTextCB(WidthCB, Width, widthUnit);
293 setAutoTextCB(HeightCB, Height, heightUnit);
297 void GuiGraphics::on_scaleCB_toggled(bool setScale)
299 Scale->setEnabled(setScale);
301 Scale->setText("100");
302 Scale->setFocus(Qt::OtherFocusReason);
305 WidthCB->setDisabled(setScale);
306 WidthCB->blockSignals(true);
307 WidthCB->setChecked(false);
308 WidthCB->blockSignals(false);
309 Width->setEnabled(false);
310 widthUnit->setEnabled(false);
312 HeightCB->setDisabled(setScale);
313 HeightCB->blockSignals(true);
314 HeightCB->setChecked(false);
315 HeightCB->blockSignals(false);
316 Height->setEnabled(false);
317 heightUnit->setEnabled(false);
319 aspectratio->setDisabled(true);
320 aspectratio->setChecked(true);
322 rotateOrderCB->setEnabled((WidthCB->isChecked() ||
323 HeightCB->isChecked() ||
324 scaleCB->isChecked()) &&
325 (angle->text() != "0"));
331 void GuiGraphics::on_WidthCB_toggled(bool setWidth)
333 Width->setEnabled(setWidth);
334 widthUnit->setEnabled(setWidth);
336 Width->setFocus(Qt::OtherFocusReason);
338 bool const setHeight = HeightCB->isChecked();
339 aspectratio->setEnabled(setWidth && setHeight);
340 aspectratio->blockSignals(true);
341 aspectratio->setChecked(!(setWidth && setHeight));
342 aspectratio->blockSignals(false);
344 scaleCB->setEnabled(!setWidth && !setHeight);
345 //already will be unchecked, so don't need to do that
346 Scale->setEnabled((!setWidth && !setHeight) //=scaleCB->isEnabled()
347 && scaleCB->isChecked()); //should be false, but let's check
348 rotateOrderCB->setEnabled((setWidth || setHeight ||
349 scaleCB->isChecked()) &&
350 (angle->text() != "0"));
356 void GuiGraphics::on_HeightCB_toggled(bool setHeight)
358 Height->setEnabled(setHeight);
359 heightUnit->setEnabled(setHeight);
361 Height->setFocus(Qt::OtherFocusReason);
363 bool const setWidth = WidthCB->isChecked();
364 aspectratio->setEnabled(setWidth && setHeight);
365 aspectratio->blockSignals(true);
366 aspectratio->setChecked(!(setWidth && setHeight));
367 aspectratio->blockSignals(false);
369 scaleCB->setEnabled(!setWidth && !setHeight);
371 Scale->setEnabled((!setWidth && !setHeight) //=scaleCB->isEnabled()
372 && scaleCB->isChecked()); //should be false
373 rotateOrderCB->setEnabled((setWidth || setHeight ||
374 scaleCB->isChecked()) &&
375 (angle->text() != "0"));
381 void GuiGraphics::on_angle_textChanged(const QString & filename)
383 rotateOrderCB->setEnabled((WidthCB->isChecked() ||
384 HeightCB->isChecked() ||
385 scaleCB->isChecked()) &&
389 // returns the number of the string s in the vector v
390 static int getItemNo(const vector<string> & v, string const & s)
392 vector<string>::const_iterator cit =
393 find(v.begin(), v.end(), s);
394 return (cit != v.end()) ? int(cit - v.begin()) : 0;
398 void GuiGraphics::updateContents()
400 // clear and fill in the comboboxes
401 vector<string> const bb_units = frontend::getBBUnits();
406 for (vector<string>::const_iterator it = bb_units.begin();
407 it != bb_units.end(); ++it) {
408 lbXunit->addItem(toqstr(*it));
409 lbYunit->addItem(toqstr(*it));
410 rtXunit->addItem(toqstr(*it));
411 rtYunit->addItem(toqstr(*it));
414 InsetGraphicsParams & igp = params_;
416 // set the right default unit
417 Length::UNIT unitDefault = Length::CM;
418 switch (lyxrc.default_papersize) {
421 case PAPER_USEXECUTIVE:
422 unitDefault = Length::IN;
429 igp.filename.outputFilename(fromqstr(bufferFilepath()));
430 filename->setText(toqstr(name));
432 // set the bounding box values
433 if (igp.bb.empty()) {
434 string const bb = readBB(igp.filename.absFilename());
435 // the values from the file always have the bigpoint-unit bp
436 lbX->setText(toqstr(token(bb, ' ', 0)));
437 lbY->setText(toqstr(token(bb, ' ', 1)));
438 rtX->setText(toqstr(token(bb, ' ', 2)));
439 rtY->setText(toqstr(token(bb, ' ', 3)));
440 lbXunit->setCurrentIndex(0);
441 lbYunit->setCurrentIndex(0);
442 rtXunit->setCurrentIndex(0);
443 rtYunit->setCurrentIndex(0);
446 // get the values from the inset
448 string const xl = token(igp.bb, ' ', 0);
449 string const yl = token(igp.bb, ' ', 1);
450 string const xr = token(igp.bb, ' ', 2);
451 string const yr = token(igp.bb, ' ', 3);
452 if (isValidLength(xl, &anyLength)) {
453 lbX->setText(toqstr(convert<string>(anyLength.value())));
454 string const unit(unit_name[anyLength.unit()]);
455 lbXunit->setCurrentIndex(getItemNo(bb_units, unit));
457 lbX->setText(toqstr(xl));
459 if (isValidLength(yl, &anyLength)) {
460 lbY->setText(toqstr(convert<string>(anyLength.value())));
461 string const unit(unit_name[anyLength.unit()]);
462 lbYunit->setCurrentIndex(getItemNo(bb_units, unit));
464 lbY->setText(toqstr(xl));
466 if (isValidLength(xr, &anyLength)) {
467 rtX->setText(toqstr(convert<string>(anyLength.value())));
468 string const unit(unit_name[anyLength.unit()]);
469 rtXunit->setCurrentIndex(getItemNo(bb_units, unit));
471 rtX->setText(toqstr(xl));
473 if (isValidLength(yr, &anyLength)) {
474 rtY->setText(toqstr(convert<string>(anyLength.value())));
475 string const unit(unit_name[anyLength.unit()]);
476 rtYunit->setCurrentIndex(getItemNo(bb_units, unit));
478 rtY->setText(toqstr(xl));
483 // Update the draft and clip mode
484 draftCB->setChecked(igp.draft);
485 clip->setChecked(igp.clip);
486 unzipCB->setChecked(igp.noUnzip);
489 switch (igp.display) {
490 case graphics::DefaultDisplay: item = 0; break;
491 case graphics::MonochromeDisplay: item = 1; break;
492 case graphics::GrayscaleDisplay: item = 2; break;
493 case graphics::ColorDisplay: item = 3; break;
494 case graphics::NoDisplay: item = 0; break;
496 showCB->setCurrentIndex(item);
497 displayscale->setText(toqstr(convert<string>(igp.lyxscale)));
498 displayGB->setChecked(igp.display != graphics::NoDisplay);
500 // the output section (width/height)
502 Scale->setText(toqstr(igp.scale));
503 //igp.scale defaults to 100, so we treat it as empty
504 bool const scaleChecked = !igp.scale.empty() && igp.scale != "100";
505 scaleCB->blockSignals(true);
506 scaleCB->setChecked(scaleChecked);
507 scaleCB->blockSignals(false);
508 Scale->setEnabled(scaleChecked);
510 lengthAutoToWidgets(Width, widthUnit, igp.width,
512 bool const widthChecked = !Width->text().isEmpty() &&
513 Width->text() != "auto";
514 WidthCB->blockSignals(true);
515 WidthCB->setChecked(widthChecked);
516 WidthCB->blockSignals(false);
517 Width->setEnabled(widthChecked);
518 widthUnit->setEnabled(widthChecked);
520 lengthAutoToWidgets(Height, heightUnit, igp.height,
522 bool const heightChecked = !Height->text().isEmpty()
523 && Height->text() != "auto";
524 HeightCB->blockSignals(true);
525 HeightCB->setChecked(heightChecked);
526 HeightCB->blockSignals(false);
527 Height->setEnabled(heightChecked);
528 heightUnit->setEnabled(heightChecked);
530 scaleCB->setEnabled(!widthChecked && !heightChecked);
531 WidthCB->setEnabled(!scaleChecked);
532 HeightCB->setEnabled(!scaleChecked);
533 aspectratio->setEnabled(widthChecked && heightChecked);
537 angle->setText(toqstr(igp.rotateAngle));
538 rotateOrderCB->setChecked(igp.scaleBeforeRotation);
540 rotateOrderCB->setEnabled( (widthChecked || heightChecked || scaleChecked)
541 && igp.rotateAngle != "0");
545 vector<RotationOriginPair> origindata = getRotationOriginData();
546 vector<docstring> const origin_lang = getFirst(origindata);
547 origin_ltx = getSecond(origindata);
549 for (vector<docstring>::const_iterator it = origin_lang.begin();
550 it != origin_lang.end(); ++it)
551 origin->addItem(toqstr(*it));
553 if (!igp.rotateOrigin.empty())
554 origin->setCurrentIndex(
555 getItemNo(origin_ltx, igp.rotateOrigin));
557 origin->setCurrentIndex(0);
560 latexoptions->setText(toqstr(igp.special));
564 void GuiGraphics::applyView()
566 InsetGraphicsParams & igp = params_;
568 igp.filename.set(fromqstr(filename->text()), fromqstr(bufferFilepath()));
574 string lbXs = fromqstr(lbX->text());
575 string lbYs = fromqstr(lbY->text());
576 string rtXs = fromqstr(rtX->text());
577 string rtYs = fromqstr(rtY->text());
579 convert<int>(lbXs) + convert<int>(lbYs) +
580 convert<int>(rtXs) + convert<int>(rtXs);
585 bb = lbXs + fromqstr(lbXunit->currentText()) + ' ';
589 bb += (lbYs + fromqstr(lbYunit->currentText()) + ' ');
593 bb += (rtXs + fromqstr(rtXunit->currentText()) + ' ');
597 bb += (rtYs + fromqstr(rtYunit->currentText()));
602 igp.draft = draftCB->isChecked();
603 igp.clip = clip->isChecked();
605 switch (showCB->currentIndex()) {
606 case 0: igp.display = graphics::DefaultDisplay; break;
607 case 1: igp.display = graphics::MonochromeDisplay; break;
608 case 2: igp.display = graphics::GrayscaleDisplay; break;
609 case 3: igp.display = graphics::ColorDisplay; break;
613 if (!displayGB->isChecked())
614 igp.display = graphics::NoDisplay;
616 //the graphics section
617 if (scaleCB->isChecked() && !Scale->text().isEmpty()) {
618 igp.scale = fromqstr(Scale->text());
619 igp.width = Length("0pt");
620 igp.height = Length("0pt");
621 igp.keepAspectRatio = false;
623 igp.scale = string();
624 igp.width = WidthCB->isChecked() ?
625 //Note that this works even if Width is "auto", since in
626 //that case we get "0pt".
627 Length(widgetsToLength(Width, widthUnit)):
629 igp.height = HeightCB->isChecked() ?
630 Length(widgetsToLength(Height, heightUnit)) :
632 igp.keepAspectRatio = aspectratio->isEnabled() &&
633 aspectratio->isChecked() &&
634 igp.width.value() > 0 && igp.height.value() > 0;
637 igp.noUnzip = unzipCB->isChecked();
638 igp.lyxscale = displayscale->text().toInt();
639 igp.rotateAngle = fromqstr(angle->text());
641 double rotAngle = convert<double>(igp.rotateAngle);
642 if (abs(rotAngle) > 360.0) {
643 rotAngle -= 360.0 * floor(rotAngle / 360.0);
644 igp.rotateAngle = convert<string>(rotAngle);
647 // save the latex name for the origin. If it is the default
648 // then origin_ltx returns ""
649 igp.rotateOrigin = origin_ltx[origin->currentIndex()];
650 igp.scaleBeforeRotation = rotateOrderCB->isChecked();
652 // more latex options
653 igp.special = fromqstr(latexoptions->text());
657 void GuiGraphics::getBB()
659 string const fn = fromqstr(filename->text());
662 string const bb = readBB(fn);
666 lbX->setText(toqstr(token(bb, ' ', 0)));
667 lbY->setText(toqstr(token(bb, ' ', 1)));
668 rtX->setText(toqstr(token(bb, ' ', 2)));
669 rtY->setText(toqstr(token(bb, ' ', 3)));
670 // the default units for the bb values when reading
672 lbXunit->setCurrentIndex(0);
673 lbYunit->setCurrentIndex(0);
674 rtXunit->setCurrentIndex(0);
675 rtYunit->setCurrentIndex(0);
679 bool GuiGraphics::isValid()
681 return !filename->text().isEmpty();
685 bool GuiGraphics::initialiseParams(string const & data)
687 InsetGraphics::string2params(data, buffer(), params_);
692 void GuiGraphics::clearParams()
694 params_ = InsetGraphicsParams();
698 void GuiGraphics::dispatchParams()
700 InsetGraphicsParams tmp_params(params_);
701 string const lfun = InsetGraphics::params2string(tmp_params, buffer());
702 dispatch(FuncRequest(getLfun(), lfun));
706 QString GuiGraphics::browse(QString const & in_name) const
708 QString const title = qt_("Select graphics file");
710 // Does user clipart directory exist?
711 string clipdir = addName(package().user_support().absFilename(), "clipart");
712 FileName clip(clipdir);
714 // bail out to system clipart directory
715 if (!(clip.exists() && clip.isDirectory()))
716 clipdir = addName(package().system_support().absFilename(), "clipart");
718 return browseRelFile(in_name, bufferFilepath(),
719 title, FileFilterList(), false,
720 qt_("Clipart|#C#c"), toqstr(clipdir),
721 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
725 string const GuiGraphics::readBB(string const & file)
727 FileName const abs_file = makeAbsPath(file, fromqstr(bufferFilepath()));
729 // try to get it from the file, if possible. Zipped files are
730 // unzipped in the readBB_from_PSFile-Function
731 string const bb = readBB_from_PSFile(abs_file);
735 // we don't, so ask the Graphics Cache if it has loaded the file
739 graphics::Cache & gc = graphics::Cache::get();
740 if (gc.inCache(abs_file)) {
741 graphics::Image const * image = gc.item(abs_file)->image();
744 width = image->width();
745 height = image->height();
749 return ("0 0 " + convert<string>(width) + ' ' + convert<string>(height));
753 bool GuiGraphics::isFilenameValid(string const & fname) const
755 // It may be that the filename is relative.
756 return makeAbsPath(fname, fromqstr(bufferFilepath())).isReadableFile();
762 char const * const bb_units[] = { "bp", "cm", "mm", "in" };
763 size_t const bb_size = sizeof(bb_units) / sizeof(bb_units[0]);
765 // These are the strings that are stored in the LyX file and which
766 // correspond to the LaTeX identifiers shown in the comments at the
768 char const * const rorigin_lyx_strs[] = {
769 // the LaTeX default is leftBaseline
771 "leftTop", "leftBottom", "leftBaseline", // lt lb lB
772 "center", "centerTop", "centerBottom", "centerBaseline", // c ct cb cB
773 "rightTop", "rightBottom", "rightBaseline" }; // rt rb rB
775 // These are the strings, corresponding to the above, that the GUI should
776 // use. Note that they can/should be translated.
777 char const * const rorigin_gui_strs[] = {
779 N_("Top left"), N_("Bottom left"), N_("Baseline left"),
780 N_("Center"), N_("Top center"), N_("Bottom center"), N_("Baseline center"),
781 N_("Top right"), N_("Bottom right"), N_("Baseline right") };
783 size_t const rorigin_size = sizeof(rorigin_lyx_strs) / sizeof(char *);
788 vector<string> const getBBUnits()
790 return vector<string>(bb_units, bb_units + bb_size);
794 vector<RotationOriginPair> getRotationOriginData()
796 static vector<RotationOriginPair> data;
800 data.resize(rorigin_size);
801 for (size_type i = 0; i < rorigin_size; ++i) {
802 data[i] = make_pair(_(rorigin_gui_strs[i]),
803 rorigin_lyx_strs[i]);
810 Dialog * createGuiGraphics(GuiView & lv) { return new GuiGraphics(lv); }
813 } // namespace frontend
816 #include "GuiGraphics_moc.cpp"