]> git.lyx.org Git - features.git/blob - src/frontends/qt/ButtonController.cpp
Regenerate previews after zoom (#11919)
[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
86         /// \return true if all CheckedWidgets are in a valid state.
87         bool checkWidgets() const
88         {
89                 bool valid = true;
90                 for (const CheckedLineEdit & w : checked_widgets_)
91                         valid &= w.check();
92                 return valid;
93         }
94
95 public:
96         CheckedWidgetList checked_widgets_;
97
98         QPushButton * okay_ = nullptr;
99         QPushButton * apply_ = nullptr;
100         QPushButton * cancel_ = nullptr;
101         QPushButton * restore_ = nullptr;
102         QCheckBox * auto_apply_ = nullptr;
103         QPushButton * default_ = nullptr;
104
105         typedef QList<QWidget *> Widgets;
106         Widgets read_only_;
107
108         ButtonPolicy policy_ {ButtonPolicy::IgnorantPolicy};
109 };
110
111
112 /////////////////////////////////////////////////////////////////////////
113 //
114 // ButtonController
115 //
116 /////////////////////////////////////////////////////////////////////////
117
118 ButtonController::ButtonController()
119         : d(new Private)
120 {}
121
122
123 ButtonController::~ButtonController()
124 {
125         delete d;
126 }
127
128
129 void ButtonController::setPolicy(ButtonPolicy::Policy policy)
130 {
131         d->policy_.setPolicy(policy);
132 }
133
134
135 void ButtonController::ok()
136 {
137         input(ButtonPolicy::SMI_OKAY);
138 }
139
140
141 void ButtonController::input(ButtonPolicy::SMInput in)
142 {
143         if (ButtonPolicy::SMI_NOOP == in)
144                 return;
145         d->policy_.input(in);
146         refresh();
147 }
148
149
150 void ButtonController::apply()
151 {
152         input(ButtonPolicy::SMI_APPLY);
153 }
154
155
156 void ButtonController::autoApply()
157 {
158         input(ButtonPolicy::SMI_AUTOAPPLY);
159 }
160
161
162 void ButtonController::cancel()
163 {
164         input(ButtonPolicy::SMI_CANCEL);
165 }
166
167
168 void ButtonController::restore()
169 {
170         input(ButtonPolicy::SMI_RESTORE);
171 }
172
173
174 void ButtonController::hide()
175 {
176         input(ButtonPolicy::SMI_HIDE);
177 }
178
179
180 void ButtonController::setValid(bool v)
181 {
182         input(v ? ButtonPolicy::SMI_VALID : ButtonPolicy::SMI_INVALID);
183 }
184
185
186 bool ButtonController::setReadOnly(bool ro)
187 {
188         LYXERR(Debug::GUI, "Setting controller ro: " << ro);
189
190         d->policy_.input(ro ?
191                 ButtonPolicy::SMI_READ_ONLY : ButtonPolicy::SMI_READ_WRITE);
192
193         refresh();
194         return ro;
195 }
196
197
198 void ButtonController::refresh() const
199 {
200         LYXERR(Debug::GUI, "Calling BC refresh()");
201
202         bool const all_valid = d->checkWidgets();
203
204         if (d->okay_) {
205                 bool const enabled =
206                         all_valid && policy().buttonStatus(ButtonPolicy::OKAY);
207                 d->okay_->setEnabled(enabled);
208         }
209         if (d->apply_) {
210                 bool const enabled =
211                         all_valid && policy().buttonStatus(ButtonPolicy::APPLY);
212                 d->apply_->setEnabled(enabled);
213         }
214         if (d->restore_) {
215                 bool const enabled =
216                         all_valid && policy().buttonStatus(ButtonPolicy::RESTORE);
217                 d->restore_->setEnabled(enabled);
218         }
219         if (d->cancel_) {
220                 bool const enabled = policy().buttonStatus(ButtonPolicy::CANCEL);
221                 if (enabled)
222                         d->cancel_->setText(qt_("Cancel"));
223                 else
224                         d->cancel_->setText(qt_("Close"));
225         }
226         if (d->auto_apply_) {
227                 bool const enabled = policy().buttonStatus(ButtonPolicy::AUTOAPPLY);
228                 d->auto_apply_->setEnabled(enabled);
229         }
230         if (d->default_)
231                 // Somewhere in the chain this can lose default status (#11417)
232                 d->default_->setDefault(true);
233 }
234
235
236 void ButtonController::addCheckedLineEdit(QLineEdit * input, QWidget * label)
237 {
238         d->checked_widgets_.append(CheckedLineEdit(input, label));
239 }
240
241
242 void ButtonController::setOK(QPushButton * obj, bool const default_button)
243 {
244         d->okay_ = obj;
245         if (default_button)
246                 d->default_ = obj;
247 }
248
249
250 void ButtonController::setApply(QPushButton * obj, bool const default_button)
251 {
252         d->apply_ = obj;
253         if (default_button)
254                 d->default_ = obj;
255 }
256
257
258 void ButtonController::setAutoApply(QCheckBox * obj)
259 {
260         d->auto_apply_ = obj;
261 }
262
263
264 void ButtonController::setCancel(QPushButton * obj, bool const default_button)
265 {
266         d->cancel_ = obj;
267         if (default_button)
268                 d->default_ = obj;
269 }
270
271
272 void ButtonController::setRestore(QPushButton * obj, bool const default_button)
273 {
274         d->restore_ = obj;
275         if (default_button)
276                 d->default_ = obj;
277 }
278
279
280 void ButtonController::addReadOnly(QWidget * obj)
281 {
282         d->read_only_.push_back(obj);
283 }
284
285 ButtonPolicy const & ButtonController::policy() const
286 {
287         return d->policy_;
288 }
289
290
291 ButtonPolicy & ButtonController::policy()
292 {
293         return d->policy_;
294 }
295
296 } // namespace frontend
297 } // namespace lyx