X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiGraphics.cpp;h=b48c2fd06f0c2231cc1d088a744e711538d37165;hb=ba76bf5eb85db5a10839fccee3430d906d3f7b70;hp=cc58105a845c0b1c7ff9ca440ec038984100ad6a;hpb=34492a9d033aef3d4369d4d758b01f3969ef3af0;p=lyx.git diff --git a/src/frontends/qt4/GuiGraphics.cpp b/src/frontends/qt4/GuiGraphics.cpp index cc58105a84..b48c2fd06f 100644 --- a/src/frontends/qt4/GuiGraphics.cpp +++ b/src/frontends/qt4/GuiGraphics.cpp @@ -3,6 +3,7 @@ * 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ß @@ -15,25 +16,33 @@ #include "GuiGraphics.h" -#include "ControlGraphics.h" -#include "debug.h" +#include "support/debug.h" #include "LengthCombo.h" -#include "lengthcommon.h" +#include "Length.h" #include "LyXRC.h" #include "qt_helpers.h" #include "Validator.h" -#include "controllers/frontend_helpers.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 @@ -41,41 +50,72 @@ #include #include +#include -using lyx::support::float_equal; -using lyx::support::token; - -using lyx::support::os::internal_path; - -#ifndef CXX_GLOBAL_CSTD -using std::floor; -#endif - -using std::vector; -using std::string; - +using namespace std; +using namespace lyx::support; 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 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 -std::vector const -getFirst(std::vector const & pr) +vector const +getFirst(vector const & pr) { - std::vector tmp(pr.size()); - std::transform(pr.begin(), pr.end(), tmp.begin(), - boost::bind(&Pair::first, _1)); + vector tmp(pr.size()); + transform(pr.begin(), pr.end(), tmp.begin(), + boost::bind(&Pair::first, _1)); return tmp; } -GuiGraphicsDialog::GuiGraphicsDialog(LyXView & lv) - : GuiDialog(lv, "graphics") +/// +template +vector const +getSecond(vector const & pr) { - setupUi(this); - setViewTitle(_("Graphics")); - setController(new ControlGraphics(*this)); + vector tmp(pr.size()); + transform(pr.begin(), pr.end(), tmp.begin(), + boost::bind(&Pair::second, _1)); + return tmp; +} + +/// The (tranlated) GUI string and it's LaTeX equivalent. +typedef pair RotationOriginPair; +/// +vector getRotationOriginData(); + +GuiGraphics::GuiGraphics(GuiView & lv) + : GuiDialog(lv, "graphics", qt_("Graphics")) +{ + setupUi(this); + //main buttons connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK())); connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply())); @@ -85,6 +125,8 @@ GuiGraphicsDialog::GuiGraphicsDialog(LyXView & lv) //graphics pane connect(filename, SIGNAL(textChanged(const QString &)), this, SLOT(change_adaptor())); + connect(embedCB, SIGNAL(toggled(bool)), + this, SLOT(change_adaptor())); connect(WidthCB, SIGNAL( clicked()), this, SLOT(change_adaptor())); connect(HeightCB, SIGNAL( clicked()), @@ -211,64 +253,50 @@ GuiGraphicsDialog::GuiGraphicsDialog(LyXView & lv) } -ControlGraphics & GuiGraphicsDialog::controller() const -{ - return static_cast(GuiDialog::controller()); -} - - -void GuiGraphicsDialog::change_adaptor() +void GuiGraphics::change_adaptor() { changed(); } -void GuiGraphicsDialog::change_bb() +void GuiGraphics::change_bb() { - controller().bbChanged = true; - LYXERR(Debug::GRAPHICS) - << "[controller().bb_Changed set to true]\n"; + bbChanged = true; + LYXERR(Debug::GRAPHICS, "[bb_Changed set to true]"); changed(); } -void GuiGraphicsDialog::closeEvent(QCloseEvent * e) -{ - slotClose(); - e->accept(); -} - - -void GuiGraphicsDialog::on_browsePB_clicked() +void GuiGraphics::on_browsePB_clicked() { - docstring const str = - controller().browse(qstring_to_ucs4(filename->text())); - if(!str.empty()){ + docstring const str = browse(qstring_to_ucs4(filename->text())); + if (!str.empty()) { filename->setText(toqstr(str)); changed(); } } -void GuiGraphicsDialog::on_getPB_clicked() +void GuiGraphics::on_getPB_clicked() { getBB(); } -void GuiGraphicsDialog::on_editPB_clicked() +void GuiGraphics::on_editPB_clicked() { - controller().editGraphics(); + editGraphics(); } -void GuiGraphicsDialog::on_filename_textChanged(const QString & filename) +void GuiGraphics::on_filename_textChanged(const QString & filename) { editPB->setDisabled(filename.isEmpty()); + EmbeddedFile file = EmbeddedFile(fromqstr(filename), bufferFilepath()); } -void GuiGraphicsDialog::setAutoText() +void GuiGraphics::setAutoText() { if (scaleCB->isChecked()) return; @@ -280,7 +308,7 @@ void GuiGraphicsDialog::setAutoText() } -void GuiGraphicsDialog::on_scaleCB_toggled(bool setScale) +void GuiGraphics::on_scaleCB_toggled(bool setScale) { Scale->setEnabled(setScale); if (setScale) { @@ -314,7 +342,7 @@ void GuiGraphicsDialog::on_scaleCB_toggled(bool setScale) } -void GuiGraphicsDialog::on_WidthCB_toggled(bool setWidth) +void GuiGraphics::on_WidthCB_toggled(bool setWidth) { Width->setEnabled(setWidth); widthUnit->setEnabled(setWidth); @@ -339,7 +367,7 @@ void GuiGraphicsDialog::on_WidthCB_toggled(bool setWidth) } -void GuiGraphicsDialog::on_HeightCB_toggled(bool setHeight) +void GuiGraphics::on_HeightCB_toggled(bool setHeight) { Height->setEnabled(setHeight); heightUnit->setEnabled(setHeight); @@ -364,7 +392,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() || @@ -381,7 +409,7 @@ static int getItemNo(const vector & v, string const & s) } -void GuiGraphicsDialog::update_contents() +void GuiGraphics::updateContents() { // clear and fill in the comboboxes vector const bb_units = frontend::getBBUnits(); @@ -397,7 +425,7 @@ void GuiGraphicsDialog::update_contents() rtYunit->addItem(toqstr(*it)); } - InsetGraphicsParams & igp = controller().params(); + InsetGraphicsParams & igp = params_; // set the right default unit Length::UNIT unitDefault = Length::CM; @@ -412,12 +440,13 @@ void GuiGraphicsDialog::update_contents() } string const name = - igp.filename.outputFilename(controller().bufferFilepath()); + 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 = controller().readBB(igp.filename.absFilename()); + 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))); @@ -427,14 +456,14 @@ void GuiGraphicsDialog::update_contents() lbYunit->setCurrentIndex(0); rtXunit->setCurrentIndex(0); rtYunit->setCurrentIndex(0); - controller().bbChanged = false; + 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)) { lbX->setText(toqstr(convert(anyLength.value()))); string const unit(unit_name[anyLength.unit()]); @@ -463,7 +492,7 @@ void GuiGraphicsDialog::update_contents() } else { rtY->setText(toqstr(xl)); } - controller().bbChanged = true; + bbChanged = true; } // Update the draft and clip mode @@ -554,16 +583,16 @@ void GuiGraphicsDialog::update_contents() } -void GuiGraphicsDialog::applyView() +void GuiGraphics::applyView() { - InsetGraphicsParams & igp = controller().params(); + InsetGraphicsParams & igp = params_; - igp.filename.set(internal_path(fromqstr(filename->text())), - controller().bufferFilepath()); + igp.filename.set(fromqstr(filename->text()), bufferFilepath()); + igp.filename.setEmbed(embedCB->checkState() == Qt::Checked); // the bb section igp.bb.erase(); - if (controller().bbChanged) { + if (bbChanged) { string bb; string lbXs = fromqstr(lbX->text()); string lbYs = fromqstr(lbY->text()); @@ -635,7 +664,7 @@ void GuiGraphicsDialog::applyView() igp.rotateAngle = fromqstr(angle->text()); double rotAngle = convert(igp.rotateAngle); - if (std::abs(rotAngle) > 360.0) { + if (abs(rotAngle) > 360.0) { rotAngle -= 360.0 * floor(rotAngle / 360.0); igp.rotateAngle = convert(rotAngle); } @@ -650,36 +679,173 @@ void GuiGraphicsDialog::applyView() } -void GuiGraphicsDialog::getBB() +void GuiGraphics::getBB() { string const fn = fromqstr(filename->text()); - if (!fn.empty()) { - string const bb = controller().readBB(fn); - if (!bb.empty()) { - 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); + 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(); } - controller().bbChanged = false; } + + return ("0 0 " + convert(width) + ' ' + convert(height)); } -bool GuiGraphicsDialog::isValid() +bool GuiGraphics::isFilenameValid(string const & fname) const { - return !filename->text().isEmpty(); + // 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" -