]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt2/QGraphics.C
the convert patch
[lyx.git] / src / frontends / qt2 / QGraphics.C
index 40a8bc4565927fdbc25fc6203dbe70185acdc725..6589682058dfc27ff3f22a9cddb48ee0c59d8746 100644 (file)
@@ -1,36 +1,62 @@
 /**
  * \file QGraphics.C
- * Copyright 2001 the LyX Team
- * Read the file COPYING
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
  *
- * \author John Levon <moz@compsoc.man.ac.uk>
+ * \author John Levon
+ * \author Edwin Leuven
+ * \author Herbert Voß
+ *
+ * Full author contact details are available in file CREDITS.
  */
 
 #include <config.h>
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
+#include "QGraphics.h"
 
+#include "checkedwidgets.h"
+#include "lengthcombo.h"
 #include "QGraphicsDialog.h"
-#include "ControlGraphics.h"
-#include "QGraphics.h"
 #include "Qt2BC.h"
-#include "gettext.h"
-#include "debug.h" 
+#include "qt_helpers.h"
+
+#include "lengthcommon.h"
+#include "lyxrc.h"
 
+#include "controllers/ControlGraphics.h"
+#include "controllers/helper_funcs.h"
+
+#include "insets/insetgraphicsParams.h"
+
+#include "support/convert.h"
 #include "support/lstrings.h"
+#include "support/lyxlib.h"
+
 #include <qlineedit.h>
 #include <qpushbutton.h>
 #include <qcheckbox.h>
-#include <qradiobutton.h>
-#include <qcombobox.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+
+#include <cmath>
 
-typedef Qt2CB<ControlGraphics, Qt2DB<QGraphicsDialog> > base_class;
+using lyx::support::float_equal;
+using lyx::support::token;
 
-QGraphics::QGraphics(ControlGraphics & c)
-       : base_class(c, _("Graphics"))
+#ifndef CXX_GLOBAL_CSTD
+using std::floor;
+#endif
+
+using std::vector;
+using std::string;
+
+namespace lyx {
+namespace frontend {
+
+typedef QController<ControlGraphics, QView<QGraphicsDialog> > base_class;
+
+QGraphics::QGraphics(Dialog & parent)
+       : base_class(parent, _("LyX: Graphics"))
 {
 }
 
@@ -39,139 +65,369 @@ void QGraphics::build_dialog()
 {
        dialog_.reset(new QGraphicsDialog(this));
 
-       bc().setOK(dialog_->okPB);
-       bc().setApply(dialog_->applyPB);
-       bc().setCancel(dialog_->closePB);
-       bc().addReadOnly(dialog_->filenameED);
-       bc().addReadOnly(dialog_->browsePB);
-       bc().addReadOnly(dialog_->widthED);
-       bc().addReadOnly(dialog_->widthCO);
-       bc().addReadOnly(dialog_->heightED);
-       bc().addReadOnly(dialog_->heightCO);
-       bc().addReadOnly(dialog_->scaleCB);
-       bc().addReadOnly(dialog_->rotateED);
-       bc().addReadOnly(dialog_->monochromeRB);
-       bc().addReadOnly(dialog_->grayscaleRB);
-       bc().addReadOnly(dialog_->colorRB);
-       bc().addReadOnly(dialog_->dontRB);
-       bc().addReadOnly(dialog_->subcaptionED);
+       bcview().setOK(dialog_->okPB);
+       bcview().setApply(dialog_->applyPB);
+       bcview().setRestore(dialog_->restorePB);
+       bcview().setCancel(dialog_->closePB);
+
+       bcview().addReadOnly(dialog_->rotateGB);
+       bcview().addReadOnly(dialog_->latexoptions);
+       bcview().addReadOnly(dialog_->subfigure);
+       bcview().addReadOnly(dialog_->subcaption);
+       bcview().addReadOnly(dialog_->filenameL);
+       bcview().addReadOnly(dialog_->filename);
+       bcview().addReadOnly(dialog_->browsePB);
+       bcview().addReadOnly(dialog_->unzipCB);
+       bcview().addReadOnly(dialog_->filename);
+       bcview().addReadOnly(dialog_->lbX);
+       bcview().addReadOnly(dialog_->lbY);
+       bcview().addReadOnly(dialog_->rtX);
+       bcview().addReadOnly(dialog_->rtY);
+       bcview().addReadOnly(dialog_->lbXunit);
+       bcview().addReadOnly(dialog_->lbYunit);
+       bcview().addReadOnly(dialog_->rtXunit);
+       bcview().addReadOnly(dialog_->rtYunit);
+       bcview().addReadOnly(dialog_->draftCB);
+       bcview().addReadOnly(dialog_->clip);
+       bcview().addReadOnly(dialog_->unzipCB);
+       bcview().addReadOnly(dialog_->subfigure);
+       bcview().addReadOnly(dialog_->subcaption);
+       bcview().addReadOnly(dialog_->showCB);
+       bcview().addReadOnly(dialog_->width);
+       bcview().addReadOnly(dialog_->height);
+       bcview().addReadOnly(dialog_->displayCB);
+       bcview().addReadOnly(dialog_->displayscale);
+       bcview().addReadOnly(dialog_->widthUnit);
+       bcview().addReadOnly(dialog_->heightUnit);
+       bcview().addReadOnly(dialog_->aspectratio);
+       bcview().addReadOnly(dialog_->angle);
+       bcview().addReadOnly(dialog_->origin);
+       bcview().addReadOnly(dialog_->latexoptions);
+       bcview().addReadOnly(dialog_->getPB);
+
+       // initialize the length validator
+       addCheckedLineEdit(bcview(), dialog_->width, dialog_->sizewidthL_2);
+       addCheckedLineEdit(bcview(), dialog_->height, dialog_->sizeheightL_2);
+       addCheckedLineEdit(bcview(), dialog_->displayscale, dialog_->scaleLA);
+       addCheckedLineEdit(bcview(), dialog_->angle, dialog_->angleL_2);
+       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);
 }
 
 
 namespace {
-       string const numtostr(double val) {
-               string a(tostr(val));
-               if (a == "0")
-                       a = "";
-               return a;
-       }
-} // namespace anon
+
+// returns the number of the string s in the vector v
+int getItemNo(vector<string> v, string const & s) {
+       vector<string>::const_iterator cit =
+                   find(v.begin(), v.end(), s);
+       return (cit != v.end()) ? int(cit - v.begin()) : 0;
+}
+
+}
+
+
 void QGraphics::update_contents()
 {
+       // clear and fill in the comboboxes
+       vector<string> const bb_units = lyx::frontend::getBBUnits();
+       dialog_->lbXunit->clear();
+       dialog_->lbYunit->clear();
+       dialog_->rtXunit->clear();
+       dialog_->rtYunit->clear();
+       for (vector<string>::const_iterator it = bb_units.begin();
+           it != bb_units.end(); ++it) {
+               dialog_->lbXunit->insertItem(toqstr(*it), -1);
+               dialog_->lbYunit->insertItem(toqstr(*it), -1);
+               dialog_->rtXunit->insertItem(toqstr(*it), -1);
+               dialog_->rtYunit->insertItem(toqstr(*it), -1);
+       }
+
        InsetGraphicsParams & igp = controller().params();
 
-       dialog_->filenameED->setText(igp.filename.c_str());
-       QRadioButton * button;
-       switch (igp.display) {
-               case InsetGraphicsParams::COLOR: button = dialog_->colorRB; break;
-               case InsetGraphicsParams::GRAYSCALE: button = dialog_->grayscaleRB; break;
-               case InsetGraphicsParams::MONOCHROME: button = dialog_->monochromeRB; break;
-               case InsetGraphicsParams::NONE: button = dialog_->dontRB; break;
+       // set the right default unit
+       LyXLength::UNIT unitDefault = LyXLength::CM;
+       switch (lyxrc.default_papersize) {
+               case PAPER_DEFAULT: break;
+
+               case PAPER_USLETTER:
+               case PAPER_LEGALPAPER:
+               case PAPER_EXECUTIVEPAPER:
+                       unitDefault = LyXLength::IN;
+                       break;
+
+               case PAPER_A3PAPER:
+               case PAPER_A4PAPER:
+               case PAPER_A5PAPER:
+               case PAPER_B5PAPER:
+                       unitDefault = LyXLength::CM;
+                       break;
+       }
+
+       string const name =
+               igp.filename.outputFilename(kernel().bufferFilepath());
+       dialog_->filename->setText(toqstr(name));
+
+       // set the bounding box values
+       if (igp.bb.empty()) {
+               string const bb = controller().readBB(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->setCurrentItem(0);
+               dialog_->lbYunit->setCurrentItem(0);
+               dialog_->rtXunit->setCurrentItem(0);
+               dialog_->rtYunit->setCurrentItem(0);
+               controller().bbChanged = false;
+       } else {
+               // get the values from the inset
+               LyXLength 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)) {
+                       dialog_->lbX->setText(toqstr(convert<string>(anyLength.value())));
+                       string const unit(unit_name[anyLength.unit()]);
+                       dialog_->lbXunit->setCurrentItem(getItemNo(bb_units, unit));
+               } else {
+                       dialog_->lbX->setText(toqstr(xl));
+               }
+               if (isValidLength(yl, &anyLength)) {
+                       dialog_->lbY->setText(toqstr(convert<string>(anyLength.value())));
+                       string const unit(unit_name[anyLength.unit()]);
+                       dialog_->lbYunit->setCurrentItem(getItemNo(bb_units, unit));
+               } else {
+                       dialog_->lbY->setText(toqstr(xl));
+               }
+               if (isValidLength(xr, &anyLength)) {
+                       dialog_->rtX->setText(toqstr(convert<string>(anyLength.value())));
+                       string const unit(unit_name[anyLength.unit()]);
+                       dialog_->rtXunit->setCurrentItem(getItemNo(bb_units, unit));
+               } else {
+                       dialog_->rtX->setText(toqstr(xl));
+               }
+               if (isValidLength(yr, &anyLength)) {
+                       dialog_->rtY->setText(toqstr(convert<string>(anyLength.value())));
+                       string const unit(unit_name[anyLength.unit()]);
+                       dialog_->rtYunit->setCurrentItem(getItemNo(bb_units, unit));
+               } else {
+                       dialog_->rtY->setText(toqstr(xl));
+               }
+               controller().bbChanged = true;
        }
-       button->setChecked(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.widthResize) {
-               case InsetGraphicsParams::INCH: item = 1; break;
-               case InsetGraphicsParams::PERCENT_PAGE: item = 2; break;
-               case InsetGraphicsParams::PERCENT_COLUMN: item = 3; break;
-               default: break;
+       switch (igp.display) {
+               case lyx::graphics::DefaultDisplay: item = 0; break;
+               case lyx::graphics::MonochromeDisplay: item = 1; break;
+               case lyx::graphics::GrayscaleDisplay: item = 2; break;
+               case lyx::graphics::ColorDisplay: item = 3; break;
+               case lyx::graphics::NoDisplay: item = 0; break;
        }
-       dialog_->widthCO->setCurrentItem(item);
-       item = 0;
-       switch (igp.heightResize) {
-               case InsetGraphicsParams::INCH: item = 1; break;
-               case InsetGraphicsParams::PERCENT_PAGE: item = 2; break;
-               default: break;
+       dialog_->showCB->setCurrentItem(item);
+       dialog_->showCB->setEnabled(igp.display != lyx::graphics::NoDisplay && !readOnly());
+       dialog_->displayCB->setChecked(igp.display != lyx::graphics::NoDisplay);
+       dialog_->displayscale->setEnabled(igp.display != lyx::graphics::NoDisplay && !readOnly());
+       dialog_->displayscale->setText(toqstr(convert<string>(igp.lyxscale)));
+
+       //// the output section (width/height)
+       // set the length combo boxes
+       // only the width has the possibility for scale%. The original
+       // units are defined in lengthcommon.C
+       // 1. the width (a listttype)
+       dialog_->widthUnit->clear();
+       dialog_->widthUnit->insertItem(qt_("Scale%"));
+       for (int i = 0; i < num_units; i++)
+               dialog_->widthUnit->insertItem(unit_name_gui[i], -1);
+
+       if (!igp.scale.empty()
+               && !float_equal(convert<double>(igp.scale), 0.0, 0.05)) {
+               dialog_->width->setText(toqstr(igp.scale));
+               dialog_->widthUnit->setCurrentItem(0);
+       } else {
+               // no scale means default width/height
+               dialog_->width->setText(toqstr(convert<string>(igp.width.value())));
+               // the width cannot have a unitDefault, because
+               // it is a "Scale%" or another user defined unit!
+               // +1 instead of the "Scale%" option
+               int unit_ = igp.width.unit();
+               dialog_->widthUnit->setCurrentItem(unit_ + 1);
        }
-       dialog_->heightCO->setCurrentItem(item);
-       // FIXME: scale ???
-       dialog_->widthED->setText(numtostr(igp.widthSize).c_str());
-       dialog_->heightED->setText(numtostr(igp.heightSize).c_str());
-       dialog_->rotateED->setText(numtostr(igp.rotateAngle).c_str());
-       dialog_->subcaptionED->setText(igp.subcaptionText.c_str());
+       // 2. the height (a lengthgcombo type)
+       lengthToWidgets(dialog_->height, dialog_->heightUnit,
+               igp.height.asString(), unitDefault);
+
+       // enable height input in case of non "Scale%" as width-unit
+       bool use_height = (dialog_->widthUnit->currentItem() > 0);
+       dialog_->height->setEnabled(use_height);
+       dialog_->heightUnit->setEnabled(use_height);
+
+       dialog_->aspectratio->setChecked(igp.keepAspectRatio);
+
+       dialog_->angle->setText(toqstr(igp.rotateAngle));
+
+       dialog_->origin->clear();
+
+       using namespace lyx::frontend;
+       vector<RotationOriginPair> origindata = getRotationOriginData();
+       vector<string> const origin_lang = getFirst(origindata);
+       QGraphics::origin_ltx = getSecond(origindata);
+
+       for (vector<string>::const_iterator it = origin_lang.begin();
+           it != origin_lang.end(); ++it)
+               dialog_->origin->insertItem(toqstr(*it), -1);
+
+       if (!igp.rotateOrigin.empty())
+               dialog_->origin->setCurrentItem(
+                       getItemNo(origin_ltx, igp.rotateOrigin));
+       else
+               dialog_->origin->setCurrentItem(0);
+
+       //// latex section
+       dialog_->latexoptions->setText(toqstr(igp.special));
 }
 
 
 void QGraphics::apply()
 {
        InsetGraphicsParams & igp = controller().params();
-       if (dialog_->colorRB->isChecked())
-               igp.display = InsetGraphicsParams::COLOR;
-       else if (dialog_->grayscaleRB->isChecked())
-               igp.display = InsetGraphicsParams::GRAYSCALE;
-       else if (dialog_->monochromeRB->isChecked())
-               igp.display = InsetGraphicsParams::MONOCHROME;
-       else
-               igp.display = InsetGraphicsParams::NONE;
-        
-       igp.subcaptionText = dialog_->subcaptionED->text().latin1();
-       igp.subcaption = !igp.subcaptionText.empty();
-
-       switch (dialog_->widthCO->currentItem()) {
-               case 0: igp.widthResize = InsetGraphicsParams::CM; break;
-               case 1: igp.widthResize = InsetGraphicsParams::INCH; break;
-               case 2: igp.widthResize = InsetGraphicsParams::PERCENT_PAGE; break;
-               case 3: igp.widthResize = InsetGraphicsParams::PERCENT_COLUMN; break;
-               default:;
-       }
-       if (string(dialog_->widthED->text().latin1()).empty()) {
-               igp.widthResize = InsetGraphicsParams::DEFAULT_SIZE;
-               igp.widthSize = 0.0; 
-       } else {
-               igp.widthSize = strToDbl(dialog_->widthED->text().latin1());
+
+       igp.filename.set(fromqstr(dialog_->filename->text()),
+                        kernel().bufferFilepath());
+
+       // the bb section
+       igp.bb.erase();
+       if (controller().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()));
+               int bb_sum =
+                       convert<int>(lbX) + convert<int>(lbY) +
+                       convert<int>(rtX) + convert<int>(rtX);
+               if (bb_sum) {
+                       if (lbX.empty())
+                               bb = "0 ";
+                       else
+                               bb = lbX + fromqstr(dialog_->lbXunit->currentText()) + ' ';
+                       if (lbY.empty())
+                               bb += "0 ";
+                       else
+                               bb += (lbY + fromqstr(dialog_->lbYunit->currentText()) + ' ');
+                       if (rtX.empty())
+                               bb += "0 ";
+                       else
+                               bb += (rtX + fromqstr(dialog_->rtXunit->currentText()) + ' ');
+                       if (rtY.empty())
+                               bb += '0';
+                       else
+                               bb += (rtY + fromqstr(dialog_->rtYunit->currentText()));
+                       igp.bb = bb;
+               }
        }
-       switch (dialog_->heightCO->currentItem()) {
-               case 0: igp.heightResize = InsetGraphicsParams::CM; break;
-               case 1: igp.heightResize = InsetGraphicsParams::INCH; break;
-               case 2: igp.heightResize = InsetGraphicsParams::PERCENT_PAGE; break;
+
+       igp.draft = dialog_->draftCB->isChecked();
+       igp.clip = dialog_->clip->isChecked();
+       igp.subcaption = dialog_->subfigure->isChecked();
+       igp.subcaptionText = fromqstr(dialog_->subcaption->text());
+
+       switch (dialog_->showCB->currentItem()) {
+               case 0: igp.display = lyx::graphics::DefaultDisplay; break;
+               case 1: igp.display = lyx::graphics::MonochromeDisplay; break;
+               case 2: igp.display = lyx::graphics::GrayscaleDisplay; break;
+               case 3: igp.display = lyx::graphics::ColorDisplay; break;
                default:;
        }
-       if (string(dialog_->heightED->text().latin1()).empty()) {
-               igp.heightResize = InsetGraphicsParams::DEFAULT_SIZE;
-               igp.heightSize = 0.0; 
+
+       if (!dialog_->displayCB->isChecked())
+               igp.display = lyx::graphics::NoDisplay;
+
+       string value = fromqstr(dialog_->width->text());
+       if (dialog_->widthUnit->currentItem() > 0 || isValidLength(value)) {
+               // width/height combination
+               igp.width =
+                       widgetsToLength(dialog_->width, dialog_->widthUnit);
+               igp.scale = string();
        } else {
-               igp.heightSize = strToDbl(dialog_->heightED->text().latin1());
-       } 
+               // scaling instead of a width
+               igp.scale = value;
+               igp.width = LyXLength();
+       }
+       value = fromqstr(dialog_->height->text());
+       igp.height =
+               LyXLength(widgetsToLength(dialog_->height, dialog_->heightUnit));
+
+       igp.keepAspectRatio = dialog_->aspectratio->isChecked();
 
-       // FIXME: scale ??? 
+       igp.noUnzip = dialog_->unzipCB->isChecked();
 
-       igp.rotateAngle = strToDbl(dialog_->rotateED->text().latin1());
+       igp.lyxscale = convert<int>(fromqstr(dialog_->displayscale->text()));
 
-       igp.filename = dialog_->filenameED->text().latin1();
+       igp.rotateAngle = fromqstr(dialog_->angle->text());
+
+       double rotAngle = convert<double>(igp.rotateAngle);
+       if (std::abs(rotAngle) > 360.0) {
+               rotAngle -= 360.0 * floor(rotAngle / 360.0);
+               igp.rotateAngle = convert<string>(rotAngle);
+       }
+
+       // save the latex name for the origin. If it is the default
+       // then origin_ltx returns ""
+       igp.rotateOrigin =
+               QGraphics::origin_ltx[dialog_->origin->currentItem()];
+
+       // more latex options
+       igp.special = fromqstr(dialog_->latexoptions->text());
 }
 
 
-void QGraphics::browse()
+void QGraphics::getBB()
 {
-       string const & name = controller().Browse(dialog_->filenameED->text().latin1());
-       if (!name.empty())
-               dialog_->filenameED->setText(name.c_str()); 
+       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->setCurrentItem(0);
+                       dialog_->lbYunit->setCurrentItem(0);
+                       dialog_->rtXunit->setCurrentItem(0);
+                       dialog_->rtYunit->setCurrentItem(0);
+               }
+               controller().bbChanged = false;
+       }
 }
 
 
 bool QGraphics::isValid()
 {
-       return !string(dialog_->filenameED->text().latin1()).empty();
+       return !dialog_->filename->text().isEmpty();
+}
+
+
+void QGraphics::slotEdit()
+{
+       controller().editGraphics();
 }
+
+} // namespace frontend
+} // namespace lyx