void GuiBC<Button, Widget>::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_) {
#include "debug.h"
+CheckedWidget::~CheckedWidget()
+{}
+
+
ButtonControllerBase::ButtonControllerBase(string const & cancel,
string const & close)
: cancel_label_(cancel), close_label_(close)
{
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;
+}
+
#include "ButtonPolicies.h"
#include "LString.h"
+#include <boost/shared_ptr.hpp>
+#include <list>
+
+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.
void valid(bool = true);
///
void invalid();
+ ///
+ void addCheckedWidget(CheckedWidget * ptr);
+
protected:
///
string cancel_label_;
///
string close_label_;
+ ///
+ bool checkWidgets();
+
+private:
+ ///
+ typedef boost::shared_ptr<CheckedWidget> checked_widget_ptr;
+ typedef std::list<checked_widget_ptr> checked_widget_list;
+ ///
+ checked_widget_list checked_widgets;
};
#endif // BUTTONCONTROLLERBASE_H
+2002-10-22 Angus Leeming <leeming@lyx.org>
+
+ * 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 <larsbj@birdstep.com>
* tex_helpers.C (rescanTexStyles): don't pop p
bc().readOnly(bufferIsReadonly());
view().show();
+
+ // The widgets may not be valid, so refresh the button controller
+ bc().refresh();
}
template <class Base>
bc().readOnly(bufferIsReadonly());
view().update();
+
+ // The widgets may not be valid, so refresh the button controller
+ bc().refresh();
}
template <class Base>
connectInset(inset);
show(getParams(*inset));
+
+ // The widgets may not be valid, so refresh the button controller
+ bc().refresh();
}
bc().readOnly(bufferIsReadonly());
view().update();
+
+ // The widgets may not be valid, so refresh the button controller
+ bc().refresh();
}
ControlExternal.h \
ControlFloat.C \
ControlFloat.h \
- ControlWrap.C \
- ControlWrap.h \
ControlForks.C \
ControlForks.h \
ControlGraphics.C \
ControlUrl.h \
ControlVCLog.C \
ControlVCLog.h \
+ ControlWrap.C \
+ ControlWrap.h \
GUI.h \
ViewBase.h \
helper_funcs.C \
+2002-10-22 Angus Leeming <leeming@lyx.org>
+
+ * 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 <larsbj@gullik.net>
* xfont_loader.C (doLoad): typo
forms_gettext.h \
bmtable.c \
bmtable.h \
+ checkedwidgets.C \
+ checkedwidgets.h \
combox.C \
combox.h \
input_validators.C \
FormExternal.h \
FormFloat.C \
FormFloat.h \
- FormWrap.C \
- FormWrap.h \
FormForks.C \
FormForks.h \
FormGraphics.C \
FormUrl.h \
FormVCLog.C \
FormVCLog.h \
+ FormWrap.C \
+ FormWrap.h \
LyXKeySymFactory.C \
LyXScreenFactory.C \
MathsCallbacks.h \
--- /dev/null
+/**
+ * \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 <config.h>
+
+#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;
+}
--- /dev/null
+// -*- 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
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)
{
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);