From 780742b73af854c9e934e3687443568591f82985 Mon Sep 17 00:00:00 2001 From: Vincent van Ravesteijn Date: Sun, 18 Jan 2009 14:33:51 +0000 Subject: [PATCH] New ButtonPolicy for dialogs with an auto-apply option. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@28237 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/frontends/qt4/ButtonController.cpp | 21 ++++- src/frontends/qt4/ButtonController.h | 3 + src/frontends/qt4/ButtonPolicy.cpp | 123 ++++++++++++++++++++++++- src/frontends/qt4/ButtonPolicy.h | 37 ++++++-- src/frontends/qt4/GuiDialog.cpp | 7 ++ src/frontends/qt4/GuiDialog.h | 2 + 6 files changed, 180 insertions(+), 13 deletions(-) diff --git a/src/frontends/qt4/ButtonController.cpp b/src/frontends/qt4/ButtonController.cpp index d2897eb5e0..bccae6a706 100644 --- a/src/frontends/qt4/ButtonController.cpp +++ b/src/frontends/qt4/ButtonController.cpp @@ -17,6 +17,7 @@ #include "support/debug.h" #include "support/foreach.h" +#include #include #include #include @@ -93,7 +94,7 @@ public: typedef QList CheckedWidgetList; Private() - : okay_(0), apply_(0), cancel_(0), restore_(0), + : okay_(0), apply_(0), cancel_(0), restore_(0), auto_apply_(0), policy_(ButtonPolicy::IgnorantPolicy) {} @@ -113,6 +114,7 @@ public: QPushButton * apply_; QPushButton * cancel_; QPushButton * restore_; + QCheckBox * auto_apply_; typedef QList Widgets; Widgets read_only_; @@ -165,6 +167,12 @@ void ButtonController::apply() } +void ButtonController::autoApply() +{ + input(ButtonPolicy::SMI_AUTOAPPLY); +} + + void ButtonController::cancel() { input(ButtonPolicy::SMI_CANCEL); @@ -232,6 +240,11 @@ void ButtonController::refresh() const else d->cancel_->setText(qt_("Close")); } + if (d->auto_apply_) { + bool const enabled = policy().buttonStatus(ButtonPolicy::AUTOAPPLY); + d->auto_apply_->setEnabled(enabled); + } + } @@ -265,6 +278,12 @@ void ButtonController::setApply(QPushButton * obj) } +void ButtonController::setAutoApply(QCheckBox * obj) +{ + d->auto_apply_ = obj; +} + + void ButtonController::setCancel(QPushButton * obj) { d->cancel_ = obj; diff --git a/src/frontends/qt4/ButtonController.h b/src/frontends/qt4/ButtonController.h index 06420a4d7b..cec52bf566 100644 --- a/src/frontends/qt4/ButtonController.h +++ b/src/frontends/qt4/ButtonController.h @@ -17,6 +17,7 @@ class QWidget; class QPushButton; class QLineEdit; +class QCheckBox; namespace lyx { namespace frontend { @@ -61,6 +62,7 @@ public: void apply(); void cancel(); void restore(); + void autoApply(); //@} /// Tell the BC that the dialog is being hidden @@ -97,6 +99,7 @@ public: void setApply(QPushButton * obj); void setCancel(QPushButton * obj); void setRestore(QPushButton * obj); + void setAutoApply(QCheckBox * obj); //@} /** Add a pointer to the list of widgets whose activation diff --git a/src/frontends/qt4/ButtonPolicy.cpp b/src/frontends/qt4/ButtonPolicy.cpp index e24338a0b0..2e6b1bfce4 100644 --- a/src/frontends/qt4/ButtonPolicy.cpp +++ b/src/frontends/qt4/ButtonPolicy.cpp @@ -33,6 +33,10 @@ static char const * printState(ButtonPolicy::State const & state) return "INVALID"; case ButtonPolicy::APPLIED: return "APPLIED"; + case ButtonPolicy::AUTOAPPLY_INITIAL: + return "AUTOAPPLY_INITIAL"; + case ButtonPolicy::AUTOAPPLY_CHANGED: + return "AUTOAPPLY_CHANGED"; case ButtonPolicy::RO_INITIAL: return "RO_INITIAL"; case ButtonPolicy::RO_VALID: @@ -41,6 +45,8 @@ static char const * printState(ButtonPolicy::State const & state) return "RO_INVALID"; case ButtonPolicy::RO_APPLIED: return "RO_APPLIED"; + case ButtonPolicy::RO_AUTOAPPLY: + return "RO_AUTOAPPLY"; case ButtonPolicy::BOGUS: return "BOGUS"; default: @@ -64,6 +70,8 @@ static char const * printInput(ButtonPolicy::SMInput const & input) return "SMI_CANCEL"; case ButtonPolicy::SMI_RESTORE: return "SMI_RESTORE"; + case ButtonPolicy::SMI_AUTOAPPLY: + return "SMI_AUTOAPPLY"; case ButtonPolicy::SMI_HIDE: return "SMI_HIDE"; case ButtonPolicy::SMI_READ_ONLY: @@ -93,6 +101,8 @@ char const * functionName(ButtonPolicy::Policy policy) return "OkApplyCancelPolicy"; case ButtonPolicy::OkApplyCancelReadOnlyPolicy: return "OkApplyCancelReadOnlyPolicy"; + case ButtonPolicy::OkApplyCancelAutoReadOnlyPolicy: + return "OkApplyCancelAutoReadOnlyPolicy"; case ButtonPolicy::NoRepeatedApplyPolicy: return "NoRepeatedApplyPolicy"; case ButtonPolicy::NoRepeatedApplyReadOnlyPolicy: @@ -138,6 +148,7 @@ public: void initOkCancelReadOnly(); void initNoRepeatedApplyReadOnly(); void initOkApplyCancelReadOnly(); + void initOkApplyCancelAutoReadOnly(); void initOkApplyCancel(); void initNoRepeatedApply(); void initPreferences(); @@ -180,6 +191,9 @@ ButtonPolicy::Private::Private(Policy policy) case OkApplyCancelReadOnlyPolicy: initOkApplyCancelReadOnly(); break; + case OkApplyCancelAutoReadOnlyPolicy: + initOkApplyCancelAutoReadOnly(); + break; case NoRepeatedApplyPolicy: initNoRepeatedApply(); break; @@ -538,6 +552,105 @@ void ButtonPolicy::Private::initOkApplyCancel() } +void ButtonPolicy::Private::initOkApplyCancelAutoReadOnly() +{ + outputs_ = StateOutputs(RO_AUTOAPPLY + 1, ButtonPolicy::ALL_BUTTONS); + state_machine_ = StateMachine(RO_AUTOAPPLY + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)); + + // Build the state output map + outputs_[INITIAL] = CLOSE | AUTOAPPLY; + outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL | AUTOAPPLY; + outputs_[INVALID] = RESTORE | CANCEL | AUTOAPPLY; + outputs_[APPLIED] = OKAY | CLOSE | AUTOAPPLY; + outputs_[AUTOAPPLY_INITIAL] = CLOSE | AUTOAPPLY | OKAY; + outputs_[AUTOAPPLY_CHANGED] = CLOSE | RESTORE | AUTOAPPLY | OKAY; + outputs_[RO_INITIAL] = CLOSE; + outputs_[RO_VALID] = RESTORE | CANCEL; + outputs_[RO_INVALID] = RESTORE | CANCEL; + outputs_[RO_APPLIED] = CLOSE; + outputs_[RO_AUTOAPPLY] = CLOSE; + + // Build the state machine one state at a time + // NOTE: Since CANCEL and HIDE always go to INITIAL they are + // left out of the state machine and handled explicitly + // in input() + // + // State::INITIAL + state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; + state_machine_[INITIAL][SMI_VALID] = VALID; + state_machine_[INITIAL][SMI_INVALID] = INVALID; + state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL; + state_machine_[INITIAL][SMI_AUTOAPPLY] = AUTOAPPLY_INITIAL; + // State::VALID + state_machine_[VALID][SMI_VALID] = VALID; + state_machine_[VALID][SMI_READ_WRITE] = VALID; + state_machine_[VALID][SMI_INVALID] = INVALID; + state_machine_[VALID][SMI_OKAY] = INITIAL; + state_machine_[VALID][SMI_RESTORE] = INITIAL; + state_machine_[VALID][SMI_APPLY] = APPLIED; + state_machine_[VALID][SMI_READ_ONLY] = RO_VALID; + state_machine_[VALID][SMI_AUTOAPPLY] = AUTOAPPLY_INITIAL; + // State::INVALID + state_machine_[INVALID][SMI_INVALID] = INVALID; + state_machine_[INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[INVALID][SMI_VALID] = VALID; + state_machine_[INVALID][SMI_RESTORE] = INITIAL; + state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID; + state_machine_[INVALID][SMI_AUTOAPPLY] = AUTOAPPLY_CHANGED; + // State::APPLIED + state_machine_[APPLIED][SMI_APPLY] = APPLIED; + state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED; + state_machine_[APPLIED][SMI_VALID] = VALID; + state_machine_[APPLIED][SMI_INVALID] = INVALID; + state_machine_[APPLIED][SMI_OKAY] = INITIAL; + state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED; + state_machine_[APPLIED][SMI_AUTOAPPLY] = AUTOAPPLY_INITIAL; + // State::AUTOAPPLY_INITIAL + state_machine_[AUTOAPPLY_INITIAL][SMI_AUTOAPPLY] = APPLIED; + state_machine_[AUTOAPPLY_INITIAL][SMI_READ_ONLY] = RO_AUTOAPPLY; + state_machine_[AUTOAPPLY_INITIAL][SMI_VALID] = AUTOAPPLY_CHANGED; + state_machine_[AUTOAPPLY_INITIAL][SMI_INVALID] = AUTOAPPLY_CHANGED; + state_machine_[AUTOAPPLY_INITIAL][SMI_READ_WRITE] = AUTOAPPLY_INITIAL; + // State::AUTOAPPLY_CHANGED + state_machine_[AUTOAPPLY_CHANGED][SMI_AUTOAPPLY] = APPLIED; + state_machine_[AUTOAPPLY_CHANGED][SMI_READ_ONLY] = RO_AUTOAPPLY; + state_machine_[AUTOAPPLY_CHANGED][SMI_RESTORE] = AUTOAPPLY_INITIAL; + state_machine_[AUTOAPPLY_CHANGED][SMI_VALID] = AUTOAPPLY_CHANGED; + state_machine_[AUTOAPPLY_CHANGED][SMI_INVALID] = AUTOAPPLY_CHANGED; + state_machine_[AUTOAPPLY_CHANGED][SMI_READ_WRITE] = AUTOAPPLY_CHANGED; + state_machine_[AUTOAPPLY_CHANGED][SMI_APPLY] = AUTOAPPLY_INITIAL; + // State::RO_INITIAL + state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL; + state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID; + state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID; + state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL; + state_machine_[RO_INITIAL][SMI_AUTOAPPLY] = RO_AUTOAPPLY; + // State::RO_VALID + state_machine_[RO_VALID][SMI_VALID] = RO_VALID; + state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID; + state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID; + state_machine_[RO_VALID][SMI_READ_WRITE] = VALID; + state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL; + state_machine_[RO_VALID][SMI_AUTOAPPLY] = RO_AUTOAPPLY; + // State::RO_INVALID + state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID; + state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID; + state_machine_[RO_INVALID][SMI_VALID] = RO_VALID; + state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL; + state_machine_[RO_INVALID][SMI_AUTOAPPLY] = RO_AUTOAPPLY; + // State::RO_APPLIED + state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED; + state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID; + state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID; + state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED; + state_machine_[RO_APPLIED][SMI_AUTOAPPLY] = RO_AUTOAPPLY; + // State::RO_AUTOAPPLY + state_machine_[RO_AUTOAPPLY][SMI_READ_WRITE] = AUTOAPPLY_INITIAL; +} + + void ButtonPolicy::Private::initNoRepeatedApply() { outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS); @@ -616,9 +729,13 @@ void ButtonPolicy::input(SMInput input) break; default: // CANCEL and HIDE always take us to INITIAL for all cases - if (SMI_CANCEL == input || SMI_HIDE == input) - d->state_ = INITIAL; - else + if (SMI_CANCEL == input || SMI_HIDE == input) { + if (d->state_ == AUTOAPPLY_INITIAL + || d->state_ == AUTOAPPLY_CHANGED) + d->state_ = AUTOAPPLY_INITIAL; + else + d->state_ = INITIAL; + } else d->nextState(input); break; } diff --git a/src/frontends/qt4/ButtonPolicy.h b/src/frontends/qt4/ButtonPolicy.h index 93f03ed0aa..28f711e9eb 100644 --- a/src/frontends/qt4/ButtonPolicy.h +++ b/src/frontends/qt4/ButtonPolicy.h @@ -23,7 +23,7 @@ namespace frontend { dialogs. Only the policy is implemented here. Separate ButtonController classes are needed for each GUI implementation. - Policy | ReadOnly | Apply Button | Repeated Apply + Policy | ReadOnly | Apply Button | Repeated Apply ======================================================================== OkCancel | N | N | - OkCancelReadOnly | Y | N | - @@ -31,6 +31,7 @@ namespace frontend { OkApplyCancelReadOnly | Y | Y | Y NoRepeatedApply | N | Y | N NoRepeatedApplyReadOnly | Y | Y | N + OkApplyCancelAutoReadOnly | Y | Y | Y Preferences | N | Y | No (Ok-Close) Ignorant | N/A | N/A | N/A ======================================================================== @@ -72,7 +73,7 @@ public: This is based on the value of the bool state of the Button::CANCEL. true == Cancel, false == Close */ - OkCancelPolicy, + OkCancelPolicy, /** Ok and Cancel buttons for dialogs where read-only operation is blocked. @@ -121,7 +122,7 @@ public: OkApplyCancelReadOnlyPolicy, /** Ok, Apply and Cancel buttons for dialogs where repeated - * Apply is allowed. + Apply is allowed. Note: This scheme supports the relabelling of Cancel to Close and vice versa. This is based on the value of the bool state of the Button::CANCEL. @@ -137,6 +138,14 @@ public: */ NoRepeatedApplyPolicy, + /** Ok, Apply and Cancel buttons and an AutoApply checkbox. + Note: This scheme supports the relabelling of Cancel to Close + and vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ + OkApplyCancelAutoReadOnlyPolicy, + /** Defines the policy used by the Preferences dialog. Four buttons: Ok (Save), Apply, Cancel/Close, Restore. Note: This scheme supports the relabelling of Cancel to Close @@ -176,6 +185,10 @@ public: /// APPLIED, /// + AUTOAPPLY_INITIAL, + /// + AUTOAPPLY_CHANGED, + /// RO_INITIAL, /// RO_VALID, @@ -184,25 +197,29 @@ public: /// RO_APPLIED, /// + RO_AUTOAPPLY, + /// BOGUS = 55 }; /// The various button types. enum Button { /// - CLOSE = 0, // Not a real button, but effectively !CANCEL + CLOSE = 0, // Not a real button, but effectively !CANCEL + /// + OKAY = 1, /// - OKAY = 1, + APPLY = 2, /// - APPLY = 2, + CANCEL = 4, /// - CANCEL = 4, + RESTORE = 8, /// - RESTORE = 8 + AUTOAPPLY = 16 // This is usually a checkbox }; /// static const Button ALL_BUTTONS = - Button(OKAY | APPLY | CANCEL | RESTORE); + Button(OKAY | APPLY | CANCEL | RESTORE | AUTOAPPLY); /** State machine inputs. All the policies so far have both CANCEL and HIDE always going to @@ -225,6 +242,8 @@ public: SMI_CANCEL, /// a restore action has happened SMI_RESTORE, + /// apply auto-apply + SMI_AUTOAPPLY, /// the dialog has been hidden SMI_HIDE, /// the dialog contents are read-only diff --git a/src/frontends/qt4/GuiDialog.cpp b/src/frontends/qt4/GuiDialog.cpp index 3e8a54faca..1c0c628fc6 100644 --- a/src/frontends/qt4/GuiDialog.cpp +++ b/src/frontends/qt4/GuiDialog.cpp @@ -50,6 +50,13 @@ void GuiDialog::slotApply() } +void GuiDialog::slotAutoApply() +{ + apply(); + bc().autoApply(); +} + + void GuiDialog::slotOK() { is_closing_ = true; diff --git a/src/frontends/qt4/GuiDialog.h b/src/frontends/qt4/GuiDialog.h index 04878e2981..2359d74012 100644 --- a/src/frontends/qt4/GuiDialog.h +++ b/src/frontends/qt4/GuiDialog.h @@ -52,6 +52,8 @@ public Q_SLOTS: void slotOK(); // Apply button clicked void slotApply(); + // AutoApply checkbox clicked + void slotAutoApply(); // Close button clicked or closed from WindowManager void slotClose(); /// -- 2.39.5