From 8b2a93c2bc22777be2cbbf69e7896b545fbbed31 Mon Sep 17 00:00:00 2001 From: Angus Leeming Date: Fri, 5 Dec 2003 02:49:22 +0000 Subject: [PATCH] The External dialog for Qt, + a validator for LyXLength + Widget checking. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8197 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/frontends/qt2/ChangeLog | 21 + src/frontends/qt2/Makefile.am | 1 + src/frontends/qt2/Makefile.dialogs | 1 + src/frontends/qt2/QExternal.C | 445 ++++- src/frontends/qt2/QExternal.h | 9 +- src/frontends/qt2/QExternalDialog.C | 147 +- src/frontends/qt2/QExternalDialog.h | 12 +- src/frontends/qt2/checkedwidgets.C | 69 + src/frontends/qt2/checkedwidgets.h | 38 + src/frontends/qt2/lengthvalidator.C | 54 + src/frontends/qt2/lengthvalidator.h | 40 + src/frontends/qt2/ui/QExternalDialogBase.ui | 1727 +++++++++++++------ 12 files changed, 1974 insertions(+), 590 deletions(-) create mode 100644 src/frontends/qt2/checkedwidgets.C create mode 100644 src/frontends/qt2/checkedwidgets.h create mode 100644 src/frontends/qt2/lengthvalidator.C create mode 100644 src/frontends/qt2/lengthvalidator.h diff --git a/src/frontends/qt2/ChangeLog b/src/frontends/qt2/ChangeLog index dd7e0ddc29..ccb76af699 100644 --- a/src/frontends/qt2/ChangeLog +++ b/src/frontends/qt2/ChangeLog @@ -1,3 +1,24 @@ +2003-12-04 Angus Leeming + + * lengthvalidator.[Ch]: a new class LengthValidator, derived from + QValidator enables us to validate that the input text is a LyXLength. + + * checkedwidgets.[Ch]: a new class CheckedLineEdit derived from + CheckedWidget enables us to add widgets to a list at build time. + Thereafter, their validity is checked automatically on each + input event, thus allowing us to 'remember' invalid widgets and + so control the state of the 'Apply', 'Ok' buttons. + As a bit of fun and to provide the user with some visual feedback, + the invalid widgets are displayed in red. + + * Makefile.am, Makefile.dialogs: add the new files. + + * QExternal.[Ch]: + * QExternalDialog.C: + * ui/QExternalDialogBase.ui: a total overhaul. In addition, the + dialog can now manipulate the transform data (rotate, scale, crop). + Makes full use of CheckedLineEdit. + 2003-12-01 Angus Leeming * QContentPane.[Ch] (SyntheticMouseEvent): a new, helper struct. diff --git a/src/frontends/qt2/Makefile.am b/src/frontends/qt2/Makefile.am index 2284d7e5e4..36fb2b10f9 100644 --- a/src/frontends/qt2/Makefile.am +++ b/src/frontends/qt2/Makefile.am @@ -70,6 +70,7 @@ libqt2_la_SOURCES = \ Qt2BC.C Qt2BC.h \ QtLyXView.h \ WorkAreaFactory.C \ + checkedwidgets.C checkedwidgets.h \ lyx_gui.C \ lcolorcache.h lcolorcache.C \ panelstack.h panelstack.C \ diff --git a/src/frontends/qt2/Makefile.dialogs b/src/frontends/qt2/Makefile.dialogs index 06bc5415cd..41a8a81f33 100644 --- a/src/frontends/qt2/Makefile.dialogs +++ b/src/frontends/qt2/Makefile.dialogs @@ -128,4 +128,5 @@ MOCFILES = \ QVSpaceDialog.C QVSpaceDialog.h \ QWrapDialog.C QWrapDialog.h \ QLToolbar.C QLToolbar.h \ + lengthvalidator.C lengthvalidator.h \ socket_callback.C socket_callback.h diff --git a/src/frontends/qt2/QExternal.C b/src/frontends/qt2/QExternal.C index da46a4c555..1c8032bd3a 100644 --- a/src/frontends/qt2/QExternal.C +++ b/src/frontends/qt2/QExternal.C @@ -4,6 +4,7 @@ * Licence details can be found in the file COPYING. * * \author John Levon + * \author Angus Leeming * * Full author contact details are available in file CREDITS. */ @@ -11,8 +12,10 @@ #include #include "debug.h" -#include "ControlExternal.h" -#include "qt_helpers.h" +#include "lengthcommon.h" +#include "lyxrc.h" + +#include "controllers/ControlExternal.h" #include "insets/ExternalTemplate.h" #include "insets/insetexternal.h" @@ -20,28 +23,259 @@ #include "support/lstrings.h" #include "support/tostr.h" +#include "QExternal.h" +#include "QExternalDialog.h" +#include "Qt2BC.h" + +#include "checkedwidgets.h" +#include "lengthcombo.h" +#include "qt_helpers.h" + #include #include #include #include +#include #include -#include "QExternalDialog.h" -#include "QExternal.h" -#include "Qt2BC.h" +namespace external = lyx::external; +using lyx::support::isStrDbl; +using lyx::support::strToDbl; using lyx::support::strToInt; +using lyx::support::token; using lyx::support::trim; using std::string; +using std::vector; + + +namespace { + +LyXLength::UNIT defaultUnit() +{ + LyXLength::UNIT default_unit = LyXLength::CM; + switch (lyxrc.default_papersize) { + case PAPER_USLETTER: + case PAPER_LEGALPAPER: + case PAPER_EXECUTIVEPAPER: + default_unit = LyXLength::IN; + break; + default: + break; + } + return default_unit; +} + + +void setDisplay(QCheckBox & displayCB, QComboBox & showCO, QLineEdit & scaleED, + external::DisplayType display, unsigned int scale, + bool read_only) +{ + int item = 0; + switch (display) { + case external::DefaultDisplay: + item = 0; + break; + case external::MonochromeDisplay: + item = 1; + break; + case external::GrayscaleDisplay: + item = 2; + break; + case external::ColorDisplay: + item = 3; + break; + case external::PreviewDisplay: + item = 4; + break; + case external::NoDisplay: + item = 0; + break; + } + + showCO.setCurrentItem(item); + bool const no_display = display == lyx::external::NoDisplay; + showCO.setEnabled(!no_display && !read_only); + displayCB.setChecked(!no_display); + scaleED.setEnabled(!no_display && !read_only); + scaleED.setText(toqstr(tostr(scale))); +} + + +void getDisplay(external::DisplayType & display, + unsigned int & scale, + QCheckBox const & displayCB, + QComboBox const & showCO, + QLineEdit const & scaleED) +{ + switch (showCO.currentItem()) { + case 0: + display = external::DefaultDisplay; + break; + case 1: + display = external::MonochromeDisplay; + break; + case 2: + display = external::GrayscaleDisplay; + break; + case 3: + display = external::ColorDisplay; + break; + case 4: + display = external::PreviewDisplay; + break; + } + + if (!displayCB.isChecked()) + display = external::NoDisplay; + + scale = strToInt(fromqstr(scaleED.text())); +} + + +void setRotation(QLineEdit & angleED, QComboBox & originCO, + external::RotationData const & data) +{ + originCO.setCurrentItem(int(data.origin())); + angleED.setText(toqstr(tostr(data.angle()))); +} + + +void getRotation(external::RotationData & data, + QLineEdit const & angleED, QComboBox const & originCO) +{ + typedef external::RotationData::OriginType OriginType; + + data.origin(static_cast(originCO.currentItem())); + data.angle(strToDbl(fromqstr(angleED.text()))); +} + + +void setSize(QLineEdit & widthED, QComboBox & widthUnitCO, + QLineEdit & heightED, LengthCombo & heightUnitCO, + QCheckBox & aspectratioCB, + external::ResizeData const & data) +{ + bool using_scale = data.usingScale(); + double scale = data.scale; + if (data.no_resize()) { + // Everything is zero, so default to this! + using_scale = true; + scale = 100; + } + + if (using_scale) { + widthED.setText(toqstr(tostr(scale))); + widthUnitCO.setCurrentItem(0); + } else { + widthED.setText(toqstr(tostr(data.width.value()))); + // Because 'Scale' is position 0... + // Note also that width cannot be zero here, so + // we don't need to worry about the default unit. + widthUnitCO.setCurrentItem(data.width.unit() + 1); + } + + string const h = data.height.zero() ? string() : data.height.asString(); + LyXLength::UNIT default_unit = data.width.zero() ? + defaultUnit() : data.width.unit(); + lengthToWidgets(&heightED, &heightUnitCO, h, default_unit); + + heightED.setEnabled(!using_scale); + heightUnitCO.setEnabled(!using_scale); + + aspectratioCB.setChecked(data.keepAspectRatio); + + bool const disable_aspectRatio = using_scale || + data.width.zero() || data.height.zero(); + aspectratioCB.setEnabled(!disable_aspectRatio); +} + + +void getSize(external::ResizeData & data, + QLineEdit const & widthED, QComboBox const & widthUnitCO, + QLineEdit const & heightED, LengthCombo const & heightUnitCO, + QCheckBox const & aspectratioCB) +{ + string const width = fromqstr(widthED.text()); + + if (widthUnitCO.currentItem() > 0) { + // Subtract one, because scale is 0. + int const unit = widthUnitCO.currentItem() - 1; + + LyXLength w; + if (isValidLength(width, &w)) + data.width = w; + else if (isStrDbl(width)) + data.width = LyXLength(strToDbl(width), + static_cast(unit)); + else + data.width = LyXLength(); + + data.scale = 0.0; + + } else { + // scaling instead of a width + data.scale = strToDbl(width); + data.width = LyXLength(); + } + + data.height = LyXLength(widgetsToLength(&heightED, &heightUnitCO)); + + data.keepAspectRatio = aspectratioCB.isChecked(); +} + + +void setCrop(QCheckBox & clipCB, + QLineEdit & xlED, QLineEdit & ybED, + QLineEdit & xrED, QLineEdit & ytED, + external::ClipData const & data) +{ + clipCB.setChecked(data.clip); + lyx::graphics::BoundingBox const & bbox = data.bbox; + xlED.setText(toqstr(tostr(bbox.xl))); + ybED.setText(toqstr(tostr(bbox.yb))); + xrED.setText(toqstr(tostr(bbox.xr))); + ytED.setText(toqstr(tostr(bbox.yt))); +} + + +void getCrop(external::ClipData & data, + QCheckBox const & clipCB, + QLineEdit const & xlED, QLineEdit const & ybED, + QLineEdit const & xrED, QLineEdit const & ytED, + bool bb_changed) +{ + data.clip = clipCB.isChecked(); + + if (!bb_changed) + return; + + data.bbox.xl = strToInt(fromqstr(xlED.text())); + data.bbox.yb = strToInt(fromqstr(ybED.text())); + data.bbox.xr = strToInt(fromqstr(xrED.text())); + data.bbox.yt = strToInt(fromqstr(ytED.text())); +} + + +void getExtra(external::ExtraData & data, + QExternal::MapType const & extra) +{ + typedef QExternal::MapType MapType; + MapType::const_iterator it = extra.begin(); + MapType::const_iterator const end = extra.end(); + for (; it != end; ++it) + data.set(it->first, trim(fromqstr(it->second))); +} + +} // namespace anon typedef QController > base_class; QExternal::QExternal(Dialog & parent) : base_class(parent, _("LyX: External Material")) -{ -} +{} void QExternal::build_dialog() @@ -51,48 +285,88 @@ void QExternal::build_dialog() bcview().setOK(dialog_->okPB); bcview().setApply(dialog_->applyPB); bcview().setCancel(dialog_->closePB); - bcview().addReadOnly(dialog_->externalCO); + bcview().addReadOnly(dialog_->fileED); bcview().addReadOnly(dialog_->browsePB); + bcview().addReadOnly(dialog_->editPB); + bcview().addReadOnly(dialog_->externalCO); + bcview().addReadOnly(dialog_->displayscaleED); + bcview().addReadOnly(dialog_->showCO); + bcview().addReadOnly(dialog_->displayCB); + bcview().addReadOnly(dialog_->angleED); + bcview().addReadOnly(dialog_->originCO); + bcview().addReadOnly(dialog_->heightUnitCO); + bcview().addReadOnly(dialog_->heightED); + bcview().addReadOnly(dialog_->aspectratioCB); + bcview().addReadOnly(dialog_->widthUnitCO); + bcview().addReadOnly(dialog_->widthED); + bcview().addReadOnly(dialog_->clipCB); + bcview().addReadOnly(dialog_->getbbPB); + bcview().addReadOnly(dialog_->ytED); + bcview().addReadOnly(dialog_->xlED); + bcview().addReadOnly(dialog_->xrED); + bcview().addReadOnly(dialog_->ybED); + bcview().addReadOnly(dialog_->extraFormatCO); bcview().addReadOnly(dialog_->extraED); + addCheckedLineEdit(bcview(), dialog_->angleED, dialog_->angleLA); + addCheckedLineEdit(bcview(), dialog_->displayscaleED, dialog_->scaleLA); + addCheckedLineEdit(bcview(), dialog_->heightED, dialog_->heightLA); + addCheckedLineEdit(bcview(), dialog_->widthED, dialog_->widthLA); + addCheckedLineEdit(bcview(), dialog_->xlED, dialog_->lbLA); + addCheckedLineEdit(bcview(), dialog_->ybED, dialog_->lbLA); + addCheckedLineEdit(bcview(), dialog_->xrED, dialog_->rtLA); + addCheckedLineEdit(bcview(), dialog_->ytED, dialog_->rtLA); + std::vector templates(controller().getTemplates()); for (std::vector::const_iterator cit = templates.begin(); cit != templates.end(); ++cit) { dialog_->externalCO->insertItem(toqstr(*cit), -1); } + + // Fill the origins combo + typedef vector Origins; + Origins const & all_origins = external::all_origins(); + for (Origins::size_type i = 0; i != all_origins.size(); ++i) + dialog_->originCO->insertItem(toqstr(external::origin_gui_str(i))); + + // Fill the width combo + dialog_->widthUnitCO->insertItem(qt_("Scale%")); + for (int i = 0; i < num_units; i++) + dialog_->widthUnitCO->insertItem(unit_name_gui[i], -1); } void QExternal::update_contents() { + dialog_->tab->setCurrentPage(0); InsetExternalParams const & params = controller().params(); string const name = params.filename.outputFilename(kernel().bufferFilepath()); dialog_->fileED->setText(toqstr(name)); - dialog_->externalCO->setCurrentItem(controller() - .getTemplateNumber(params.templatename())); + dialog_->externalCO->setCurrentItem( + controller().getTemplateNumber(params.templatename())); updateTemplate(); - int item = 0; - switch (params.display) { - case lyx::external::DefaultDisplay: item = 0; break; - case lyx::external::MonochromeDisplay: item = 1; break; - case lyx::external::GrayscaleDisplay: item = 2; break; - case lyx::external::ColorDisplay: item = 3; break; - case lyx::external::PreviewDisplay: item = 4; break; - case lyx::external::NoDisplay: item = 0; break; - } - dialog_->showCB->setCurrentItem(item); - dialog_->showCB->setEnabled(params.display != lyx::external::NoDisplay && - !readOnly()); - dialog_->displayCB->setChecked(params.display != lyx::external::NoDisplay); - dialog_->displayscale->setEnabled(params.display != lyx::external::NoDisplay && - !readOnly()); - dialog_->displayscale->setText(toqstr(tostr(params.lyxscale))); + setDisplay(*dialog_->displayCB, *dialog_->showCO, + *dialog_->displayscaleED, + params.display, params.lyxscale, readOnly()); + + setRotation(*dialog_->angleED, *dialog_->originCO, params.rotationdata); + + setSize(*dialog_->widthED, *dialog_->widthUnitCO, + *dialog_->heightED, *dialog_->heightUnitCO, + *dialog_->aspectratioCB, + params.resizedata); + + setCrop(*dialog_->clipCB, + *dialog_->xlED, *dialog_->ybED, + *dialog_->xrED, *dialog_->ytED, + params.clipdata); + controller().bbChanged(!params.clipdata.bbox.empty()); isValid(); } @@ -100,21 +374,40 @@ void QExternal::update_contents() void QExternal::updateTemplate() { - namespace external = lyx::external; + external::Template templ = + controller().getTemplate(dialog_->externalCO->currentItem()); + dialog_->externalTV->setText(toqstr(templ.helpText)); - dialog_->externalTV->setText(toqstr(helpText())); + // Ascertain which (if any) transformations the template supports + // and disable tabs hosting unsupported transforms. + typedef vector TransformIDs; + TransformIDs const transformIds = templ.transformIds; + TransformIDs::const_iterator tr_begin = transformIds.begin(); + TransformIDs::const_iterator const tr_end = transformIds.end(); + + bool found = find(tr_begin, tr_end, external::Rotate) != tr_end; + dialog_->tab->setTabEnabled(dialog_->rotatetab, found); + + found = find(tr_begin, tr_end, external::Resize) != tr_end; + dialog_->tab->setTabEnabled(dialog_->scaletab, found); + + found = find(tr_begin, tr_end, external::Clip) != tr_end; + dialog_->tab->setTabEnabled(dialog_->croptab, found); + + found = find(tr_begin, tr_end, external::Extra) != tr_end; + dialog_->tab->setTabEnabled(dialog_->optionstab, found); + if (!found) + return; // Ascertain whether the template has any formats supporting // the 'Extra' option - QLineEdit * const input = dialog_->extraED; - QComboBox * const combo = dialog_->extraFormatCB; + QLineEdit * const extraED = dialog_->extraED; + QComboBox * const extraCB = dialog_->extraFormatCO; extra_.clear(); - input->clear(); - combo->clear(); + extraED->clear(); + extraCB->clear(); - external::Template templ = - controller().getTemplate(dialog_->externalCO->currentItem()); external::Template::Formats::const_iterator it = templ.formats.begin(); external::Template::Formats::const_iterator end = templ.formats.end(); for (; it != end; ++it) { @@ -123,30 +416,23 @@ void QExternal::updateTemplate() continue; string const format = it->first; string const opt = controller().params().extradata.get(format); - combo->insertItem(toqstr(format)); + extraCB->insertItem(toqstr(format)); extra_[format] = toqstr(opt); } - bool const enabled = combo->count() > 0; + bool const enabled = extraCB->count() > 0; - input->setEnabled(enabled && !kernel().isBufferReadonly()); - combo->setEnabled(enabled); + dialog_->tab->setTabEnabled(dialog_->optionstab, enabled); + extraED->setEnabled(enabled && !kernel().isBufferReadonly()); + extraCB->setEnabled(enabled); if (enabled) { - combo->setCurrentItem(0); - input->setText(extra_[fromqstr(combo->currentText())]); + extraCB->setCurrentItem(0); + extraED->setText(extra_[fromqstr(extraCB->currentText())]); } } -string const QExternal::helpText() const -{ - lyx::external::Template templ = - controller().getTemplate(dialog_->externalCO->currentItem()); - return templ.helpText; -} - - void QExternal::apply() { InsetExternalParams params = controller().params(); @@ -154,27 +440,56 @@ void QExternal::apply() params.filename.set(fromqstr(dialog_->fileED->text()), kernel().bufferFilepath()); - params.settemplate( - controller().getTemplate(dialog_->externalCO->currentItem()).lyxName); + params.settemplate(controller().getTemplate( + dialog_->externalCO->currentItem()).lyxName); - switch (dialog_->showCB->currentItem()) { - case 0: params.display = lyx::external::DefaultDisplay; break; - case 1: params.display = lyx::external::MonochromeDisplay; break; - case 2: params.display = lyx::external::GrayscaleDisplay; break; - case 3: params.display = lyx::external::ColorDisplay; break; - case 4: params.display = lyx::external::PreviewDisplay; break; - default:; - } + getDisplay(params.display, params.lyxscale, + *dialog_->displayCB, *dialog_->showCO, + *dialog_->displayscaleED); - if (!dialog_->displayCB->isChecked()) - params.display = lyx::external::NoDisplay; + if (dialog_->tab->isTabEnabled(dialog_->rotatetab)) + getRotation(params.rotationdata, + *dialog_->angleED, *dialog_->originCO); - params.lyxscale = strToInt(fromqstr(dialog_->displayscale->text())); + if (dialog_->tab->isTabEnabled(dialog_->scaletab)) + getSize(params.resizedata, + *dialog_->widthED, *dialog_->widthUnitCO, + *dialog_->heightED, *dialog_->heightUnitCO, + *dialog_->aspectratioCB); - std::map::const_iterator it = extra_.begin(); - std::map::const_iterator end = extra_.end(); - for (; it != end; ++it) - params.extradata.set(it->first, trim(fromqstr(it->second))); + if (dialog_->tab->isTabEnabled(dialog_->croptab)) + getCrop(params.clipdata, + *dialog_->clipCB, + *dialog_->xlED, *dialog_->ybED, + *dialog_->xrED, *dialog_->ytED, + controller().bbChanged()); + + if (dialog_->tab->isTabEnabled(dialog_->optionstab)) + getExtra(params.extradata, extra_); controller().setParams(params); } + + +void QExternal::getBB() +{ + dialog_->xlED->setText("0"); + dialog_->ybED->setText("0"); + dialog_->xrED->setText("0"); + dialog_->ytED->setText("0"); + + string const filename = fromqstr(dialog_->fileED->text()); + if (filename.empty()) + return; + + string const bb = controller().readBB(filename); + if (bb.empty()) + return; + + dialog_->xlED->setText(toqstr(token(bb, ' ', 0))); + dialog_->ybED->setText(toqstr(token(bb, ' ', 1))); + dialog_->xrED->setText(toqstr(token(bb, ' ', 2))); + dialog_->ytED->setText(toqstr(token(bb, ' ', 3))); + + controller().bbChanged(false); +} diff --git a/src/frontends/qt2/QExternal.h b/src/frontends/qt2/QExternal.h index 74c5f689f8..fc52d621cd 100644 --- a/src/frontends/qt2/QExternal.h +++ b/src/frontends/qt2/QExternal.h @@ -29,6 +29,8 @@ public: QExternal(Dialog &); + typedef std::map MapType; + private: /// Apply changes virtual void apply(); @@ -37,13 +39,12 @@ private: /// build the dialog virtual void build_dialog(); - /// get the right helptext - std::string const helpText() const; - /// Helper function called when the template is changed. void updateTemplate(); + /// get bounding box from file + void getBB(); - std::map extra_; + MapType extra_; }; #endif // QEXTERNAL_H diff --git a/src/frontends/qt2/QExternalDialog.C b/src/frontends/qt2/QExternalDialog.C index 423899fd9e..e8286ed306 100644 --- a/src/frontends/qt2/QExternalDialog.C +++ b/src/frontends/qt2/QExternalDialog.C @@ -4,15 +4,27 @@ * Licence details can be found in the file COPYING. * * \author John Levon + * \author Angus Leeming * * Full author contact details are available in file CREDITS. */ #include -#include "qt_helpers.h" -#include "ControlExternal.h" +#include "controllers/ButtonController.h" +#include "controllers/ControlExternal.h" +#include "support/lstrings.h" +#include "support/lyxlib.h" + +#include "QExternalDialog.h" + +#include "lengthcombo.h" +#include "lengthvalidator.h" +#include "qt_helpers.h" +#include "QExternal.h" + +#include #include #include #include @@ -20,13 +32,27 @@ #include #include -#include "QExternalDialog.h" -#include "QExternal.h" +using lyx::support::float_equal; +using lyx::support::isStrDbl; +using lyx::support::strToDbl; +using std::string; + + +namespace { + +LengthValidator * unsignedLengthValidator(QLineEdit * ed) +{ + LengthValidator * v = new LengthValidator(ed); + v->setBottom(LyXLength()); + return v; +} + +} // namespace anon QExternalDialog::QExternalDialog(QExternal * form) : QExternalDialogBase(0, 0, false, 0), - form_(form) + form_(form) { connect(okPB, SIGNAL(clicked()), form, SLOT(slotOK())); @@ -35,9 +61,21 @@ QExternalDialog::QExternalDialog(QExternal * form) connect(closePB, SIGNAL(clicked()), form, SLOT(slotClose())); - QIntValidator * validator = new QIntValidator(displayscale); + QIntValidator * validator = new QIntValidator(displayscaleED); validator->setBottom(1); - displayscale->setValidator(validator); + displayscaleED->setValidator(validator); + + angleED->setValidator(new QDoubleValidator(-360, 360, 2, angleED)); + + xlED->setValidator(new QIntValidator(xlED)); + ybED->setValidator(new QIntValidator(ybED)); + xrED->setValidator(new QIntValidator(xrED)); + ytED->setValidator(new QIntValidator(ytED)); + + // The width is initially set to 'scale' and so should accept + // a pure number only. + widthED->setValidator(new QDoubleValidator(0, 1000, 2, widthED)); + heightED->setValidator(unsignedLengthValidator(heightED)); } @@ -48,6 +86,51 @@ void QExternalDialog::show() } + +bool QExternalDialog::activateAspectratio() const +{ + if (widthUnitCO->currentItem() == 0) + return false; + + string const wstr = fromqstr(widthED->text()); + if (wstr.empty()) + return false; + bool const wIsDbl = isStrDbl(wstr); + if (wIsDbl && float_equal(strToDbl(wstr), 0.0, 0.05)) + return false; + LyXLength l; + if (!wIsDbl && (!isValidLength(wstr, &l) || l.zero())) + return false; + + string const hstr = fromqstr(heightED->text()); + if (hstr.empty()) + return false; + bool const hIsDbl = isStrDbl(hstr); + if (hIsDbl && float_equal(strToDbl(hstr), 0.0, 0.05)) + return false; + if (!hIsDbl && (!isValidLength(hstr, &l) || l.zero())) + return false; + + return true; +} + + +void QExternalDialog::bbChanged() +{ + form_->controller().bbChanged(true); + form_->changed(); +} + + +void QExternalDialog::browseClicked() +{ + string const str = + form_->controller().Browse(fromqstr(fileED->text())); + fileED->setText(toqstr(str)); + form_->changed(); +} + + void QExternalDialog::change_adaptor() { form_->changed(); @@ -67,23 +150,11 @@ void QExternalDialog::editClicked() } -void QExternalDialog::browseClicked() -{ - QString file = - QFileDialog::getOpenFileName(QString::null, - qt_("External material (*)"), - this, 0, - qt_("Select external material")); - if (!file.isNull()) { - fileED->setText(file); - form_->changed(); - } -} - -void QExternalDialog::templateChanged() +void QExternalDialog::extraChanged(const QString& text) { - form_->updateTemplate(); + std::string const format = fromqstr(extraFormatCO->currentText()); + form_->extra_[format] = text; form_->changed(); } @@ -94,10 +165,36 @@ void QExternalDialog::formatChanged(const QString& format) } -void QExternalDialog::extraChanged(const QString& text) +void QExternalDialog::getbbClicked() { - std::string const format = fromqstr(extraFormatCB->currentText()); - form_->extra_[format] = text; + form_->getBB(); +} + + +void QExternalDialog::sizeChanged() +{ + aspectratioCB->setEnabled(activateAspectratio()); form_->changed(); } + +void QExternalDialog::templateChanged() +{ + form_->updateTemplate(); + form_->changed(); +} + + +void QExternalDialog::widthUnitChanged() +{ + bool useHeight = (widthUnitCO->currentItem() > 0); + + if (useHeight) + widthED->setValidator(unsignedLengthValidator(widthED)); + else + widthED->setValidator(new QDoubleValidator(0, 1000, 2, widthED)); + + heightED->setEnabled(useHeight); + heightUnitCO->setEnabled(useHeight); + form_->changed(); +} diff --git a/src/frontends/qt2/QExternalDialog.h b/src/frontends/qt2/QExternalDialog.h index c1c988b732..1ac74c111c 100644 --- a/src/frontends/qt2/QExternalDialog.h +++ b/src/frontends/qt2/QExternalDialog.h @@ -24,15 +24,21 @@ public: virtual void show(); protected slots: + virtual void bbChanged(); + virtual void browseClicked(); virtual void change_adaptor(); virtual void editClicked(); - virtual void browseClicked(); - virtual void templateChanged(); - virtual void formatChanged(const QString&); virtual void extraChanged(const QString&); + virtual void formatChanged(const QString&); + virtual void getbbClicked(); + virtual void sizeChanged(); + virtual void templateChanged(); + virtual void widthUnitChanged(); + protected: virtual void closeEvent(QCloseEvent * e); private: + bool activateAspectratio() const; QExternal * form_; }; diff --git a/src/frontends/qt2/checkedwidgets.C b/src/frontends/qt2/checkedwidgets.C new file mode 100644 index 0000000000..e01c54a2a8 --- /dev/null +++ b/src/frontends/qt2/checkedwidgets.C @@ -0,0 +1,69 @@ +/** + * \file qt2/checkedwidgets.C + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Angus Leeming + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "checkedwidgets.h" + +#include +#include +#include + + +void addCheckedLineEdit(BCView & bcview, + QLineEdit * input, QLabel * label) +{ + bcview.addCheckedWidget(new CheckedLineEdit(input, label)); +} + + +namespace { + +void setWidget(bool valid, QLineEdit * input, QLabel * label) +{ + QColor const red(255, 0, 0); + + if (valid) + input->unsetPalette(); + else + input->setPaletteForegroundColor(red); + + if (!label) + return; + + if (valid) + label->unsetPalette(); + else + label->setPaletteForegroundColor(red); +} + +} // namespace anon + + +CheckedLineEdit::CheckedLineEdit(QLineEdit * input, QLabel * label) + : input_(input), label_(label) +{} + + +bool CheckedLineEdit::check() const +{ + QValidator const * validator = input_->validator(); + if (!validator) + return true; + + QString t = input_->text(); + int p = 0; + bool const valid = validator->validate(t, p) == QValidator::Acceptable; + + // Visual feedback. + setWidget(valid, input_, label_); + + return valid; +} diff --git a/src/frontends/qt2/checkedwidgets.h b/src/frontends/qt2/checkedwidgets.h new file mode 100644 index 0000000000..fde0e6301b --- /dev/null +++ b/src/frontends/qt2/checkedwidgets.h @@ -0,0 +1,38 @@ +// -*- C++ -*- +/** + * \file qt2/checkedwidgets.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Angus Leeming + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef CHECKEDWIDGETS_H +#define CHECKEDWIDGETS_H + + +#include "BCView.h" + +class QLabel; +class QLineEdit; + + +void addCheckedLineEdit(BCView & bcview, + QLineEdit * input, QLabel * label = 0); + +class CheckedLineEdit : public CheckedWidget { +public: + CheckedLineEdit(QLineEdit * input, QLabel * label = 0); + +private: + /// + virtual bool check() const; + + /// + QLineEdit * input_; + QLabel * label_; +}; + +#endif // CHECKEDWIDGETS_H diff --git a/src/frontends/qt2/lengthvalidator.C b/src/frontends/qt2/lengthvalidator.C new file mode 100644 index 0000000000..be37b824d1 --- /dev/null +++ b/src/frontends/qt2/lengthvalidator.C @@ -0,0 +1,54 @@ +/** + * \file lengthvalidator.C + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Angus Leeming + * + * Full author contact details are available in file CREDITS. + */ + + +#include + +#include "lengthvalidator.h" + +#include "support/lstrings.h" + +#include "qt_helpers.h" + + +using lyx::support::isStrDbl; +using std::string; + + +LengthValidator::LengthValidator(QObject * parent, const char * name) + : QValidator(parent, name), + no_bottom_(true) +{} + + +QValidator::State LengthValidator::validate(QString & qtext, int &) const +{ + string const text = fromqstr(qtext); + if (text.empty() || isStrDbl(text)) + return QValidator::Acceptable; + + LyXLength l; + bool const valid_length = isValidLength(text, &l); + if (!valid_length) + return QValidator::Intermediate; + + if (no_bottom_) + return QValidator::Acceptable; + + return b_.inPixels(100) <= l.inPixels(100) ? + QValidator::Acceptable : QValidator::Intermediate; +} + + +void LengthValidator::setBottom(LyXLength b) +{ + b_ = b; + no_bottom_ = false; +} diff --git a/src/frontends/qt2/lengthvalidator.h b/src/frontends/qt2/lengthvalidator.h new file mode 100644 index 0000000000..1ef4e22c42 --- /dev/null +++ b/src/frontends/qt2/lengthvalidator.h @@ -0,0 +1,40 @@ +// -*- C++ -*- +/** + * \file lengthvalidator.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Angus Leeming + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef LENGTHVALIDATOR_H +#define LENGTHVALIDATOR_H + +#include "lyxlength.h" +#include + + +class Q_EXPORT LengthValidator : public QValidator +{ + Q_OBJECT +public: + LengthValidator(QObject * parent, const char *name = 0); + + QValidator::State validate(QString &, int &) const; + + void setBottom(LyXLength); + LyXLength bottom() const { return b_; } + +private: +#if defined(Q_DISABLE_COPY) + LengthValidator( const LengthValidator & ); + LengthValidator& operator=( const LengthValidator & ); +#endif + + LyXLength b_; + bool no_bottom_; +}; + +# endif // NOT LENGTHVALIDATOR_H diff --git a/src/frontends/qt2/ui/QExternalDialogBase.ui b/src/frontends/qt2/ui/QExternalDialogBase.ui index 39e29b0d33..8abeb57116 100644 --- a/src/frontends/qt2/ui/QExternalDialogBase.ui +++ b/src/frontends/qt2/ui/QExternalDialogBase.ui @@ -13,8 +13,8 @@ 0 0 - 279 - 580 + 394 + 418 @@ -25,50 +25,144 @@ sizeGripEnabled true - + + QLayoutWidget - margin - 11 + name + Layout2 - spacing - 6 + geometry + + 11 + 369 + 372 + 38 + - - QPushButton + + + margin + 0 + + + spacing + 6 + + + + name + Spacer3 + + + orientation + Horizontal + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + QPushButton + + name + okPB + + + text + &OK + + + default + true + + + + QPushButton + + name + applyPB + + + text + &Apply + + + default + false + + + + QPushButton + + name + closePB + + + text + &Close + + + autoDefault + false + + + default + false + + + + + + QTabWidget + + name + tab + + + geometry + + 11 + 11 + 387 + 325 + + + + layoutSpacing + + + QWidget name - editPB + filetab - - text - &Edit file... - - - toolTip - Edit the file externally - - - - QLayoutWidget - - name - Layout11 - - + + title + File + + margin - 0 + 11 spacing 6 - + QLayoutWidget name - Layout8 + Layout11_2 @@ -79,130 +173,11 @@ spacing 6 - - QLabel - - name - fileLA - - - text - &File: - - - buddy - fileED - - - toolTip - Filename - - - - QLineEdit - - name - fileED - - - toolTip - Filename - - - - - - QPushButton - - name - browsePB - - - text - &Browse... - - - - - - - name - Spacer8 - - - orientation - Horizontal - - - sizeType - Expanding - - - sizeHint - - 20 - 20 - - - - - QGroupBox - - name - GroupBox4 - - - title - LyX Display - - - - margin - 11 - - - spacing - 6 - - - QLayoutWidget - - name - Layout11 - - - - margin - 0 - - - spacing - 6 - - - QLabel - - name - scaleLA - - - text - Sca&le: - - - buddy - displayscale - - - toolTip - Percentage to scale by in LyX - - QLayoutWidget name - Layout10 + Layout8 @@ -213,235 +188,130 @@ spacing 6 - - QLineEdit - - name - displayscale - - - enabled - true - - - sizePolicy - - 5 - 0 - - - - toolTip - Percentage to scale by in LyX - - QLabel name - displayscaleL - - - enabled - true - - - focusPolicy - NoFocus + fileLA text - % + &File: + + + buddy + fileED + + + toolTip + Filename + + + + QLineEdit + + name + fileED + + + toolTip + Filename - + + QPushButton + + name + browsePB + + + text + &Browse... + + + toolTip + Get bounding box from the (EPS) file + + + - - QLayoutWidget + + QGroupBox name - Layout9 + GroupBox3 - + + title + Template + + margin - 0 + 11 spacing 6 - - QLabel - - name - TextLabel1 - - - text - &Display: - - - buddy - showCB - - - toolTip - Screen display - - - + QComboBox - - - text - Default - - - - - text - Monochrome - - - - - text - Grayscale - - - - - text - Color - - - - - text - Preview - - name - showCB + externalCO + + + sizePolicy + + 3 + 0 + toolTip - Screen display + Available templates - + + QTextView + + name + externalTV + + + toolTip + + + + + + name + Spacer3_3 + + + orientation + Horizontal + + + sizeType + Preferred + + + sizeHint + + 20 + 20 + + + + - - QCheckBox - - name - displayCB - - - text - &Show in LyX - - - toolTip - Display image in LyX - - - - - - QGroupBox - - name - GroupBox3 - - - title - Template - - - - margin - 11 - - - spacing - 6 - - - QComboBox - - name - externalCO - - - sizePolicy - - 3 - 0 - - - - toolTip - Available templates - - - - QTextView - - name - externalTV - - - toolTip - LaTeX error messages - - - + name - Spacer3_2 - - - orientation - Horizontal - - - sizeType - Preferred - - - sizeHint - - 20 - 20 - - - - - - - QLayoutWidget - - name - Layout2 - - - - margin - 0 - - - spacing - 6 - - - - name - Spacer3 + Spacer8 orientation @@ -459,67 +329,33 @@ - + QPushButton name - okPB + editPB text - &OK + &Edit File... - - default - true + + toolTip + Edit the file externally - - QPushButton - - name - applyPB - - - text - &Apply - - - default - false - - - - QPushButton - - name - closePB - - - text - &Close - - - autoDefault - false - - - default - false - - - + - - QGroupBox + + QWidget name - GroupBox5 + lyxviewtab - + title - Output Options - + LyX View + margin @@ -530,92 +366,961 @@ 6 - QLayoutWidget + QGroupBox name - Layout13 + lyxviewBG - + + title + + + margin - 0 + 11 spacing 6 - - QLabel + + QLayoutWidget name - formatLA + Layout11 + + + + margin + 0 + + + spacing + 6 + + + QLabel + + name + scaleLA + + + text + Sca&le: + + + buddy + displayscaleED + + + toolTip + Percentage to scale by in LyX + + + + QLayoutWidget + + name + Layout10 + + + + margin + 0 + + + spacing + 6 + + + QLineEdit + + name + displayscaleED + + + enabled + true + + + sizePolicy + + 5 + 0 + + + + toolTip + Percentage to scale by in LyX + + + + QLabel + + name + displayscaleLA + + + enabled + true + + + focusPolicy + NoFocus + + + text + % + + + + + + + + QLayoutWidget + + name + Layout9 + + + + margin + 0 + + + spacing + 6 + + + QLabel + + name + showLA + + + text + &Display: + + + buddy + showCO + + + toolTip + Screen display + + + + QComboBox + + + text + Default + + + + + text + Monochrome + + + + + text + Grayscale + + + + + text + Color + + + + + text + Preview + + + + name + showCO + + + toolTip + Screen display + + + + + + QCheckBox + + name + displayCB text - Forma&t: - - - textFormat - AutoText + &Show in LyX - buddy - extraFormatCB + toolTip + Display image in LyX - - QComboBox - - name - extraFormatCB - - - - - - QLayoutWidget - - name - Layout14 - - - - margin - 0 - - - spacing - 6 - - - QLabel - - name - optionLA - - - text - O&ption: - - - buddy - extraED - - - - QLineEdit - - name - extraED - - - + - + + QWidget + + name + rotatetab + + + title + Rotate + + + + margin + 11 + + + spacing + 6 + + + QGroupBox + + name + rotateBG + + + title + + + + QLayoutWidget + + name + Layout49 + + + geometry + + 11 + 11 + 322 + 36 + + + + + margin + 0 + + + spacing + 6 + + + QLabel + + name + originLA + + + text + &Origin: + + + buddy + originCO + + + toolTip + The origin of the rotation + + + + QLineEdit + + name + angleED + + + sizePolicy + + 3 + 0 + + + + text + + + + toolTip + Angle to rotate image by + + + + QLabel + + name + angleLA + + + text + A&ngle: + + + buddy + angleED + + + toolTip + Angle to rotate image by + + + + QComboBox + + name + originCO + + + toolTip + The origin of the rotation + + + + + + + + + QWidget + + name + scaletab + + + title + Scale + + + + margin + 11 + + + spacing + 6 + + + QGroupBox + + name + scaleBG + + + title + + + + QComboBox + + name + widthUnitCO + + + geometry + + 232 + 11 + 95 + 34 + + + + + LengthCombo + + name + heightUnitCO + + + geometry + + 236 + 56 + 91 + 31 + + + + + QLineEdit + + name + heightED + + + enabled + true + + + geometry + + 61 + 53 + 165 + 30 + + + + toolTip + Height of image in output + + + + QCheckBox + + name + aspectratioCB + + + enabled + true + + + geometry + + 61 + 91 + 165 + 26 + + + + text + &Maintain aspect ratio + + + toolTip + Maintain aspect ratio with largest dimension + + + + QLineEdit + + name + widthED + + + enabled + true + + + geometry + + 61 + 13 + 165 + 30 + + + + toolTip + Width of image in output + + + + QLabel + + name + widthLA + + + enabled + true + + + geometry + + 11 + 11 + 44 + 34 + + + + text + &Width: + + + buddy + widthED + + + + QLabel + + name + heightLA + + + enabled + true + + + geometry + + 11 + 51 + 44 + 34 + + + + text + &Height: + + + buddy + heightED + + + + + + + QWidget + + name + croptab + + + title + Crop + + + + margin + 11 + + + spacing + 6 + + + QGroupBox + + name + cropBG + + + title + + + + QCheckBox + + name + clipCB + + + geometry + + 11 + 16 + 150 + 26 + + + + text + Clip to &bounding box + + + toolTip + Clip to bounding box values + + + + QLabel + + name + rtLA + + + geometry + + 11 + 81 + 73 + 30 + + + + text + Right &top: + + + buddy + xrED + + + + QLabel + + name + yLA + + + geometry + + 223 + 53 + 127 + 22 + + + + text + y + + + + QLineEdit + + name + xlED + + + geometry + + 90 + 117 + 127 + 30 + + + + toolTip + + + + + QLabel + + name + lbLA + + + geometry + + 11 + 117 + 73 + 30 + + + + text + &Left bottom: + + + buddy + xlED + + + + QLineEdit + + name + ytED + + + geometry + + 223 + 81 + 127 + 30 + + + + + QLineEdit + + name + ybED + + + geometry + + 223 + 117 + 127 + 30 + + + + + QLabel + + name + xLA + + + geometry + + 90 + 53 + 71 + 22 + + + + text + x + + + + QLineEdit + + name + xrED + + + geometry + + 90 + 81 + 127 + 30 + + + + + QPushButton + + name + getbbPB + + + geometry + + 167 + 11 + 183 + 36 + + + + text + &Get from File + + + toolTip + Get bounding box from the (EPS) file + + + + + + + QWidget + + name + optionstab + + + title + Options + + + + margin + 11 + + + spacing + 6 + + + QGroupBox + + name + optionsBG + + + title + + + + + margin + 11 + + + spacing + 6 + + + QLayoutWidget + + name + Layout13_2 + + + + margin + 0 + + + spacing + 6 + + + QLabel + + name + formatLA + + + text + Forma&t: + + + textFormat + AutoText + + + buddy + extraFormatCO + + + + QComboBox + + name + extraFormatCO + + + + + + QLayoutWidget + + name + Layout14_2 + + + + margin + 0 + + + spacing + 6 + + + QLabel + + name + optionLA + + + text + O&ption: + + + buddy + extraED + + + + QLineEdit + + name + extraED + + + + + + + + + + + + LengthCombo +
lengthcombo.h
+ + -1 + -1 + + 0 + + 5 + 5 + + image0 + selectionChanged(LyXLength::UNIT) +
+
+ + + image0 + 789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758 + + + + displayCB + toggled(bool) + showCO + setEnabled(bool) + + + displayCB + toggled(bool) + displayscaleED + setEnabled(bool) + + + showCO + activated(const QString&) + QExternalDialogBase + change_adaptor() + + + originCO + activated(int) + QExternalDialogBase + change_adaptor() + + + aspectratioCB + stateChanged(int) + QExternalDialogBase + change_adaptor() + + + browsePB + clicked() + QExternalDialogBase + browseClicked() + editPB clicked() @@ -629,28 +1334,28 @@ templateChanged() - fileED + extraED textChanged(const QString&) QExternalDialogBase - change_adaptor() + extraChanged(const QString&) - browsePB - clicked() + extraFormatCO + activated(const QString&) QExternalDialogBase - browseClicked() + formatChanged(const QString&) - displayCB - toggled(bool) - showCB - setEnabled(bool) + widthUnitCO + activated(int) + QExternalDialogBase + widthUnitChanged() - displayCB - toggled(bool) - displayscale - setEnabled(bool) + heightUnitCO + selectionChanged(LyXLength::UNIT) + QExternalDialogBase + change_adaptor() displayCB @@ -659,47 +1364,83 @@ change_adaptor() - showCB - activated(const QString&) - QExternalDialogBase - change_adaptor() - - - extraFormatCB - activated(const QString&) - QExternalDialogBase - formatChanged(const QString&) - - - displayscale + displayscaleED textChanged(const QString&) QExternalDialogBase change_adaptor() - extraED + angleED textChanged(const QString&) QExternalDialogBase - extraChanged(const QString&) + change_adaptor() + + + widthED + textChanged(const QString&) + QExternalDialogBase + sizeChanged() + + + heightED + textChanged(const QString&) + QExternalDialogBase + sizeChanged() + + + fileED + textChanged(const QString&) + QExternalDialogBase + change_adaptor() + + + clipCB + stateChanged(int) + QExternalDialogBase + change_adaptor() + + + getbbPB + clicked() + QExternalDialogBase + getbbClicked() + + + xrED + textChanged(const QString&) + QExternalDialogBase + bbChanged() + + + ytED + textChanged(const QString&) + QExternalDialogBase + bbChanged() + + + xlED + textChanged(const QString&) + QExternalDialogBase + bbChanged() + + + ybED + textChanged(const QString&) + QExternalDialogBase + bbChanged() browseClicked() change_adaptor() editClicked() - formatChanged(const QString&) extraChanged(const QString&) + formatChanged(const QString&) + getbbClicked() + bbChanged() + sizeChanged() templateChanged() - updateClicked() - viewClicked() + widthUnitChanged() - externalCO - externalTV - fileED - browsePB - editPB - displayCB - showCB - displayscale okPB applyPB closePB