]> git.lyx.org Git - features.git/blob - src/frontends/qt/ButtonController.cpp
#10571 improved handling of WM's signal when switching from or to full-screen window
[features.git] / src / frontends / qt / ButtonController.cpp
1 /**
2  * \file ButtonController.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Allan Rae
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "ButtonController.h"
14
15 #include "qt_helpers.h"
16
17 #include "support/debug.h"
18
19 #include <QCheckBox>
20 #include <QPushButton>
21 #include <QLineEdit>
22 #include <QLabel>
23 #include <QList>
24 #include <QValidator>
25
26
27 namespace lyx {
28 namespace frontend {
29
30 /////////////////////////////////////////////////////////////////////////
31 //
32 // CheckedLineEdit
33 //
34 /////////////////////////////////////////////////////////////////////////
35
36 class CheckedLineEdit
37 {
38 public:
39         CheckedLineEdit(QLineEdit * input, QWidget * label = nullptr);
40         bool check() const;
41
42 private:
43         // non-owned
44         QLineEdit * input_;
45         QWidget * label_;
46 };
47
48
49 CheckedLineEdit::CheckedLineEdit(QLineEdit * input, QWidget * label)
50         : input_(input), label_(label)
51 {}
52
53
54 bool CheckedLineEdit::check() const
55 {
56         QValidator const * validator = input_->validator();
57         if (!validator)
58                 return true;
59
60         QString t = input_->text();
61         int p = 0;
62         bool const valid = validator->validate(t, p) == QValidator::Acceptable;
63
64         // Visual feedback.
65         setValid(input_, valid);
66         if (label_)
67                 setValid(label_, valid);
68
69         return valid;
70 }
71
72
73 /////////////////////////////////////////////////////////////////////////
74 //
75 // ButtonController::Private
76 //
77 /////////////////////////////////////////////////////////////////////////
78
79 class ButtonController::Private
80 {
81 public:
82         typedef QList<CheckedLineEdit> CheckedWidgetList;
83
84         Private()
85                 : okay_(nullptr), apply_(nullptr), cancel_(nullptr),
86                         restore_(nullptr), auto_apply_(nullptr), default_(nullptr),
87                         policy_(ButtonPolicy::IgnorantPolicy)
88         {}
89
90         /// \return true if all CheckedWidgets are in a valid state.
91         bool checkWidgets() const
92         {
93                 bool valid = true;
94                 for (const CheckedLineEdit & w : checked_widgets_)
95                         valid &= w.check();
96                 return valid;
97         }
98
99 public:
100         CheckedWidgetList checked_widgets_;
101
102         QPushButton * okay_;
103         QPushButton * apply_;
104         QPushButton * cancel_;
105         QPushButton * restore_;
106         QCheckBox * auto_apply_;
107         QPushButton * default_;
108
109         typedef QList<QWidget *> Widgets;
110         Widgets read_only_;
111
112         ButtonPolicy policy_;
113 };
114
115
116 /////////////////////////////////////////////////////////////////////////
117 //
118 // ButtonController
119 //
120 /////////////////////////////////////////////////////////////////////////
121
122 ButtonController::ButtonController()
123         : d(new Private)
124 {}
125
126
127 ButtonController::~ButtonController()
128 {
129         delete d;
130 }
131
132
133 void ButtonController::setPolicy(ButtonPolicy::Policy policy)
134 {
135         d->policy_.setPolicy(policy);
136 }
137
138
139 void ButtonController::ok()
140 {
141         input(ButtonPolicy::SMI_OKAY);
142 }
143
144
145 void ButtonController::input(ButtonPolicy::SMInput in)
146 {
147         if (ButtonPolicy::SMI_NOOP == in)
148                 return;
149         d->policy_.input(in);
150         refresh();
151 }
152
153
154 void ButtonController::apply()
155 {
156         input(ButtonPolicy::SMI_APPLY);
157 }
158
159
160 void ButtonController::autoApply()
161 {
162         input(ButtonPolicy::SMI_AUTOAPPLY);
163 }
164
165
166 void ButtonController::cancel()
167 {
168         input(ButtonPolicy::SMI_CANCEL);
169 }
170
171
172 void ButtonController::restore()
173 {
174         input(ButtonPolicy::SMI_RESTORE);
175 }
176
177
178 void ButtonController::hide()
179 {
180         input(ButtonPolicy::SMI_HIDE);
181 }
182
183
184 void ButtonController::setValid(bool v)
185 {
186         input(v ? ButtonPolicy::SMI_VALID : ButtonPolicy::SMI_INVALID);
187 }
188
189
190 bool ButtonController::setReadOnly(bool ro)
191 {
192         LYXERR(Debug::GUI, "Setting controller ro: " << ro);
193
194         d->policy_.input(ro ?
195                 ButtonPolicy::SMI_READ_ONLY : ButtonPolicy::SMI_READ_WRITE);
196
197         refresh();
198         return ro;
199 }
200
201
202 void ButtonController::refresh() const
203 {
204         LYXERR(Debug::GUI, "Calling BC refresh()");
205
206         bool const all_valid = d->checkWidgets();
207
208         if (d->okay_) {
209                 bool const enabled =
210                         all_valid && policy().buttonStatus(ButtonPolicy::OKAY);
211                 d->okay_->setEnabled(enabled);
212         }
213         if (d->apply_) {
214                 bool const enabled =
215                         all_valid && policy().buttonStatus(ButtonPolicy::APPLY);
216                 d->apply_->setEnabled(enabled);
217         }
218         if (d->restore_) {
219                 bool const enabled =
220                         all_valid && policy().buttonStatus(ButtonPolicy::RESTORE);
221                 d->restore_->setEnabled(enabled);
222         }
223         if (d->cancel_) {
224                 bool const enabled = policy().buttonStatus(ButtonPolicy::CANCEL);
225                 if (enabled)
226                         d->cancel_->setText(qt_("Cancel"));
227                 else
228                         d->cancel_->setText(qt_("Close"));
229         }
230         if (d->auto_apply_) {
231                 bool const enabled = policy().buttonStatus(ButtonPolicy::AUTOAPPLY);
232                 d->auto_apply_->setEnabled(enabled);
233         }
234         if (d->default_)
235                 // Somewhere in the chain this can lose default status (#11417)
236                 d->default_->setDefault(true);
237 }
238
239
240 void ButtonController::addCheckedLineEdit(QLineEdit * input, QWidget * label)
241 {
242         d->checked_widgets_.append(CheckedLineEdit(input, label));
243 }
244
245
246 void ButtonController::setOK(QPushButton * obj, bool const default_button)
247 {
248         d->okay_ = obj;
249         if (default_button)
250                 d->default_ = obj;
251 }
252
253
254 void ButtonController::setApply(QPushButton * obj, bool const default_button)
255 {
256         d->apply_ = obj;
257         if (default_button)
258                 d->default_ = obj;
259 }
260
261
262 void ButtonController::setAutoApply(QCheckBox * obj)
263 {
264         d->auto_apply_ = obj;
265 }
266
267
268 void ButtonController::setCancel(QPushButton * obj, bool const default_button)
269 {
270         d->cancel_ = obj;
271         if (default_button)
272                 d->default_ = obj;
273 }
274
275
276 void ButtonController::setRestore(QPushButton * obj, bool const default_button)
277 {
278         d->restore_ = obj;
279         if (default_button)
280                 d->default_ = obj;
281 }
282
283
284 void ButtonController::addReadOnly(QWidget * obj)
285 {
286         d->read_only_.push_back(obj);
287 }
288
289 ButtonPolicy const & ButtonController::policy() const
290 {
291         return d->policy_;
292 }
293
294
295 ButtonPolicy & ButtonController::policy()
296 {
297         return d->policy_;
298 }
299
300 } // namespace frontend
301 } // namespace lyx