From: Angus Leeming Date: Tue, 22 Oct 2002 12:39:05 +0000 (+0000) Subject: Rob's patch, part 1: the checked widget stuff. X-Git-Tag: 1.6.10~18126 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=649e3fee9ace4d74a96912b1907c29d885902e75;p=features.git Rob's patch, part 1: the checked widget stuff. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@5467 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/frontends/controllers/ButtonController.tmpl b/src/frontends/controllers/ButtonController.tmpl index 72b8854444..024c4d2d43 100644 --- a/src/frontends/controllers/ButtonController.tmpl +++ b/src/frontends/controllers/ButtonController.tmpl @@ -29,17 +29,22 @@ template void GuiBC::refresh() { lyxerr[Debug::GUI] << "Calling BC refresh()" << std::endl; - + + bool const all_valid = checkWidgets(); + if (okay_) { - bool const enabled = bp().buttonStatus(ButtonPolicy::OKAY); + bool const enabled = + all_valid && bp().buttonStatus(ButtonPolicy::OKAY); setButtonEnabled(okay_, enabled); } if (apply_) { - bool const enabled = bp().buttonStatus(ButtonPolicy::APPLY); + bool const enabled = + all_valid && bp().buttonStatus(ButtonPolicy::APPLY); setButtonEnabled(apply_, enabled); } if (restore_) { - bool const enabled = bp().buttonStatus(ButtonPolicy::RESTORE); + bool const enabled = + all_valid && bp().buttonStatus(ButtonPolicy::RESTORE); setButtonEnabled(restore_, enabled); } if (cancel_) { diff --git a/src/frontends/controllers/ButtonControllerBase.C b/src/frontends/controllers/ButtonControllerBase.C index 729c0a0852..16226f73f9 100644 --- a/src/frontends/controllers/ButtonControllerBase.C +++ b/src/frontends/controllers/ButtonControllerBase.C @@ -18,6 +18,10 @@ #include "debug.h" +CheckedWidget::~CheckedWidget() +{} + + ButtonControllerBase::ButtonControllerBase(string const & cancel, string const & close) : cancel_label_(cancel), close_label_(close) @@ -98,3 +102,27 @@ void ButtonControllerBase::readWrite() { readOnly(false); } + + +void ButtonControllerBase::addCheckedWidget(CheckedWidget * ptr) +{ + if (ptr) + checked_widgets.push_back(checked_widget_ptr(ptr)); +} + + +bool ButtonControllerBase::checkWidgets() +{ + bool valid = true; + + checked_widget_list::const_iterator it = checked_widgets.begin(); + checked_widget_list::const_iterator end = checked_widgets.end(); + + for (; it != end; ++it) { + valid &= (*it)->check(); + } + + // return valid status after checking ALL widgets + return valid; +} + diff --git a/src/frontends/controllers/ButtonControllerBase.h b/src/frontends/controllers/ButtonControllerBase.h index 46dd059c07..32afe73135 100644 --- a/src/frontends/controllers/ButtonControllerBase.h +++ b/src/frontends/controllers/ButtonControllerBase.h @@ -19,6 +19,21 @@ #include "ButtonPolicies.h" #include "LString.h" +#include +#include + +struct CheckedWidget { + /// + virtual ~CheckedWidget(); + + /** Returns true if the widget is in a valid state. + * Might also change the visual appearance of the widget, + * to reflect this state. + */ + virtual bool check() const = 0; +}; + + /** Abstract base class for a ButtonController * Controls the activation of the OK, Apply and Cancel buttons. @@ -69,11 +84,23 @@ public: void valid(bool = true); /// void invalid(); + /// + void addCheckedWidget(CheckedWidget * ptr); + protected: /// string cancel_label_; /// string close_label_; + /// + bool checkWidgets(); + +private: + /// + typedef boost::shared_ptr checked_widget_ptr; + typedef std::list checked_widget_list; + /// + checked_widget_list checked_widgets; }; #endif // BUTTONCONTROLLERBASE_H diff --git a/src/frontends/controllers/ChangeLog b/src/frontends/controllers/ChangeLog index a0c8c490f2..0c75999144 100644 --- a/src/frontends/controllers/ChangeLog +++ b/src/frontends/controllers/ChangeLog @@ -1,3 +1,21 @@ +2002-10-22 Angus Leeming + + * Makefile.am (libcontrollers_la_SOURCES): arrange list into + alphabetical order once again. + + * ButtonControllerBase.[Ch]: define an abstract base class CheckedWidget + Add a list of CheckedWidget ptrs to ButtonControllerBase + together with methods addCheckedWidget and checkWidgets to use it. + + * ButtonController.tmpl (refresh): use the return value of + checkWidgets to control the activation state of the Ok, Apply, Restore + buttons. + + * ControlDialog.tmpl (show, update): + * ControlInset.tmpl (showInset, update): + invoke ButtonController::refresh to ensure that the activation state of + the Ok, Apply buttons reflects the valid-state of the widgets. + 2002-10-21 Lars Gullik Bjønnes * tex_helpers.C (rescanTexStyles): don't pop p diff --git a/src/frontends/controllers/ControlDialog.tmpl b/src/frontends/controllers/ControlDialog.tmpl index 525338e8da..0ba97195d3 100644 --- a/src/frontends/controllers/ControlDialog.tmpl +++ b/src/frontends/controllers/ControlDialog.tmpl @@ -45,6 +45,9 @@ void ControlDialog::show() bc().readOnly(bufferIsReadonly()); view().show(); + + // The widgets may not be valid, so refresh the button controller + bc().refresh(); } template @@ -61,6 +64,9 @@ void ControlDialog::update() bc().readOnly(bufferIsReadonly()); view().update(); + + // The widgets may not be valid, so refresh the button controller + bc().refresh(); } template diff --git a/src/frontends/controllers/ControlInset.tmpl b/src/frontends/controllers/ControlInset.tmpl index a4d80caf10..19189579b1 100644 --- a/src/frontends/controllers/ControlInset.tmpl +++ b/src/frontends/controllers/ControlInset.tmpl @@ -34,6 +34,9 @@ void ControlInset::showInset(Inset * inset) connectInset(inset); show(getParams(*inset)); + + // The widgets may not be valid, so refresh the button controller + bc().refresh(); } @@ -91,6 +94,9 @@ void ControlInset::update() bc().readOnly(bufferIsReadonly()); view().update(); + + // The widgets may not be valid, so refresh the button controller + bc().refresh(); } diff --git a/src/frontends/controllers/Makefile.am b/src/frontends/controllers/Makefile.am index 656c5c6bbb..5e0108cf87 100644 --- a/src/frontends/controllers/Makefile.am +++ b/src/frontends/controllers/Makefile.am @@ -52,8 +52,6 @@ libcontrollers_la_SOURCES= \ ControlExternal.h \ ControlFloat.C \ ControlFloat.h \ - ControlWrap.C \ - ControlWrap.h \ ControlForks.C \ ControlForks.h \ ControlGraphics.C \ @@ -97,6 +95,8 @@ libcontrollers_la_SOURCES= \ ControlUrl.h \ ControlVCLog.C \ ControlVCLog.h \ + ControlWrap.C \ + ControlWrap.h \ GUI.h \ ViewBase.h \ helper_funcs.C \ diff --git a/src/frontends/xforms/ChangeLog b/src/frontends/xforms/ChangeLog index 0d036259be..dce9503c49 100644 --- a/src/frontends/xforms/ChangeLog +++ b/src/frontends/xforms/ChangeLog @@ -1,3 +1,14 @@ +2002-10-22 Angus Leeming + + * Makefile.am (libxforms_la_SOURCES): arrange list into alphabetical + order once again. + Add checkedwidgets.[Ch]. + + * checkedwidgets.[Ch]: new files, defining CheckedLyXLength and + CheckedGlueLength. + + * xforms_helpers.[Ch] (isActive): new helper function. + 2002-10-21 Lars Gullik Bjønnes * xfont_loader.C (doLoad): typo diff --git a/src/frontends/xforms/Makefile.am b/src/frontends/xforms/Makefile.am index e183d88d6d..64713b513d 100644 --- a/src/frontends/xforms/Makefile.am +++ b/src/frontends/xforms/Makefile.am @@ -23,6 +23,8 @@ libxforms_la_SOURCES = \ forms_gettext.h \ bmtable.c \ bmtable.h \ + checkedwidgets.C \ + checkedwidgets.h \ combox.C \ combox.h \ input_validators.C \ @@ -85,8 +87,6 @@ libxforms_la_SOURCES = \ FormExternal.h \ FormFloat.C \ FormFloat.h \ - FormWrap.C \ - FormWrap.h \ FormForks.C \ FormForks.h \ FormGraphics.C \ @@ -147,6 +147,8 @@ libxforms_la_SOURCES = \ FormUrl.h \ FormVCLog.C \ FormVCLog.h \ + FormWrap.C \ + FormWrap.h \ LyXKeySymFactory.C \ LyXScreenFactory.C \ MathsCallbacks.h \ diff --git a/src/frontends/xforms/checkedwidgets.C b/src/frontends/xforms/checkedwidgets.C new file mode 100644 index 0000000000..6de28cdc4b --- /dev/null +++ b/src/frontends/xforms/checkedwidgets.C @@ -0,0 +1,105 @@ +/** + * \file 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 + +#ifdef __GNUG__ +#pragma implementation +#endif + +#include "checkedwidgets.h" +#include "xforms_helpers.h" +#include "lyxlength.h" +#include "lyxgluelength.h" +#include "support/LAssert.h" +#include "support/lstrings.h" +#include "LString.h" + +#include FORMS_H_LOCATION + + +void addCheckedLyXLength(ButtonControllerBase & bc, + FL_OBJECT * input, FL_OBJECT * label) +{ + bc.addCheckedWidget(new CheckedLyXLength(input, label)); +} + + +void addCheckedGlueLength(ButtonControllerBase & bc, + FL_OBJECT * input, FL_OBJECT * label) +{ + bc.addCheckedWidget(new CheckedGlueLength(input, label)); +} + + +namespace { + +void setWidget(bool valid, FL_OBJECT * input, FL_OBJECT * label) +{ + // define color to mark invalid input + FL_COLOR const alert_col = FL_RED; + + FL_COLOR const lcol = valid ? FL_LCOL : alert_col; + if (label->lcol != lcol && isActive(label)) { + fl_set_object_lcol(label, lcol); + } + if (input->lcol != lcol && isActive(input)) { + fl_set_object_lcol(input, lcol); + } + + // set background color of input widget + FL_COLOR const icol1 = valid ? FL_INPUT_COL1 : alert_col; + FL_COLOR const icol2 = valid ? FL_INPUT_COL2 : alert_col; + if (input->col1 != icol1 || input->col2 != icol2) { + fl_set_object_color(input, icol1, icol2); + } +} + +} // namespace anon + + +CheckedLyXLength::CheckedLyXLength(FL_OBJECT * input, FL_OBJECT * label) + : input_(input), label_(label ? label : input) +{ + lyx::Assert(input && input->objclass == FL_INPUT); +} + + +bool CheckedLyXLength::check() const +{ + string const str = getString(input_); + bool const valid = !isActive(input_) || str.empty() + || isStrDbl(str) || isValidLength(str); + + // set the color of label and input widget + setWidget(valid, input_, label_); + + return valid; +} + + +CheckedGlueLength::CheckedGlueLength(FL_OBJECT * input, FL_OBJECT * label) + : input_(input), label_(label ? label : input) +{ + lyx::Assert(input && input->objclass == FL_INPUT); +} + + +bool CheckedGlueLength::check() const +{ + string const str = getString(input_); + bool const valid = !isActive(input_) || str.empty() + || isStrDbl(str) || isValidGlueLength(str); + + // set the color of label and input widget + setWidget(valid, input_, label_); + + return valid; +} diff --git a/src/frontends/xforms/checkedwidgets.h b/src/frontends/xforms/checkedwidgets.h new file mode 100644 index 0000000000..ee75881250 --- /dev/null +++ b/src/frontends/xforms/checkedwidgets.h @@ -0,0 +1,63 @@ +// -*- C++ -*- +/** + * \file 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 + +#ifdef __GNUG__ +#pragma interface +#endif + +#include "ButtonControllerBase.h" +#include "forms_fwd.h" + +void addCheckedLyXLength(ButtonControllerBase & bc, + FL_OBJECT * input, FL_OBJECT * label = 0); + +void addCheckedGlueLength(ButtonControllerBase & bc, + FL_OBJECT * input, FL_OBJECT * label = 0); + +class CheckedLyXLength : public CheckedWidget { +public: + /** The label widget's label will be turned red if input + * does not make a valid LyXLength. + * If label == 0, then the label of input will be used. + */ + CheckedLyXLength(FL_OBJECT * input, FL_OBJECT * label = 0); + +private: + /// + virtual bool check() const; + + /// + FL_OBJECT * input_; + FL_OBJECT * label_; +}; + + +class CheckedGlueLength : public CheckedWidget { +public: + /** The label widget's label will be turned red if input + * does not make a valid LyXGlueLength. + * If label == 0, then the label of input will be used. + */ + CheckedGlueLength(FL_OBJECT * input, FL_OBJECT * label = 0); + +private: + /// + virtual bool check() const; + + /// + FL_OBJECT * input_; + FL_OBJECT * label_; +}; + +#endif // CHECKEDWIDGETS_H diff --git a/src/frontends/xforms/xforms_helpers.C b/src/frontends/xforms/xforms_helpers.C index b6409a6aaa..bf9ce98074 100644 --- a/src/frontends/xforms/xforms_helpers.C +++ b/src/frontends/xforms/xforms_helpers.C @@ -35,6 +35,12 @@ using std::ofstream; using std::pair; using std::vector; +bool isActive(FL_OBJECT * ob) +{ + return ob && ob->active > 0; +} + + // Set an FL_OBJECT to activated or deactivated void setEnabled(FL_OBJECT * ob, bool enable) { diff --git a/src/frontends/xforms/xforms_helpers.h b/src/frontends/xforms/xforms_helpers.h index d2b227bcf9..c413697f9e 100644 --- a/src/frontends/xforms/xforms_helpers.h +++ b/src/frontends/xforms/xforms_helpers.h @@ -32,6 +32,9 @@ string const choice_Length_All = string const choice_Length_WithUnit = "cm|mm|in|ex|em|pt|sp|bp|dd|pc|cc|mu"; // all with a Unit +/// return the (in)active state of the object +bool isActive(FL_OBJECT * ob); + /// Set an FL_OBJECT to activated or deactivated void setEnabled(FL_OBJECT *, bool enable);