X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiGraphics.cpp;h=e89bd4cfe6467e0e050ea0d0c88df64609a2b07a;hb=425d092204118ea6c24c28e85fdf03fcf2bb51a4;hp=1b804c841cce3e68771e11cf09c6a6ff8515d5b3;hpb=fc36725282df43059aee9a821f098309ccdbd523;p=lyx.git diff --git a/src/frontends/qt4/GuiGraphics.cpp b/src/frontends/qt4/GuiGraphics.cpp index 1b804c841c..e89bd4cfe6 100644 --- a/src/frontends/qt4/GuiGraphics.cpp +++ b/src/frontends/qt4/GuiGraphics.cpp @@ -3,9 +3,10 @@ * 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 Herbert Voß * \author Richard Heck * * Full author contact details are available in file CREDITS. @@ -14,74 +15,117 @@ #include #include "GuiGraphics.h" +#include "frontends/alert.h" +#include "qt_helpers.h" +#include "Validator.h" -#include "CheckedLineEdit.h" -#include "debug.h" +#include "Buffer.h" +#include "FuncRequest.h" #include "LengthCombo.h" -#include "lengthcommon.h" +#include "Length.h" #include "LyXRC.h" -#include "Qt2BC.h" -#include "qt_helpers.h" -#include "Validator.h" +#include "Undo.h" -#include "controllers/frontend_helpers.h" +#include "graphics/GraphicsCache.h" +#include "graphics/GraphicsCacheItem.h" +#include "graphics/GraphicsImage.h" -#include "insets/InsetGraphicsParams.h" +#include "insets/InsetGraphics.h" #include "support/convert.h" +#include "support/debug.h" +#include "support/filetools.h" +#include "support/gettext.h" #include "support/lstrings.h" -#include "support/lyxlib.h" #include "support/os.h" - -#include - -#include "insets/InsetGraphicsParams.h" +#include "support/Package.h" +#include "support/types.h" #include -#include #include #include #include #include +#include +#include -using lyx::support::float_equal; -using lyx::support::token; +using namespace std; +using namespace lyx::support; -using lyx::support::os::internal_path; +namespace { + +// 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 *); -#ifndef CXX_GLOBAL_CSTD -using std::floor; -#endif +static string autostr = N_("automatically"); -using std::vector; -using std::string; +} // namespace anon namespace lyx { namespace frontend { +//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 paramsToDialog(). +//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, + _(autostr), lengthCombo->currentLengthItem()); + else if (lineEdit->text() == qt_(autostr)) + lengthToWidgets(lineEdit, lengthCombo, string(), + lengthCombo->currentLengthItem()); +} + -GuiGraphicsDialog::GuiGraphicsDialog(GuiGraphics * form) - : form_(form) +GuiGraphics::GuiGraphics(GuiView & lv) + : GuiDialog(lv, "graphics", qt_("Graphics")) { setupUi(this); + //main buttons - connect(okPB, SIGNAL(clicked()), - form, SLOT(slotOK())); - connect(applyPB, SIGNAL(clicked()), - form, SLOT(slotApply())); - connect(closePB, SIGNAL(clicked()), - form, SLOT(slotClose())); - connect(restorePB, SIGNAL(clicked()), - form, SLOT(slotRestore())); + 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()), + connect(WidthCB, SIGNAL(clicked()), this, SLOT(change_adaptor())); - connect(HeightCB, SIGNAL( clicked()), + connect(HeightCB, SIGNAL(clicked()), this, SLOT(change_adaptor())); connect(Width, SIGNAL(textChanged(const QString &)), this, SLOT(change_adaptor())); @@ -107,33 +151,34 @@ GuiGraphicsDialog::GuiGraphicsDialog(GuiGraphics * form) filename->setValidator(new PathValidator(true, filename)); setFocusProxy(filename); - QDoubleValidator * scaleValidator = new DoubleAutoValidator(Scale); + QDoubleValidator * scaleValidator = + new DoubleAutoValidator(Scale, qt_(autostr)); scaleValidator->setBottom(0); scaleValidator->setDecimals(256); //I guess that will do Scale->setValidator(scaleValidator); - Height->setValidator(unsignedLengthAutoValidator(Height)); - Width->setValidator(unsignedLengthAutoValidator(Width)); + Height->setValidator(unsignedLengthAutoValidator(Height, qt_(autostr))); + Width->setValidator(unsignedLengthAutoValidator(Width, qt_(autostr))); 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())); + this, SLOT(changeBB())); connect(lbYunit, SIGNAL(activated(int)), - this, SLOT(change_bb())); + this, SLOT(changeBB())); connect(rtY, SIGNAL(textChanged(const QString&)), - this, SLOT(change_bb())); + this, SLOT(changeBB())); connect(rtYunit, SIGNAL(activated(int)), - this, SLOT(change_bb())); + this, SLOT(changeBB())); connect(lbX, SIGNAL(textChanged(const QString&)), - this, SLOT(change_bb())); + this, SLOT(changeBB())); connect(lbXunit, SIGNAL(activated(int)), - this, SLOT(change_bb())); + this, SLOT(changeBB())); connect(rtX, SIGNAL(textChanged(const QString&)), - this, SLOT(change_bb())); + this, SLOT(changeBB())); connect(rtXunit, SIGNAL(activated(int)), - this, SLOT(change_bb())); + this, SLOT(changeBB())); connect(getPB, SIGNAL(clicked()), this, SLOT(change_adaptor())); @@ -156,89 +201,183 @@ GuiGraphicsDialog::GuiGraphicsDialog(GuiGraphics * form) // 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(displayGB, SIGNAL(toggled(bool)), this, SLOT(change_adaptor())); connect(displayscale, SIGNAL(textChanged(const QString&)), this, SLOT(change_adaptor())); + connect(groupCO, SIGNAL(currentIndexChanged(int)), + this, SLOT(changeGroup(int))); + 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(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); -void GuiGraphicsDialog::show() -{ - QDialog::show(); + // 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 GuiGraphicsDialog::change_adaptor() +void GuiGraphics::change_adaptor() { - form_->changed(); + changed(); } -void GuiGraphicsDialog::change_bb() +void GuiGraphics::changeGroup(int /* index */) { - form_->controller().bbChanged = true; - LYXERR(Debug::GRAPHICS) - << "[controller().bb_Changed set to true]\n"; - form_->changed(); -} + QString const new_group = groupCO->itemData( + groupCO->currentIndex()).toString(); + + // check if the old group consisted only of this member + if (current_group_ != fromqstr(new_group) + && graphics::countGroupMembers(buffer(), current_group_) == 1) { + if (!new_group.isEmpty()) { + if (Alert::prompt(_("Dissolve previous group?"), + bformat(_("If you assign this graphic to group '%2$s',\n" + "the previously assigned group '%1$s' will be dissolved,\n" + "because this graphic was its only member.\n" + "How do you want to proceed?"), + from_utf8(current_group_), qstring_to_ucs4(new_group)), + 0, 0, + bformat(_("Stick with group '%1$s'"), + from_utf8(current_group_)), + bformat(_("Assign to group '%1$s' anyway"), + qstring_to_ucs4(new_group))) == 0) { + groupCO->setCurrentIndex( + groupCO->findData(toqstr(current_group_), Qt::MatchExactly)); + return; + } + } else { + if (Alert::prompt(_("Dissolve previous group?"), + bformat(_("If you sign off this graphic from group '%1$s',\n" + "the group will be dissolved,\n" + "because this graphic was its only member.\n" + "How do you want to proceed?"), + from_utf8(current_group_)), + 0, 0, + bformat(_("Stick with group '%1$s'"), + from_utf8(current_group_)), + bformat(_("Sign off from group '%1$s'"), + from_utf8(current_group_))) == 0) { + groupCO->setCurrentIndex( + groupCO->findData(toqstr(current_group_), Qt::MatchExactly)); + return; + } + } + } + if (new_group.isEmpty()) { + changed(); + return; + } -void GuiGraphicsDialog::closeEvent(QCloseEvent * e) -{ - form_->slotWMHide(); - e->accept(); + string grp = graphics::getGroupParams(buffer(), fromqstr(new_group)); + if (grp.empty()) { + // group does not exist yet + changed(); + return; + } + + // filename might have been changed + QString current_filename = filename->text(); + + // group exists: load params into the dialog + groupCO->blockSignals(true); + InsetGraphics::string2params(grp, buffer(), params_); + paramsToDialog(params_); + groupCO->blockSignals(false); + + // reset filename + filename->setText(current_filename); + + changed(); } -void GuiGraphicsDialog::on_browsePB_clicked() +void GuiGraphics::on_newGroupPB_clicked() { - docstring const str = - form_->controller().browse(qstring_to_ucs4(filename->text())); - if(!str.empty()){ - filename->setText(toqstr(str)); - form_->changed(); + docstring newgroup; + if (!Alert::askForText(newgroup, _("Enter unique group name:"))) + return; + if (newgroup.empty()) + return; + if (groupCO->findData(toqstr(newgroup), Qt::MatchExactly) != -1) { + Alert::warning(_("Group already defined!"), + bformat(_("A graphics group with the name '%1$s' already exists."), + newgroup)); + return; } + groupCO->addItem(toqstr(newgroup), toqstr(newgroup)); + groupCO->setCurrentIndex( + groupCO->findData(toqstr(newgroup), Qt::MatchExactly)); } -void GuiGraphicsDialog::on_getPB_clicked() +void GuiGraphics::changeBB() { - form_->getBB(); + bbChanged = true; + LYXERR(Debug::GRAPHICS, "[bb_Changed set to true]"); + changed(); } -void GuiGraphicsDialog::on_editPB_clicked() +void GuiGraphics::on_browsePB_clicked() { - form_->controller().editGraphics(); + QString const str = browse(filename->text()); + if (!str.isEmpty()) { + filename->setText(str); + changed(); + } } -void GuiGraphicsDialog::on_filename_textChanged(const QString & filename) +void GuiGraphics::on_getPB_clicked() { - editPB->setDisabled(filename.isEmpty()); + getBB(); } -void GuiGraphicsDialog::setAutoText() +void GuiGraphics::setAutoText() { - if (scaleCB->isChecked()) return; + if (scaleCB->isChecked()) + return; if (!Scale->isEnabled() && Scale->text() != "100") - Scale->setText(QString("auto")); + Scale->setText(qt_(autostr)); setAutoTextCB(WidthCB, Width, widthUnit); setAutoTextCB(HeightCB, Height, heightUnit); } -void GuiGraphicsDialog::on_scaleCB_toggled(bool setScale) +void GuiGraphics::on_scaleCB_toggled(bool setScale) { Scale->setEnabled(setScale); if (setScale) { @@ -271,7 +410,8 @@ void GuiGraphicsDialog::on_scaleCB_toggled(bool setScale) setAutoText(); } -void GuiGraphicsDialog::on_WidthCB_toggled(bool setWidth) + +void GuiGraphics::on_WidthCB_toggled(bool setWidth) { Width->setEnabled(setWidth); widthUnit->setEnabled(setWidth); @@ -295,7 +435,8 @@ void GuiGraphicsDialog::on_WidthCB_toggled(bool setWidth) setAutoText(); } -void GuiGraphicsDialog::on_HeightCB_toggled(bool setHeight) + +void GuiGraphics::on_HeightCB_toggled(bool setHeight) { Height->setEnabled(setHeight); heightUnit->setEnabled(setHeight); @@ -320,7 +461,7 @@ void GuiGraphicsDialog::on_HeightCB_toggled(bool setHeight) } -void GuiGraphicsDialog::on_angle_textChanged(const QString & filename) +void GuiGraphics::on_angle_textChanged(const QString & filename) { rotateOrderCB->setEnabled((WidthCB->isChecked() || HeightCB->isChecked() || @@ -329,323 +470,248 @@ void GuiGraphicsDialog::on_angle_textChanged(const QString & filename) } -GuiGraphics::GuiGraphics(Dialog & parent) - : GuiView(parent, _("Graphics")) -{ -} - - -void GuiGraphics::build_dialog() -{ - dialog_.reset(new GuiGraphicsDialog(this)); - - bcview().setOK(dialog_->okPB); - bcview().setApply(dialog_->applyPB); - bcview().setRestore(dialog_->restorePB); - bcview().setCancel(dialog_->closePB); - - bcview().addReadOnly(dialog_->latexoptions); - bcview().addReadOnly(dialog_->subfigure); - bcview().addReadOnly(dialog_->filenameL); - bcview().addReadOnly(dialog_->filename); - bcview().addReadOnly(dialog_->browsePB); - bcview().addReadOnly(dialog_->unzipCB); - bcview().addReadOnly(dialog_->bbFrame); - bcview().addReadOnly(dialog_->draftCB); - bcview().addReadOnly(dialog_->clip); - bcview().addReadOnly(dialog_->unzipCB); - bcview().addReadOnly(dialog_->displayGB); - bcview().addReadOnly(dialog_->sizeGB); - bcview().addReadOnly(dialog_->rotationGB); - bcview().addReadOnly(dialog_->latexoptions); - bcview().addReadOnly(dialog_->getPB); - bcview().addReadOnly(dialog_->rotateOrderCB); - - // initialize the length validator - addCheckedLineEdit(bcview(), dialog_->Scale, dialog_->scaleCB); - addCheckedLineEdit(bcview(), dialog_->Width, dialog_->WidthCB); - addCheckedLineEdit(bcview(), dialog_->Height, dialog_->HeightCB); - addCheckedLineEdit(bcview(), dialog_->displayscale, dialog_->scaleLA); - addCheckedLineEdit(bcview(), dialog_->angle, dialog_->angleL); - addCheckedLineEdit(bcview(), dialog_->lbX, dialog_->xL); - addCheckedLineEdit(bcview(), dialog_->lbY, dialog_->yL); - addCheckedLineEdit(bcview(), dialog_->rtX, dialog_->xL_2); - addCheckedLineEdit(bcview(), dialog_->rtY, dialog_->yL_2); - addCheckedLineEdit(bcview(), dialog_->filename, dialog_->filenameL); -} - - -namespace { - -// returns the number of the string s in the vector v -int getItemNo(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::update_contents() +void GuiGraphics::paramsToDialog(InsetGraphicsParams const & igp) { - // clear and fill in the comboboxes - vector const bb_units = frontend::getBBUnits(); - dialog_->lbXunit->clear(); - dialog_->lbYunit->clear(); - dialog_->rtXunit->clear(); - dialog_->rtYunit->clear(); - for (vector::const_iterator it = bb_units.begin(); - it != bb_units.end(); ++it) { - dialog_->lbXunit->addItem(toqstr(*it)); - dialog_->lbYunit->addItem(toqstr(*it)); - dialog_->rtXunit->addItem(toqstr(*it)); - dialog_->rtYunit->addItem(toqstr(*it)); + static char const * const bb_units[] = { "bp", "cm", "mm", "in" }; + static char const * const bb_units_gui[] = { N_("bp"), N_("cm"), N_("mm"), N_("in") }; + size_t const bb_size = sizeof(bb_units) / sizeof(bb_units[0]); + + lbXunit->clear(); + lbYunit->clear(); + rtXunit->clear(); + rtYunit->clear(); + + for (size_t i = 0; i < bb_size; i++) { + lbXunit->addItem(qt_(bb_units_gui[i]), + toqstr(bb_units[i])); + lbYunit->addItem(qt_(bb_units_gui[i]), + toqstr(bb_units[i])); + rtXunit->addItem(qt_(bb_units_gui[i]), + toqstr(bb_units[i])); + rtYunit->addItem(qt_(bb_units_gui[i]), + toqstr(bb_units[i])); } - - InsetGraphicsParams & igp = controller().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; - } + Length::UNIT const defaultUnit = Length::defaultUnit(); + //lyxerr << bufferFilepath(); string const name = - igp.filename.outputFilename(kernel().bufferFilepath()); - dialog_->filename->setText(toqstr(name)); + igp.filename.outputFilename(fromqstr(bufferFilepath())); + filename->setText(toqstr(name)); // set the bounding box values if (igp.bb.empty()) { - string const bb = controller().readBB(igp.filename.absFilename()); + string const bb = readBoundingBox(igp.filename.absFilename()); // the values from the file always have the bigpoint-unit bp - dialog_->lbX->setText(toqstr(token(bb, ' ', 0))); - dialog_->lbY->setText(toqstr(token(bb, ' ', 1))); - dialog_->rtX->setText(toqstr(token(bb, ' ', 2))); - dialog_->rtY->setText(toqstr(token(bb, ' ', 3))); - dialog_->lbXunit->setCurrentIndex(0); - dialog_->lbYunit->setCurrentIndex(0); - dialog_->rtXunit->setCurrentIndex(0); - dialog_->rtYunit->setCurrentIndex(0); - controller().bbChanged = false; + doubleToWidget(lbX, token(bb, ' ', 0)); + doubleToWidget(lbY, token(bb, ' ', 1)); + doubleToWidget(rtX, token(bb, ' ', 2)); + doubleToWidget(rtY, 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)); + 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)) { - dialog_->lbX->setText(toqstr(convert(anyLength.value()))); - string const unit(unit_name[anyLength.unit()]); - dialog_->lbXunit->setCurrentIndex(getItemNo(bb_units, unit)); + doubleToWidget(lbX, anyLength.value()); + string const unit = unit_name[anyLength.unit()]; + lbXunit->setCurrentIndex(lbXunit->findData(toqstr(unit))); } else { - dialog_->lbX->setText(toqstr(xl)); + lbX->setText(toqstr(xl)); } if (isValidLength(yl, &anyLength)) { - dialog_->lbY->setText(toqstr(convert(anyLength.value()))); - string const unit(unit_name[anyLength.unit()]); - dialog_->lbYunit->setCurrentIndex(getItemNo(bb_units, unit)); + doubleToWidget(lbY, anyLength.value()); + string const unit = unit_name[anyLength.unit()]; + lbYunit->setCurrentIndex(lbYunit->findData(toqstr(unit))); } else { - dialog_->lbY->setText(toqstr(xl)); + lbY->setText(toqstr(xl)); } if (isValidLength(xr, &anyLength)) { - dialog_->rtX->setText(toqstr(convert(anyLength.value()))); - string const unit(unit_name[anyLength.unit()]); - dialog_->rtXunit->setCurrentIndex(getItemNo(bb_units, unit)); + doubleToWidget(rtX, anyLength.value()); + string const unit = unit_name[anyLength.unit()]; + rtXunit->setCurrentIndex(rtXunit->findData(toqstr(unit))); } else { - dialog_->rtX->setText(toqstr(xl)); + rtX->setText(toqstr(xl)); } if (isValidLength(yr, &anyLength)) { - dialog_->rtY->setText(toqstr(convert(anyLength.value()))); - string const unit(unit_name[anyLength.unit()]); - dialog_->rtYunit->setCurrentIndex(getItemNo(bb_units, unit)); + doubleToWidget(rtY, anyLength.value()); + string const unit = unit_name[anyLength.unit()]; + rtYunit->setCurrentIndex(rtYunit->findData(toqstr(unit))); } else { - dialog_->rtY->setText(toqstr(xl)); + rtY->setText(toqstr(xl)); } - controller().bbChanged = true; + bbChanged = true; } // Update the draft and clip mode - dialog_->draftCB->setChecked(igp.draft); - dialog_->clip->setChecked(igp.clip); - dialog_->unzipCB->setChecked(igp.noUnzip); - - // Update the subcaption check button and input field - dialog_->subfigure->setChecked(igp.subcaption); - dialog_->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; - } - dialog_->showCB->setCurrentIndex(item); - dialog_->displayscale->setText(toqstr(convert(igp.lyxscale))); - dialog_->displayGB->setChecked(igp.display != graphics::NoDisplay); + draftCB->setChecked(igp.draft); + clip->setChecked(igp.clip); + unzipCB->setChecked(igp.noUnzip); + displayGB->setChecked(igp.display); + displayscale->setText(toqstr(convert(igp.lyxscale))); // the output section (width/height) - dialog_->Scale->setText(toqstr(igp.scale)); + doubleToWidget(Scale, igp.scale); //igp.scale defaults to 100, so we treat it as empty bool const scaleChecked = !igp.scale.empty() && igp.scale != "100"; - dialog_->scaleCB->blockSignals(true); - dialog_->scaleCB->setChecked(scaleChecked); - dialog_->scaleCB->blockSignals(false); - dialog_->Scale->setEnabled(scaleChecked); - - lengthAutoToWidgets(dialog_->Width, dialog_->widthUnit, igp.width, - unitDefault); - bool const widthChecked = !dialog_->Width->text().isEmpty() && - dialog_->Width->text() != "auto"; - dialog_->WidthCB->blockSignals(true); - dialog_->WidthCB->setChecked(widthChecked); - dialog_->WidthCB->blockSignals(false); - dialog_->Width->setEnabled(widthChecked); - dialog_->widthUnit->setEnabled(widthChecked); - - lengthAutoToWidgets(dialog_->Height, dialog_->heightUnit, igp.height, - unitDefault); - bool const heightChecked = !dialog_->Height->text().isEmpty() - && dialog_->Height->text() != "auto"; - dialog_->HeightCB->blockSignals(true); - dialog_->HeightCB->setChecked(heightChecked); - dialog_->HeightCB->blockSignals(false); - dialog_->Height->setEnabled(heightChecked); - dialog_->heightUnit->setEnabled(heightChecked); - - dialog_->scaleCB->setEnabled(!widthChecked && !heightChecked); - dialog_->WidthCB->setEnabled(!scaleChecked); - dialog_->HeightCB->setEnabled(!scaleChecked); - dialog_->aspectratio->setEnabled(widthChecked && heightChecked); - - dialog_->setAutoText(); - - dialog_->angle->setText(toqstr(igp.rotateAngle)); - dialog_->rotateOrderCB->setChecked(igp.scaleBeforeRotation); - - dialog_->rotateOrderCB->setEnabled((widthChecked || - heightChecked || - scaleChecked) && - (igp.rotateAngle != "0")); - - dialog_->origin->clear(); - - vector origindata = getRotationOriginData(); - vector const origin_lang = getFirst(origindata); - GuiGraphics::origin_ltx = getSecond(origindata); - - for (vector::const_iterator it = origin_lang.begin(); - it != origin_lang.end(); ++it) - dialog_->origin->addItem(toqstr(*it)); + scaleCB->blockSignals(true); + scaleCB->setChecked(scaleChecked); + scaleCB->blockSignals(false); + Scale->setEnabled(scaleChecked); + displayGB->setEnabled(lyxrc.display_graphics); + + set grp; + graphics::getGraphicsGroups(buffer(), grp); + set::const_iterator it = grp.begin(); + set::const_iterator end = grp.end(); + groupCO->blockSignals(true); + groupCO->clear(); + for (; it != end; it++) + groupCO->addItem(toqstr(*it), toqstr(*it)); + groupCO->insertItem(0, qt_("None"), QString()); + if (igp.groupId.empty()) + groupCO->setCurrentIndex(0); + else + groupCO->setCurrentIndex( + groupCO->findData(toqstr(igp.groupId), Qt::MatchExactly)); + groupCO->blockSignals(false); - if (!igp.rotateOrigin.empty()) - dialog_->origin->setCurrentIndex( - getItemNo(origin_ltx, igp.rotateOrigin)); + if (igp.width.value() == 0) + lengthToWidgets(Width, widthUnit, _(autostr), defaultUnit); else - dialog_->origin->setCurrentIndex(0); + lengthToWidgets(Width, widthUnit, igp.width, defaultUnit); - // disable edit button when no filename is present - dialog_->editPB->setDisabled(dialog_->filename->text().isEmpty()); + bool const widthChecked = !Width->text().isEmpty() && + Width->text() != qt_(autostr); + WidthCB->blockSignals(true); + WidthCB->setChecked(widthChecked); + WidthCB->blockSignals(false); + Width->setEnabled(widthChecked); + widthUnit->setEnabled(widthChecked); + + if (igp.height.value() == 0) + lengthToWidgets(Height, heightUnit, _(autostr), defaultUnit); + else + lengthToWidgets(Height, heightUnit, igp.height, defaultUnit); - //// latex section - dialog_->latexoptions->setText(toqstr(igp.special)); + bool const heightChecked = !Height->text().isEmpty() + && Height->text() != qt_(autostr); + 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(); + + doubleToWidget(angle, igp.rotateAngle); + rotateOrderCB->setChecked(igp.scaleBeforeRotation); + + rotateOrderCB->setEnabled( (widthChecked || heightChecked || scaleChecked) + && igp.rotateAngle != "0"); + + origin->clear(); + + for (size_t i = 0; i < rorigin_size; i++) { + origin->addItem(qt_(rorigin_gui_strs[i]), + toqstr(rorigin_lyx_strs[i])); + } + + if (!igp.rotateOrigin.empty()) + origin->setCurrentIndex(origin->findData(toqstr(igp.rotateOrigin))); + else + origin->setCurrentIndex(0); + + // latex section + latexoptions->setText(toqstr(igp.special)); + // cf bug #3852 + filename->setFocus(); } -void GuiGraphics::apply() +void GuiGraphics::applyView() { - InsetGraphicsParams & igp = controller().params(); + InsetGraphicsParams & igp = params_; - igp.filename.set(internal_path(fromqstr(dialog_->filename->text())), - kernel().bufferFilepath()); + igp.filename.set(fromqstr(filename->text()), fromqstr(bufferFilepath())); // the bb section igp.bb.erase(); - if (controller().bbChanged) { + if (bbChanged) { string bb; - string lbX(fromqstr(dialog_->lbX->text())); - string lbY(fromqstr(dialog_->lbY->text())); - string rtX(fromqstr(dialog_->rtX->text())); - string rtY(fromqstr(dialog_->rtY->text())); + string lbXs = widgetToDoubleStr(lbX); + string lbYs = widgetToDoubleStr(lbY); + string rtXs = widgetToDoubleStr(rtX); + string rtYs = widgetToDoubleStr(rtY); int bb_sum = - convert(lbX) + convert(lbY) + - convert(rtX) + convert(rtX); + convert(lbXs) + convert(lbYs) + + convert(rtXs) + convert(rtXs); if (bb_sum) { - if (lbX.empty()) + if (lbXs.empty()) bb = "0 "; else - bb = lbX + fromqstr(dialog_->lbXunit->currentText()) + ' '; - if (lbY.empty()) + bb = lbXs + fromqstr(lbXunit->currentText()) + ' '; + if (lbYs.empty()) bb += "0 "; else - bb += (lbY + fromqstr(dialog_->lbYunit->currentText()) + ' '); - if (rtX.empty()) + bb += (lbYs + fromqstr(lbYunit->currentText()) + ' '); + if (rtXs.empty()) bb += "0 "; else - bb += (rtX + fromqstr(dialog_->rtXunit->currentText()) + ' '); - if (rtY.empty()) + bb += (rtXs + fromqstr(rtXunit->currentText()) + ' '); + if (rtYs.empty()) bb += '0'; else - bb += (rtY + fromqstr(dialog_->rtYunit->currentText())); + bb += (rtYs + fromqstr(rtYunit->currentText())); igp.bb = bb; } } - igp.draft = dialog_->draftCB->isChecked(); - igp.clip = dialog_->clip->isChecked(); - igp.subcaption = dialog_->subfigure->isChecked(); - igp.subcaptionText = fromqstr(dialog_->subcaption->text()); - - switch (dialog_->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 (!dialog_->displayGB->isChecked()) - igp.display = graphics::NoDisplay; + igp.draft = draftCB->isChecked(); + igp.clip = clip->isChecked(); + igp.display = displayGB->isChecked(); //the graphics section - if (dialog_->scaleCB->isChecked() && !dialog_->Scale->text().isEmpty()) { - igp.scale = fromqstr(dialog_->Scale->text()); + if (scaleCB->isChecked() && !Scale->text().isEmpty()) { + igp.scale = widgetToDoubleStr(Scale); igp.width = Length("0pt"); igp.height = Length("0pt"); igp.keepAspectRatio = false; } else { igp.scale = string(); - igp.width = dialog_->WidthCB->isChecked() ? - //Note that this works even if dialog_->Width is "auto", since in + igp.width = WidthCB->isChecked() ? + //Note that this works even if Width is "auto", since in //that case we get "0pt". - Length(widgetsToLength(dialog_->Width, dialog_->widthUnit)): + Length(widgetsToLength(Width, widthUnit)): Length("0pt"); - igp.height = dialog_->HeightCB->isChecked() ? - Length(widgetsToLength(dialog_->Height, dialog_->heightUnit)) : + igp.height = HeightCB->isChecked() ? + Length(widgetsToLength(Height, heightUnit)) : Length("0pt"); - igp.keepAspectRatio = dialog_->aspectratio->isEnabled() && - dialog_->aspectratio->isChecked() && + igp.keepAspectRatio = aspectratio->isEnabled() && + aspectratio->isChecked() && igp.width.value() > 0 && igp.height.value() > 0; } - igp.noUnzip = dialog_->unzipCB->isChecked(); - - igp.lyxscale = convert(fromqstr(dialog_->displayscale->text())); + igp.noUnzip = unzipCB->isChecked(); + igp.lyxscale = displayscale->text().toInt(); + igp.rotateAngle = widgetToDoubleStr(angle); - igp.rotateAngle = fromqstr(dialog_->angle->text()); - - double rotAngle = convert(igp.rotateAngle); - if (std::abs(rotAngle) > 360.0) { + double rotAngle = widgetToDouble(angle); + if (abs(rotAngle) > 360.0) { rotAngle -= 360.0 * floor(rotAngle / 360.0); igp.rotateAngle = convert(rotAngle); } @@ -653,45 +719,127 @@ void GuiGraphics::apply() // save the latex name for the origin. If it is the default // then origin_ltx returns "" igp.rotateOrigin = - GuiGraphics::origin_ltx[dialog_->origin->currentIndex()]; - - igp.scaleBeforeRotation = dialog_->rotateOrderCB->isChecked(); + fromqstr(origin->itemData(origin->currentIndex()).toString()); + igp.scaleBeforeRotation = rotateOrderCB->isChecked(); // more latex options - igp.special = fromqstr(dialog_->latexoptions->text()); + igp.special = fromqstr(latexoptions->text()); + + igp.groupId = fromqstr(groupCO->itemData( + groupCO->currentIndex()).toString()); + current_group_ = igp.groupId; } void GuiGraphics::getBB() { - string const filename(fromqstr(dialog_->filename->text())); - if (!filename.empty()) { - string const bb(controller().readBB(filename)); - if (!bb.empty()) { - dialog_->lbX->setText(toqstr(token(bb, ' ', 0))); - dialog_->lbY->setText(toqstr(token(bb, ' ', 1))); - dialog_->rtX->setText(toqstr(token(bb, ' ', 2))); - dialog_->rtY->setText(toqstr(token(bb, ' ', 3))); - // the default units for the bb values when reading - // it from the file - dialog_->lbXunit->setCurrentIndex(0); - dialog_->lbYunit->setCurrentIndex(0); - dialog_->rtXunit->setCurrentIndex(0); - dialog_->rtYunit->setCurrentIndex(0); + string const fn = fromqstr(filename->text()); + if (fn.empty()) + return; + string const bb = readBoundingBox(fn); + bbChanged = false; + if (bb.empty()) + return; + doubleToWidget(lbX, token(bb, ' ', 0)); + doubleToWidget(lbY, token(bb, ' ', 1)); + doubleToWidget(rtX, token(bb, ' ', 2)); + doubleToWidget(rtY, 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) +{ + InsetGraphics::string2params(data, buffer(), params_); + paramsToDialog(params_); + current_group_ = params_.groupId; + return true; +} + + +void GuiGraphics::clearParams() +{ + params_ = InsetGraphicsParams(); +} + + +void GuiGraphics::dispatchParams() +{ + InsetGraphicsParams tmp_params(params_); + string const lfun = InsetGraphics::params2string(tmp_params, buffer()); + dispatch(FuncRequest(getLfun(), lfun)); +} + + +QString GuiGraphics::browse(QString const & in_name) const +{ + QString const title = qt_("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.isDirectory()) + clipdir = addName(package().system_support().absFilename(), "clipart"); + + return browseRelFile(in_name, bufferFilepath(), + title, fileFilters(QString()), false, + qt_("Clipart|#C#c"), toqstr(clipdir), + qt_("Documents|#o#O"), toqstr(lyxrc.document_path)); +} + + +string GuiGraphics::readBoundingBox(string const & file) +{ + FileName const abs_file = support::makeAbsPath(file, fromqstr(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(); } - controller().bbChanged = false; } + + return ("0 0 " + convert(width) + ' ' + convert(height)); } -bool GuiGraphics::isValid() +bool GuiGraphics::isFileNameValid(string const & fname) const { - return !dialog_->filename->text().isEmpty(); + // It may be that the filename is relative. + return support::makeAbsPath(fname, fromqstr(bufferFilepath())).isReadableFile(); } -} // namespace frontend -} // namespace lyx +Dialog * createGuiGraphics(GuiView & lv) { return new GuiGraphics(lv); } -#include "GuiGraphics_moc.cpp" +} // namespace frontend +} // namespace lyx + +#include "moc_GuiGraphics.cpp"