pimpl ButtonController

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@24342 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2008-04-19 09:12:34 +00:00
parent 527d3ac174
commit eee0ebdff2
2 changed files with 176 additions and 112 deletions

View File

@ -15,24 +15,132 @@
#include "qt_helpers.h" #include "qt_helpers.h"
#include "support/debug.h" #include "support/debug.h"
#include "support/foreach.h"
#include <QPushButton> #include <QPushButton>
#include <QLineEdit> #include <QLineEdit>
#include <QLabel> #include <QLabel>
#include <QList>
#include <QValidator> #include <QValidator>
namespace lyx { namespace lyx {
namespace frontend { namespace frontend {
ButtonController::ButtonController() static void setWidgetEnabled(QWidget * obj, bool enabled)
{
if (QLineEdit * le = qobject_cast<QLineEdit*>(obj))
le->setReadOnly(!enabled);
else
obj->setEnabled(enabled);
obj->setFocusPolicy(enabled ? Qt::StrongFocus : Qt::NoFocus);
}
/////////////////////////////////////////////////////////////////////////
//
// CheckedLineEdit
//
/////////////////////////////////////////////////////////////////////////
class CheckedLineEdit
{
public:
CheckedLineEdit(QLineEdit * input, QWidget * label = 0);
bool check() const;
private:
// non-owned
QLineEdit * input_;
QWidget * label_;
};
CheckedLineEdit::CheckedLineEdit(QLineEdit * input, QWidget * 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.
setValid(input_, valid);
if (label_)
setValid(label_, valid);
return valid;
}
/////////////////////////////////////////////////////////////////////////
//
// ButtonController::Private
//
/////////////////////////////////////////////////////////////////////////
class ButtonController::Private
{
public:
typedef QList<CheckedLineEdit> CheckedWidgetList;
Private()
: okay_(0), apply_(0), cancel_(0), restore_(0), : okay_(0), apply_(0), cancel_(0), restore_(0),
policy_(ButtonPolicy::IgnorantPolicy) policy_(ButtonPolicy::IgnorantPolicy)
{}
/// \return true if all CheckedWidgets are in a valid state.
bool checkWidgets() const
{
bool valid = true;
foreach (const CheckedLineEdit & w, checked_widgets_)
valid &= w.check();
return valid;
}
public:
CheckedWidgetList checked_widgets_;
QPushButton * okay_;
QPushButton * apply_;
QPushButton * cancel_;
QPushButton * restore_;
typedef QList<QWidget *> Widgets;
Widgets read_only_;
ButtonPolicy policy_;
};
/////////////////////////////////////////////////////////////////////////
//
// ButtonController
//
/////////////////////////////////////////////////////////////////////////
ButtonController::ButtonController()
: d(new Private)
{} {}
ButtonController::~ButtonController()
{
delete d;
}
void ButtonController::setPolicy(ButtonPolicy::Policy policy) void ButtonController::setPolicy(ButtonPolicy::Policy policy)
{ {
policy_.setPolicy(policy); d->policy_.setPolicy(policy);
} }
@ -46,7 +154,7 @@ void ButtonController::input(ButtonPolicy::SMInput in)
{ {
if (ButtonPolicy::SMI_NOOP == in) if (ButtonPolicy::SMI_NOOP == in)
return; return;
policy_.input(in); d->policy_.input(in);
refresh(); refresh();
} }
@ -85,7 +193,7 @@ bool ButtonController::setReadOnly(bool ro)
{ {
LYXERR(Debug::GUI, "Setting controller ro: " << ro); LYXERR(Debug::GUI, "Setting controller ro: " << ro);
policy_.input(ro ? d->policy_.input(ro ?
ButtonPolicy::SMI_READ_ONLY : ButtonPolicy::SMI_READ_WRITE); ButtonPolicy::SMI_READ_ONLY : ButtonPolicy::SMI_READ_WRITE);
// refreshReadOnly(); This will enable all widgets in dialogs, no matter if // refreshReadOnly(); This will enable all widgets in dialogs, no matter if
// they allowed to be enabled, so when you plan to // they allowed to be enabled, so when you plan to
@ -100,106 +208,89 @@ void ButtonController::refresh() const
{ {
LYXERR(Debug::GUI, "Calling BC refresh()"); LYXERR(Debug::GUI, "Calling BC refresh()");
bool const all_valid = checkWidgets(); bool const all_valid = d->checkWidgets();
if (okay_) { if (d->okay_) {
bool const enabled = bool const enabled =
all_valid && policy().buttonStatus(ButtonPolicy::OKAY); all_valid && policy().buttonStatus(ButtonPolicy::OKAY);
okay_->setEnabled(enabled); d->okay_->setEnabled(enabled);
} }
if (apply_) { if (d->apply_) {
bool const enabled = bool const enabled =
all_valid && policy().buttonStatus(ButtonPolicy::APPLY); all_valid && policy().buttonStatus(ButtonPolicy::APPLY);
apply_->setEnabled(enabled); d->apply_->setEnabled(enabled);
} }
if (restore_) { if (d->restore_) {
bool const enabled = bool const enabled =
all_valid && policy().buttonStatus(ButtonPolicy::RESTORE); all_valid && policy().buttonStatus(ButtonPolicy::RESTORE);
restore_->setEnabled(enabled); d->restore_->setEnabled(enabled);
} }
if (cancel_) { if (d->cancel_) {
bool const enabled = policy().buttonStatus(ButtonPolicy::CANCEL); bool const enabled = policy().buttonStatus(ButtonPolicy::CANCEL);
if (enabled) if (enabled)
cancel_->setText(qt_("Cancel")); d->cancel_->setText(qt_("Cancel"));
else else
cancel_->setText(qt_("Close")); d->cancel_->setText(qt_("Close"));
} }
} }
void ButtonController::refreshReadOnly() const void ButtonController::refreshReadOnly() const
{ {
if (read_only_.empty()) if (d->read_only_.empty())
return; return;
bool const enable = !policy().isReadOnly(); bool const enable = !policy().isReadOnly();
Widgets::const_iterator end = read_only_.end(); foreach (QWidget * w, d->read_only_)
Widgets::const_iterator iter = read_only_.begin(); setWidgetEnabled(w, enable);
for (; iter != end; ++iter)
setWidgetEnabled(*iter, enable);
}
void ButtonController::setWidgetEnabled(QWidget * obj, bool enabled) const
{
if (QLineEdit * le = qobject_cast<QLineEdit*>(obj))
le->setReadOnly(!enabled);
else
obj->setEnabled(enabled);
obj->setFocusPolicy(enabled ? Qt::StrongFocus : Qt::NoFocus);
} }
void ButtonController::addCheckedLineEdit(QLineEdit * input, QWidget * label) void ButtonController::addCheckedLineEdit(QLineEdit * input, QWidget * label)
{ {
checked_widgets.push_back(CheckedLineEdit(input, label)); d->checked_widgets_.append(CheckedLineEdit(input, label));
} }
bool ButtonController::checkWidgets() const void ButtonController::setOK(QPushButton * obj)
{ {
bool valid = true; d->okay_ = obj;
CheckedWidgetList::const_iterator it = checked_widgets.begin();
CheckedWidgetList::const_iterator end = checked_widgets.end();
for (; it != end; ++it)
valid &= it->check();
// return valid status after checking ALL widgets
return valid;
} }
////////////////////////////////////////////////////////////// void ButtonController::setApply(QPushButton * obj)
//
// CheckedLineEdit
//
//////////////////////////////////////////////////////////////
CheckedLineEdit::CheckedLineEdit(QLineEdit * input, QWidget * label)
: input_(input), label_(label)
{}
bool CheckedLineEdit::check() const
{ {
QValidator const * validator = input_->validator(); d->apply_ = obj;
if (!validator) }
return true;
QString t = input_->text();
int p = 0;
bool const valid = validator->validate(t, p) == QValidator::Acceptable;
// Visual feedback. void ButtonController::setCancel(QPushButton * obj)
setValid(input_, valid); {
if (label_) d->cancel_ = obj;
setValid(label_, valid); }
return valid;
void ButtonController::setRestore(QPushButton * obj)
{
d->restore_ = obj;
}
void ButtonController::addReadOnly(QWidget * obj)
{
d->read_only_.push_back(obj);
}
ButtonPolicy const & ButtonController::policy() const
{
return d->policy_;
}
ButtonPolicy & ButtonController::policy()
{
return d->policy_;
} }
} // namespace frontend } // namespace frontend

View File

@ -14,8 +14,6 @@
#include "ButtonPolicy.h" #include "ButtonPolicy.h"
#include <list>
class QWidget; class QWidget;
class QPushButton; class QPushButton;
class QLineEdit; class QLineEdit;
@ -23,18 +21,6 @@ class QLineEdit;
namespace lyx { namespace lyx {
namespace frontend { namespace frontend {
class CheckedLineEdit
{
public:
CheckedLineEdit(QLineEdit * input, QWidget * label = 0);
bool check() const;
private:
// non-owned
QLineEdit * input_;
QWidget * label_;
};
/** General purpose button controller for up to four buttons. /** General purpose button controller for up to four buttons.
Controls the activation of the OK, Apply and Cancel buttons. Controls the activation of the OK, Apply and Cancel buttons.
Actually supports 4 buttons in all and it's up to the user to decide on Actually supports 4 buttons in all and it's up to the user to decide on
@ -55,14 +41,15 @@ class ButtonController
{ {
public: public:
ButtonController(); ButtonController();
~ButtonController();
//@{ //@{
/** Methods to set and get the ButtonPolicy. /** Methods to set and get the ButtonPolicy.
* \param ptr is owned by the ButtonController. * \param ptr is owned by the ButtonController.
*/ */
void setPolicy(ButtonPolicy::Policy policy); void setPolicy(ButtonPolicy::Policy policy);
ButtonPolicy const & policy() const { return policy_; } ButtonPolicy const & policy() const;
ButtonPolicy & policy() { return policy_; } ButtonPolicy & policy();
//@} //@}
/// ///
@ -92,12 +79,12 @@ public:
/** Passthrough function -- returns its input value /** Passthrough function -- returns its input value
* Tell the BC about the read-only status of the underlying buffer. * Tell the BC about the read-only status of the underlying buffer.
*/ */
bool setReadOnly(bool = true); bool setReadOnly(bool);
/** \param validity Tell the BC that the data is, or is not, valid. /** \param validity Tell the BC that the data is, or is not, valid.
* Sets the activation state of the buttons immediately. * Sets the activation state of the buttons immediately.
*/ */
void setValid(bool = true); void setValid(bool);
// //
// View // View
@ -106,45 +93,31 @@ public:
//@{ //@{
/** Store pointers to these widgets. /** Store pointers to these widgets.
*/ */
void setOK(QPushButton * obj) { okay_ = obj; } void setOK(QPushButton * obj);
void setApply(QPushButton * obj) { apply_ = obj; } void setApply(QPushButton * obj);
void setCancel(QPushButton * obj) { cancel_ = obj; } void setCancel(QPushButton * obj);
void setRestore(QPushButton * obj) { restore_ = obj; } void setRestore(QPushButton * obj);
//@} //@}
/** Add a pointer to the list of widgets whose activation /** Add a pointer to the list of widgets whose activation
* state is dependent upon the read-only status of the * state is dependent upon the read-only status of the
* underlying buffer. * underlying buffer.
*/ */
void addReadOnly(QWidget * obj) { read_only_.push_back(obj); } void addReadOnly(QWidget * obj);
/** Add a widget to the list of all widgets whose validity should /** Add a widget to the list of all widgets whose validity should
* be checked explicitly when the buttons are refreshed. * be checked explicitly when the buttons are refreshed.
*/ */
void addCheckedLineEdit(QLineEdit * input, QWidget * label = 0); void addCheckedLineEdit(QLineEdit * input, QWidget * label = 0);
protected:
/// \return true if all CheckedWidgets are in a valid state.
bool checkWidgets() const;
private: private:
typedef std::list<CheckedLineEdit> CheckedWidgetList; /// noncopyable
CheckedWidgetList checked_widgets; ButtonController(ButtonController const &);
void operator=(ButtonController const &);
private: /// pimpl
/// Updates the widget sensitivity (enabled/disabled) class Private;
void setWidgetEnabled(QWidget *, bool enabled) const; Private * d;
QPushButton * okay_;
QPushButton * apply_;
QPushButton * cancel_;
QPushButton * restore_;
typedef std::list<QWidget *> Widgets;
Widgets read_only_;
private:
ButtonPolicy policy_;
}; };
} // namespace frontend } // namespace frontend