/** * \file GuiGraphics.cpp * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * * \author Angus Leeming * \author John Levon * \author Edwin Leuven * \author Herbert Voß * \author Richard Heck * * Full author contact details are available in file CREDITS. */ #include #include "GuiGraphics.h" #include "support/debug.h" #include "LengthCombo.h" #include "Length.h" #include "LyXRC.h" #include "qt_helpers.h" #include "Validator.h" #include "FuncRequest.h" #include "support/gettext.h" #include "graphics/GraphicsCache.h" #include "graphics/GraphicsCacheItem.h" #include "graphics/GraphicsImage.h" #include "insets/InsetGraphicsParams.h" #include "support/convert.h" #include "support/FileFilterList.h" #include "support/filetools.h" #include "support/lstrings.h" #include "support/lyxlib.h" #include "support/os.h" #include "support/Package.h" #include "support/types.h" #include #include #include #include #include #include #include #include #include #include #ifndef CXX_GLOBAL_CSTD using std::floor; #endif using std::find; using std::vector; using std::string; using std::transform; using std::make_pair; using std::pair; using std::vector; namespace lyx { namespace frontend { using support::addName; using support::FileFilterList; using support::FileName; using support::float_equal; using support::makeAbsPath; using support::os::internal_path; using support::package; using support::readBB_from_PSFile; using support::token; //FIXME setAutoTextCB should really take an argument, as indicated, that //determines what text is to be written for "auto". But making //that work involves more extensive revisions than we now want //to make, since "auto" also appears in updateContents() (see //GuiGraphics.cpp). //The right way to do this, I think, would be to define a class //checkedLengthSet (and a partnering labeledLengthSete) that encapsulated //the checkbox, line edit, and length combo together, and then made e.g. //lengthToWidgets, widgetsToLength, etc, all public methods of that class. //Perhaps even the validator could be exposed through it. /** * sets a checkbox-line edit-length combo group, using "text" if the * checkbox is unchecked and clearing the line edit if it previously * said "text". */ static void setAutoTextCB(QCheckBox * checkBox, QLineEdit * lineEdit, LengthCombo * lengthCombo/*, string text = "auto"*/) { if (!checkBox->isChecked()) lengthToWidgets(lineEdit, lengthCombo, "auto", lengthCombo->currentLengthItem()); else if (lineEdit->text() == "auto") lengthToWidgets(lineEdit, lengthCombo, string(), lengthCombo->currentLengthItem()); } template vector const getFirst(vector const & pr) { vector tmp(pr.size()); transform(pr.begin(), pr.end(), tmp.begin(), boost::bind(&Pair::first, _1)); return tmp; } /// template vector const getSecond(vector const & pr) { vector tmp(pr.size()); transform(pr.begin(), pr.end(), tmp.begin(), boost::bind(&Pair::second, _1)); return tmp; } /// The (tranlated) GUI std::string and it's LaTeX equivalent. typedef std::pair RotationOriginPair; /// std::vector getRotationOriginData(); GuiGraphics::GuiGraphics(GuiView & lv) : GuiDialog(lv, "graphics") { setupUi(this); setViewTitle(_("Graphics")); //main buttons connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK())); connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply())); connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose())); connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore())); //graphics pane connect(filename, SIGNAL(textChanged(const QString &)), this, SLOT(change_adaptor())); connect(WidthCB, SIGNAL( clicked()), this, SLOT(change_adaptor())); connect(HeightCB, SIGNAL( clicked()), this, SLOT(change_adaptor())); connect(Width, SIGNAL(textChanged(const QString &)), this, SLOT(change_adaptor())); connect(Height, SIGNAL(textChanged(const QString &)), this, SLOT(change_adaptor())); connect(heightUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)), this, SLOT(change_adaptor())); connect(widthUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)), this, SLOT(change_adaptor())); connect(aspectratio, SIGNAL(stateChanged(int)), this, SLOT(change_adaptor())); connect(angle, SIGNAL(textChanged(const QString &)), this, SLOT(change_adaptor())); connect(origin, SIGNAL(activated(int)), this, SLOT(change_adaptor())); connect(scaleCB, SIGNAL(clicked()), this, SLOT(change_adaptor())); connect(Scale, SIGNAL(textChanged(const QString &)), this, SLOT(change_adaptor())); connect(rotateOrderCB, SIGNAL(clicked()), this, SLOT(change_adaptor())); filename->setValidator(new PathValidator(true, filename)); setFocusProxy(filename); QDoubleValidator * scaleValidator = new DoubleAutoValidator(Scale); scaleValidator->setBottom(0); scaleValidator->setDecimals(256); //I guess that will do Scale->setValidator(scaleValidator); Height->setValidator(unsignedLengthAutoValidator(Height)); Width->setValidator(unsignedLengthAutoValidator(Width)); angle->setValidator(new QDoubleValidator(-360, 360, 2, angle)); //clipping pane connect(clip, SIGNAL(stateChanged(int)), this, SLOT(change_adaptor())); connect(lbY, SIGNAL(textChanged(const QString&)), this, SLOT(change_bb())); connect(lbYunit, SIGNAL(activated(int)), this, SLOT(change_bb())); connect(rtY, SIGNAL(textChanged(const QString&)), this, SLOT(change_bb())); connect(rtYunit, SIGNAL(activated(int)), this, SLOT(change_bb())); connect(lbX, SIGNAL(textChanged(const QString&)), this, SLOT(change_bb())); connect(lbXunit, SIGNAL(activated(int)), this, SLOT(change_bb())); connect(rtX, SIGNAL(textChanged(const QString&)), this, SLOT(change_bb())); connect(rtXunit, SIGNAL(activated(int)), this, SLOT(change_bb())); connect(getPB, SIGNAL(clicked()), this, SLOT(change_adaptor())); lbX->setValidator(new QDoubleValidator(lbX)); lbY->setValidator(new QDoubleValidator(lbY)); rtX->setValidator(new QDoubleValidator(rtX)); rtY->setValidator(new QDoubleValidator(rtY)); //extra options pane connect(latexoptions, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor())); connect(draftCB, SIGNAL(stateChanged(int)), this, SLOT(change_adaptor())); connect(unzipCB, SIGNAL(stateChanged(int)), this, SLOT(change_adaptor())); // FIXME: we should connect to clicked() when we move to Qt 4.2 because // the toggled(bool) signal is also trigged when we update the widgets // (rgh-4/07) this isn't as much or a problem as it was, because we're now // using blockSignals() to keep from triggering that signal when we call // setChecked(). Note, too, that clicked() would get called whenever it // is clicked, even right clicked (I think), not just whenever it is // toggled. connect(subfigure, SIGNAL(toggled(bool)), this, SLOT(change_adaptor())); connect(subcaption, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor())); connect(displayGB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor())); connect(showCB, SIGNAL(currentIndexChanged(int)), this, SLOT(change_adaptor())); connect(displayscale, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor())); displayscale->setValidator(new QIntValidator(displayscale)); bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); bc().setOK(okPB); bc().setApply(applyPB); bc().setRestore(restorePB); bc().setCancel(closePB); bc().addReadOnly(latexoptions); bc().addReadOnly(subfigure); bc().addReadOnly(filenameL); bc().addReadOnly(filename); bc().addReadOnly(browsePB); bc().addReadOnly(unzipCB); bc().addReadOnly(bbFrame); bc().addReadOnly(draftCB); bc().addReadOnly(clip); bc().addReadOnly(unzipCB); bc().addReadOnly(displayGB); bc().addReadOnly(sizeGB); bc().addReadOnly(rotationGB); bc().addReadOnly(latexoptions); bc().addReadOnly(getPB); bc().addReadOnly(rotateOrderCB); // initialize the length validator bc().addCheckedLineEdit(Scale, scaleCB); bc().addCheckedLineEdit(Width, WidthCB); bc().addCheckedLineEdit(Height, HeightCB); bc().addCheckedLineEdit(displayscale, scaleLA); bc().addCheckedLineEdit(angle, angleL); bc().addCheckedLineEdit(lbX, xL); bc().addCheckedLineEdit(lbY, yL); bc().addCheckedLineEdit(rtX, xL_2); bc().addCheckedLineEdit(rtY, yL_2); bc().addCheckedLineEdit(filename, filenameL); } void GuiGraphics::change_adaptor() { changed(); } void GuiGraphics::change_bb() { bbChanged = true; LYXERR(Debug::GRAPHICS, "[bb_Changed set to true]"); changed(); } void GuiGraphics::closeEvent(QCloseEvent * e) { slotClose(); GuiDialog::closeEvent(e); } void GuiGraphics::on_browsePB_clicked() { docstring const str = browse(qstring_to_ucs4(filename->text())); if (!str.empty()) { filename->setText(toqstr(str)); embedCB->setCheckState(Qt::Unchecked); changed(); } } void GuiGraphics::on_getPB_clicked() { getBB(); } void GuiGraphics::on_editPB_clicked() { editGraphics(); } void GuiGraphics::on_filename_textChanged(const QString & filename) { editPB->setDisabled(filename.isEmpty()); } void GuiGraphics::setAutoText() { if (scaleCB->isChecked()) return; if (!Scale->isEnabled() && Scale->text() != "100") Scale->setText(QString("auto")); setAutoTextCB(WidthCB, Width, widthUnit); setAutoTextCB(HeightCB, Height, heightUnit); } void GuiGraphics::on_scaleCB_toggled(bool setScale) { Scale->setEnabled(setScale); if (setScale) { Scale->setText("100"); Scale->setFocus(Qt::OtherFocusReason); } WidthCB->setDisabled(setScale); WidthCB->blockSignals(true); WidthCB->setChecked(false); WidthCB->blockSignals(false); Width->setEnabled(false); widthUnit->setEnabled(false); HeightCB->setDisabled(setScale); HeightCB->blockSignals(true); HeightCB->setChecked(false); HeightCB->blockSignals(false); Height->setEnabled(false); heightUnit->setEnabled(false); aspectratio->setDisabled(true); aspectratio->setChecked(true); rotateOrderCB->setEnabled((WidthCB->isChecked() || HeightCB->isChecked() || scaleCB->isChecked()) && (angle->text() != "0")); setAutoText(); } void GuiGraphics::on_WidthCB_toggled(bool setWidth) { Width->setEnabled(setWidth); widthUnit->setEnabled(setWidth); if (setWidth) Width->setFocus(Qt::OtherFocusReason); bool const setHeight = HeightCB->isChecked(); aspectratio->setEnabled(setWidth && setHeight); aspectratio->blockSignals(true); aspectratio->setChecked(!(setWidth && setHeight)); aspectratio->blockSignals(false); scaleCB->setEnabled(!setWidth && !setHeight); //already will be unchecked, so don't need to do that Scale->setEnabled((!setWidth && !setHeight) //=scaleCB->isEnabled() && scaleCB->isChecked()); //should be false, but let's check rotateOrderCB->setEnabled((setWidth || setHeight || scaleCB->isChecked()) && (angle->text() != "0")); setAutoText(); } void GuiGraphics::on_HeightCB_toggled(bool setHeight) { Height->setEnabled(setHeight); heightUnit->setEnabled(setHeight); if (setHeight) Height->setFocus(Qt::OtherFocusReason); bool const setWidth = WidthCB->isChecked(); aspectratio->setEnabled(setWidth && setHeight); aspectratio->blockSignals(true); aspectratio->setChecked(!(setWidth && setHeight)); aspectratio->blockSignals(false); scaleCB->setEnabled(!setWidth && !setHeight); //already unchecked Scale->setEnabled((!setWidth && !setHeight) //=scaleCB->isEnabled() && scaleCB->isChecked()); //should be false rotateOrderCB->setEnabled((setWidth || setHeight || scaleCB->isChecked()) && (angle->text() != "0")); setAutoText(); } void GuiGraphics::on_angle_textChanged(const QString & filename) { rotateOrderCB->setEnabled((WidthCB->isChecked() || HeightCB->isChecked() || scaleCB->isChecked()) && (filename != "0")); } // returns the number of the string s in the vector v static int getItemNo(const vector & v, string const & s) { vector::const_iterator cit = find(v.begin(), v.end(), s); return (cit != v.end()) ? int(cit - v.begin()) : 0; } void GuiGraphics::updateContents() { // clear and fill in the comboboxes vector const bb_units = frontend::getBBUnits(); lbXunit->clear(); lbYunit->clear(); rtXunit->clear(); rtYunit->clear(); for (vector::const_iterator it = bb_units.begin(); it != bb_units.end(); ++it) { lbXunit->addItem(toqstr(*it)); lbYunit->addItem(toqstr(*it)); rtXunit->addItem(toqstr(*it)); rtYunit->addItem(toqstr(*it)); } InsetGraphicsParams & igp = params_; // set the right default unit Length::UNIT unitDefault = Length::CM; switch (lyxrc.default_papersize) { case PAPER_USLETTER: case PAPER_USLEGAL: case PAPER_USEXECUTIVE: unitDefault = Length::IN; break; default: break; } string const name = igp.filename.outputFilename(bufferFilepath()); filename->setText(toqstr(name)); embedCB->setCheckState(igp.filename.embedded() ? Qt::Checked : Qt::Unchecked); // set the bounding box values if (igp.bb.empty()) { string const bb = readBB(igp.filename.absFilename()); // the values from the file always have the bigpoint-unit bp lbX->setText(toqstr(token(bb, ' ', 0))); lbY->setText(toqstr(token(bb, ' ', 1))); rtX->setText(toqstr(token(bb, ' ', 2))); rtY->setText(toqstr(token(bb, ' ', 3))); lbXunit->setCurrentIndex(0); lbYunit->setCurrentIndex(0); rtXunit->setCurrentIndex(0); rtYunit->setCurrentIndex(0); bbChanged = false; } else { // get the values from the inset Length anyLength; string const xl = token(igp.bb, ' ', 0); string const yl = token(igp.bb, ' ', 1); string const xr = token(igp.bb, ' ', 2); string const yr = token(igp.bb, ' ', 3); if (isValidLength(xl, &anyLength)) { lbX->setText(toqstr(convert(anyLength.value()))); string const unit(unit_name[anyLength.unit()]); lbXunit->setCurrentIndex(getItemNo(bb_units, unit)); } else { lbX->setText(toqstr(xl)); } if (isValidLength(yl, &anyLength)) { lbY->setText(toqstr(convert(anyLength.value()))); string const unit(unit_name[anyLength.unit()]); lbYunit->setCurrentIndex(getItemNo(bb_units, unit)); } else { lbY->setText(toqstr(xl)); } if (isValidLength(xr, &anyLength)) { rtX->setText(toqstr(convert(anyLength.value()))); string const unit(unit_name[anyLength.unit()]); rtXunit->setCurrentIndex(getItemNo(bb_units, unit)); } else { rtX->setText(toqstr(xl)); } if (isValidLength(yr, &anyLength)) { rtY->setText(toqstr(convert(anyLength.value()))); string const unit(unit_name[anyLength.unit()]); rtYunit->setCurrentIndex(getItemNo(bb_units, unit)); } else { rtY->setText(toqstr(xl)); } bbChanged = true; } // Update the draft and clip mode draftCB->setChecked(igp.draft); clip->setChecked(igp.clip); unzipCB->setChecked(igp.noUnzip); // Update the subcaption check button and input field subfigure->setChecked(igp.subcaption); subcaption->setText(toqstr(igp.subcaptionText)); int item = 0; switch (igp.display) { case graphics::DefaultDisplay: item = 0; break; case graphics::MonochromeDisplay: item = 1; break; case graphics::GrayscaleDisplay: item = 2; break; case graphics::ColorDisplay: item = 3; break; case graphics::NoDisplay: item = 0; break; } showCB->setCurrentIndex(item); displayscale->setText(toqstr(convert(igp.lyxscale))); displayGB->setChecked(igp.display != graphics::NoDisplay); // the output section (width/height) Scale->setText(toqstr(igp.scale)); //igp.scale defaults to 100, so we treat it as empty bool const scaleChecked = !igp.scale.empty() && igp.scale != "100"; scaleCB->blockSignals(true); scaleCB->setChecked(scaleChecked); scaleCB->blockSignals(false); Scale->setEnabled(scaleChecked); lengthAutoToWidgets(Width, widthUnit, igp.width, unitDefault); bool const widthChecked = !Width->text().isEmpty() && Width->text() != "auto"; WidthCB->blockSignals(true); WidthCB->setChecked(widthChecked); WidthCB->blockSignals(false); Width->setEnabled(widthChecked); widthUnit->setEnabled(widthChecked); lengthAutoToWidgets(Height, heightUnit, igp.height, unitDefault); bool const heightChecked = !Height->text().isEmpty() && Height->text() != "auto"; HeightCB->blockSignals(true); HeightCB->setChecked(heightChecked); HeightCB->blockSignals(false); Height->setEnabled(heightChecked); heightUnit->setEnabled(heightChecked); scaleCB->setEnabled(!widthChecked && !heightChecked); WidthCB->setEnabled(!scaleChecked); HeightCB->setEnabled(!scaleChecked); aspectratio->setEnabled(widthChecked && heightChecked); setAutoText(); angle->setText(toqstr(igp.rotateAngle)); rotateOrderCB->setChecked(igp.scaleBeforeRotation); rotateOrderCB->setEnabled( (widthChecked || heightChecked || scaleChecked) && igp.rotateAngle != "0"); origin->clear(); vector origindata = getRotationOriginData(); vector const origin_lang = getFirst(origindata); origin_ltx = getSecond(origindata); for (vector::const_iterator it = origin_lang.begin(); it != origin_lang.end(); ++it) origin->addItem(toqstr(*it)); if (!igp.rotateOrigin.empty()) origin->setCurrentIndex( getItemNo(origin_ltx, igp.rotateOrigin)); else origin->setCurrentIndex(0); // disable edit button when no filename is present editPB->setDisabled(filename->text().isEmpty()); //// latex section latexoptions->setText(toqstr(igp.special)); } void GuiGraphics::applyView() { InsetGraphicsParams & igp = params_; igp.filename.set(fromqstr(filename->text()), bufferFilepath()); igp.filename.setEmbed(embedCB->checkState() == Qt::Checked); // the bb section igp.bb.erase(); if (bbChanged) { string bb; string lbXs = fromqstr(lbX->text()); string lbYs = fromqstr(lbY->text()); string rtXs = fromqstr(rtX->text()); string rtYs = fromqstr(rtY->text()); int bb_sum = convert(lbXs) + convert(lbYs) + convert(rtXs) + convert(rtXs); if (bb_sum) { if (lbXs.empty()) bb = "0 "; else bb = lbXs + fromqstr(lbXunit->currentText()) + ' '; if (lbYs.empty()) bb += "0 "; else bb += (lbYs + fromqstr(lbYunit->currentText()) + ' '); if (rtXs.empty()) bb += "0 "; else bb += (rtXs + fromqstr(rtXunit->currentText()) + ' '); if (rtYs.empty()) bb += '0'; else bb += (rtYs + fromqstr(rtYunit->currentText())); igp.bb = bb; } } igp.draft = draftCB->isChecked(); igp.clip = clip->isChecked(); igp.subcaption = subfigure->isChecked(); igp.subcaptionText = fromqstr(subcaption->text()); switch (showCB->currentIndex()) { case 0: igp.display = graphics::DefaultDisplay; break; case 1: igp.display = graphics::MonochromeDisplay; break; case 2: igp.display = graphics::GrayscaleDisplay; break; case 3: igp.display = graphics::ColorDisplay; break; default:; } if (!displayGB->isChecked()) igp.display = graphics::NoDisplay; //the graphics section if (scaleCB->isChecked() && !Scale->text().isEmpty()) { igp.scale = fromqstr(Scale->text()); igp.width = Length("0pt"); igp.height = Length("0pt"); igp.keepAspectRatio = false; } else { igp.scale = string(); igp.width = WidthCB->isChecked() ? //Note that this works even if Width is "auto", since in //that case we get "0pt". Length(widgetsToLength(Width, widthUnit)): Length("0pt"); igp.height = HeightCB->isChecked() ? Length(widgetsToLength(Height, heightUnit)) : Length("0pt"); igp.keepAspectRatio = aspectratio->isEnabled() && aspectratio->isChecked() && igp.width.value() > 0 && igp.height.value() > 0; } igp.noUnzip = unzipCB->isChecked(); igp.lyxscale = displayscale->text().toInt(); igp.rotateAngle = fromqstr(angle->text()); double rotAngle = convert(igp.rotateAngle); if (std::abs(rotAngle) > 360.0) { rotAngle -= 360.0 * floor(rotAngle / 360.0); igp.rotateAngle = convert(rotAngle); } // save the latex name for the origin. If it is the default // then origin_ltx returns "" igp.rotateOrigin = origin_ltx[origin->currentIndex()]; igp.scaleBeforeRotation = rotateOrderCB->isChecked(); // more latex options igp.special = fromqstr(latexoptions->text()); } void GuiGraphics::getBB() { string const fn = fromqstr(filename->text()); if (fn.empty()) return; string const bb = readBB(fn); bbChanged = false; if (bb.empty()) return; lbX->setText(toqstr(token(bb, ' ', 0))); lbY->setText(toqstr(token(bb, ' ', 1))); rtX->setText(toqstr(token(bb, ' ', 2))); rtY->setText(toqstr(token(bb, ' ', 3))); // the default units for the bb values when reading // it from the file lbXunit->setCurrentIndex(0); lbYunit->setCurrentIndex(0); rtXunit->setCurrentIndex(0); rtYunit->setCurrentIndex(0); } bool GuiGraphics::isValid() { return !filename->text().isEmpty(); } bool GuiGraphics::initialiseParams(string const & data) { InsetGraphicsMailer::string2params(data, buffer(), params_); return true; } void GuiGraphics::clearParams() { params_ = InsetGraphicsParams(); } void GuiGraphics::dispatchParams() { InsetGraphicsParams tmp_params(params_); string const lfun = InsetGraphicsMailer::params2string(tmp_params, buffer()); dispatch(FuncRequest(getLfun(), lfun)); } docstring const GuiGraphics::browse(docstring const & in_name) const { docstring const title = _("Select graphics file"); // Does user clipart directory exist? string clipdir = addName(package().user_support().absFilename(), "clipart"); FileName clip(clipdir); // bail out to system clipart directory if (!(clip.exists() && clip.isDirectory())) clipdir = addName(package().system_support().absFilename(), "clipart"); return browseRelFile(in_name, from_utf8(bufferFilepath()), title, FileFilterList(), false, _("Clipart|#C#c"), from_utf8(clipdir), _("Documents|#o#O"), from_utf8(lyxrc.document_path)); } string const GuiGraphics::readBB(string const & file) { FileName const abs_file = makeAbsPath(file, bufferFilepath()); // try to get it from the file, if possible. Zipped files are // unzipped in the readBB_from_PSFile-Function string const bb = readBB_from_PSFile(abs_file); if (!bb.empty()) return bb; // we don't, so ask the Graphics Cache if it has loaded the file int width = 0; int height = 0; graphics::Cache & gc = graphics::Cache::get(); if (gc.inCache(abs_file)) { graphics::Image const * image = gc.item(abs_file)->image(); if (image) { width = image->width(); height = image->height(); } } return ("0 0 " + convert(width) + ' ' + convert(height)); } bool GuiGraphics::isFilenameValid(string const & fname) const { // It may be that the filename is relative. return makeAbsPath(fname, bufferFilepath()).isReadableFile(); } void GuiGraphics::editGraphics() { applyView(); string const lfun = InsetGraphicsMailer::params2string(params_, buffer()); dispatch(FuncRequest(LFUN_GRAPHICS_EDIT, lfun)); } namespace { char const * const bb_units[] = { "bp", "cm", "mm", "in" }; size_t const bb_size = sizeof(bb_units) / sizeof(char *); // These are the strings that are stored in the LyX file and which // correspond to the LaTeX identifiers shown in the comments at the // end of each line. char const * const rorigin_lyx_strs[] = { // the LaTeX default is leftBaseline "", "leftTop", "leftBottom", "leftBaseline", // lt lb lB "center", "centerTop", "centerBottom", "centerBaseline", // c ct cb cB "rightTop", "rightBottom", "rightBaseline" }; // rt rb rB // These are the strings, corresponding to the above, that the GUI should // use. Note that they can/should be translated. char const * const rorigin_gui_strs[] = { N_("Default"), N_("Top left"), N_("Bottom left"), N_("Baseline left"), N_("Center"), N_("Top center"), N_("Bottom center"), N_("Baseline center"), N_("Top right"), N_("Bottom right"), N_("Baseline right") }; size_t const rorigin_size = sizeof(rorigin_lyx_strs) / sizeof(char *); } // namespace anon vector const getBBUnits() { return vector(bb_units, bb_units + bb_size); } vector getRotationOriginData() { static vector data; if (!data.empty()) return data; data.resize(rorigin_size); for (size_type i = 0; i < rorigin_size; ++i) { data[i] = make_pair(_(rorigin_gui_strs[i]), rorigin_lyx_strs[i]); } return data; } Dialog * createGuiGraphics(GuiView & lv) { return new GuiGraphics(lv); } } // namespace frontend } // namespace lyx #include "GuiGraphics_moc.cpp"