Seamly2D
Code documentation
checkablemessagebox.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** All rights reserved. This program and the accompanying materials are made
7 ** available under the terms of the GNU Lesser General Public License (LGPL)
8 ** version 2.1 which accompanies this distribution, and is available at
9 ** http://www.gnu.org/licenses/lgpl-2.1.html
10 **
11 ** This library is distributed in the hope that it will be useful, but WITHOUT
12 ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 ** for more details.
15 **
16 ****************************************************************************/
17 
18 #include "checkablemessagebox.h"
19 
20 #include <QAbstractButton>
21 #include <QApplication>
22 #include <QCheckBox>
23 #include <QHBoxLayout>
24 #include <QLabel>
25 #include <QLatin1String>
26 #include <QPushButton>
27 #include <QSettings>
28 #include <QSize>
29 #include <QSizePolicy>
30 #include <QSpacerItem>
31 #include <QVBoxLayout>
32 #include <QVariant>
33 #include <Qt>
34 
35 static const char kDoNotAskAgainKey[] = "DoNotAskAgain";
36 
37 namespace Utils
38 {
39 
40 /*!
41  \class CheckableMessageBox
42 
43  \brief The CheckableMessageBox class implements a message box suitable for
44  questions with a
45  "Do not ask me again" checkbox.
46 
47  Emulates the QMessageBox API with
48  static conveniences. The message label can open external URLs.
49 */
51 {
52 public:
53  explicit CheckableMessageBoxPrivate(QDialog *q)
54  : pixmapLabel(nullptr), messageLabel(nullptr), checkBox(nullptr), buttonBox(nullptr), clickedButton(nullptr)
55  {
56  QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
57 
58  pixmapLabel = new QLabel(q);
59  sizePolicy.setHorizontalStretch(0);
60  sizePolicy.setVerticalStretch(0);
61  sizePolicy.setHeightForWidth(pixmapLabel->sizePolicy().hasHeightForWidth());
62  pixmapLabel->setSizePolicy(sizePolicy);
63  pixmapLabel->setVisible(false);
64 
65  QSpacerItem *pixmapSpacer = new QSpacerItem(0, 5, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);
66 
67  messageLabel = new QLabel(q);
68  messageLabel->setMinimumSize(QSize(300, 0));
69  messageLabel->setWordWrap(true);
70  messageLabel->setOpenExternalLinks(true);
71  messageLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse);
72 
73  QSpacerItem *checkBoxRightSpacer = new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum);
74  QSpacerItem *buttonSpacer = new QSpacerItem(0, 1, QSizePolicy::Minimum, QSizePolicy::Minimum);
75 
76  checkBox = new QCheckBox(q);
77  checkBox->setText(CheckableMessageBox::tr("Do not ask again"));
78 
79  buttonBox = new QDialogButtonBox(q);
80  buttonBox->setOrientation(Qt::Horizontal);
81  buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
82 
83  QVBoxLayout *verticalLayout = new QVBoxLayout();
84  verticalLayout->addWidget(pixmapLabel);
85  verticalLayout->addItem(pixmapSpacer);
86 
87  QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
88  horizontalLayout_2->addLayout(verticalLayout);
89  horizontalLayout_2->addWidget(messageLabel);
90 
91  QHBoxLayout *horizontalLayout = new QHBoxLayout();
92  horizontalLayout->addWidget(checkBox);
93  horizontalLayout->addItem(checkBoxRightSpacer);
94 
95  QVBoxLayout *verticalLayout_2 = new QVBoxLayout(q);
96  verticalLayout_2->addLayout(horizontalLayout_2);
97  verticalLayout_2->addLayout(horizontalLayout);
98  verticalLayout_2->addItem(buttonSpacer);
99  verticalLayout_2->addWidget(buttonBox);
100  }
101 
102  QLabel *pixmapLabel;
103  QLabel *messageLabel;
104  QCheckBox *checkBox;
105  QDialogButtonBox *buttonBox;
106  QAbstractButton *clickedButton;
107 private:
108  Q_DISABLE_COPY(CheckableMessageBoxPrivate)
109 };
110 
112  QDialog(parent),
113  d(new CheckableMessageBoxPrivate(this))
114 {
115  setModal(true);
116  setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
117  connect(d->buttonBox, SIGNAL(accepted()), SLOT(accept()));
118  connect(d->buttonBox, SIGNAL(rejected()), SLOT(reject()));
119  connect(d->buttonBox, SIGNAL(clicked(QAbstractButton*)), SLOT(slotClicked(QAbstractButton*)));
120 }
121 
123 {
124  delete d;
125 }
126 
127 void CheckableMessageBox::slotClicked(QAbstractButton *b)
128 {
129  d->clickedButton = b;
130 }
131 
132 QAbstractButton *CheckableMessageBox::clickedButton() const
133 {
134  return d->clickedButton;
135 }
136 
137 QDialogButtonBox::StandardButton CheckableMessageBox::clickedStandardButton() const
138 {
139  if (d->clickedButton)
140  {
141  return d->buttonBox->standardButton(d->clickedButton);
142  }
143  return QDialogButtonBox::NoButton;
144 }
145 
147 {
148  return d->messageLabel->text();
149 }
150 
151 void CheckableMessageBox::setText(const QString &t)
152 {
153  d->messageLabel->setText(t);
154 }
155 
156 // cppcheck-suppress unusedFunction
157 /*
158 QPixmap CheckableMessageBox::iconPixmap() const
159 {
160  return d->pixmapLabel->pixmap(Qt::ReturnByValueConstant::ReturnByValue);
161 }
162 */
163 
165 {
166  d->pixmapLabel->setPixmap(p);
167  d->pixmapLabel->setVisible(!p.isNull());
168 }
169 
171 {
172  return d->checkBox->isChecked();
173 }
174 
176 {
177  d->checkBox->setChecked(s);
178 }
179 
181 {
182  return d->checkBox->text();
183 }
184 
186 {
187  d->checkBox->setText(t);
188 }
189 
190 // cppcheck-suppress unusedFunction
192 {
193  return d->checkBox->isVisible();
194 }
195 
197 {
198  d->checkBox->setVisible(v);
199 }
200 
201 QDialogButtonBox::StandardButtons CheckableMessageBox::standardButtons() const
202 {
203  return d->buttonBox->standardButtons();
204 }
205 
206 void CheckableMessageBox::setStandardButtons(QDialogButtonBox::StandardButtons s)
207 {
208  d->buttonBox->setStandardButtons(s);
209 }
210 
211 QPushButton *CheckableMessageBox::button(QDialogButtonBox::StandardButton b) const
212 {
213  return d->buttonBox->button(b);
214 }
215 
216 QPushButton *CheckableMessageBox::addButton(const QString &text, QDialogButtonBox::ButtonRole role)
217 {
218  return d->buttonBox->addButton(text, role);
219 }
220 
221 QDialogButtonBox::StandardButton CheckableMessageBox::defaultButton() const
222 {
223  foreach (QAbstractButton *b, d->buttonBox->buttons())
224  if (QPushButton *pb = qobject_cast<QPushButton *>(b))
225  {
226  if (pb->isDefault())
227  {
228  return d->buttonBox->standardButton(pb);
229  }
230  }
231  return QDialogButtonBox::NoButton;
232 }
233 
234 void CheckableMessageBox::setDefaultButton(QDialogButtonBox::StandardButton s)
235 {
236  if (QPushButton *b = d->buttonBox->button(s))
237  {
238  b->setDefault(true);
239  b->setFocus();
240  }
241 }
242 
243 QDialogButtonBox::StandardButton
245  const QString &title,
246  const QString &question,
247  const QString &checkBoxText,
248  bool *checkBoxSetting,
249  QDialogButtonBox::StandardButtons buttons,
250  QDialogButtonBox::StandardButton defaultButton)
251 {
252  CheckableMessageBox mb(parent);
253  mb.setWindowTitle(title);
254  mb.setIconPixmap(QMessageBox::standardIcon(QMessageBox::Question));
255  mb.setText(question);
257  mb.setChecked(*checkBoxSetting);
260  mb.exec();
261  *checkBoxSetting = mb.isChecked();
262  return mb.clickedStandardButton();
263 }
264 
265 QDialogButtonBox::StandardButton
267  const QString &title,
268  const QString &text,
269  const QString &checkBoxText,
270  bool *checkBoxSetting,
271  QDialogButtonBox::StandardButtons buttons,
272  QDialogButtonBox::StandardButton defaultButton)
273 {
274  CheckableMessageBox mb(parent);
275  mb.setWindowTitle(title);
276  mb.setIconPixmap(QMessageBox::standardIcon(QMessageBox::Information));
277  mb.setText(text);
279  mb.setChecked(*checkBoxSetting);
282  mb.exec();
283  *checkBoxSetting = mb.isChecked();
284  return mb.clickedStandardButton();
285 }
286 
287 // cppcheck-suppress unusedFunction
288 QMessageBox::StandardButton CheckableMessageBox::dialogButtonBoxToMessageBoxButton(QDialogButtonBox::StandardButton db)
289 {
290  return static_cast<QMessageBox::StandardButton>(int(db));
291 }
292 
293 bool CheckableMessageBox::askAgain(QSettings *settings, const QString &settingsSubKey)
294 {
295  //QTC_CHECK(settings);
296  if (settings)
297  {
298  settings->beginGroup(QLatin1String(kDoNotAskAgainKey));
299  bool shouldNotAsk = settings->value(settingsSubKey, false).toBool();
300  settings->endGroup();
301  if (shouldNotAsk)
302  {
303  return false;
304  }
305  }
306  return true;
307 }
308 
310  const QString &text, QDialogButtonBox::StandardButtons buttons,
311  QDialogButtonBox::StandardButton defaultButton,
312  DoNotAskAgainType type)
313 {
314  messageBox.setWindowTitle(title);
315  messageBox.setIconPixmap(QMessageBox::standardIcon(type == Information
316  ? QMessageBox::Information
317  : QMessageBox::Question));
318  messageBox.setText(text);
319  messageBox.setCheckBoxVisible(true);
322  messageBox.setChecked(false);
323  messageBox.setStandardButtons(buttons);
324  messageBox.setDefaultButton(defaultButton);
325 }
326 
327 void CheckableMessageBox::doNotAskAgain(QSettings *settings, const QString &settingsSubKey)
328 {
329  if (!settings)
330  {
331  return;
332  }
333 
334  settings->beginGroup(QLatin1String(kDoNotAskAgainKey));
335  settings->setValue(settingsSubKey, true);
336  settings->endGroup();
337 }
338 
339 /*!
340  Shows a message box with given \a title and \a text, and a \gui {Do not ask again} check box.
341  If the user checks the check box and accepts the dialog with the \a acceptButton,
342  further invocations of this function with the same \a settings and \a settingsSubKey will not
343  show the dialog, but instantly return \a acceptButton.
344 
345  Returns the clicked button, or QDialogButtonBox::NoButton if the user rejects the dialog
346  with the escape key, or \a acceptButton if the dialog is suppressed.
347 */
348 QDialogButtonBox::StandardButton
349 // cppcheck-suppress unusedFunction
350 CheckableMessageBox::doNotAskAgainQuestion(QWidget *parent, const QString &title,
351  const QString &text, QSettings *settings,
352  const QString &settingsSubKey,
353  QDialogButtonBox::StandardButtons buttons,
354  QDialogButtonBox::StandardButton defaultButton,
355  QDialogButtonBox::StandardButton acceptButton)
356 
357 {
358  if (!askAgain(settings, settingsSubKey))
359  {
360  return acceptButton;
361  }
362 
363  CheckableMessageBox messageBox(parent);
365  messageBox.exec();
366  if (messageBox.isChecked() && (messageBox.clickedStandardButton() == acceptButton))
367  {
368  doNotAskAgain(settings, settingsSubKey);
369  }
370 
371  return messageBox.clickedStandardButton();
372 }
373 
374 /*!
375  Shows a message box with given \a title and \a text, and a \gui {Do not show again} check box.
376  If the user checks the check box and quits the dialog, further invocations of this
377  function with the same \a settings and \a settingsSubKey will not show the dialog, but instantly return.
378 
379  Returns the clicked button, or QDialogButtonBox::NoButton if the user rejects the dialog
380  with the escape key, or \a defaultButton if the dialog is suppressed.
381 */
382 QDialogButtonBox::StandardButton
383 // cppcheck-suppress unusedFunction
384 CheckableMessageBox::doNotShowAgainInformation(QWidget *parent, const QString &title,
385  const QString &text, QSettings *settings,
386  const QString &settingsSubKey,
387  QDialogButtonBox::StandardButtons buttons,
388  QDialogButtonBox::StandardButton defaultButton)
389 
390 {
391  if (!askAgain(settings, settingsSubKey))
392  {
393  return defaultButton;
394  }
395 
396  CheckableMessageBox messageBox(parent);
398  messageBox.exec();
399  if (messageBox.isChecked())
400  {
401  doNotAskAgain(settings, settingsSubKey);
402  }
403 
404  return messageBox.clickedStandardButton();
405 }
406 
407 /*!
408  Resets all suppression settings for doNotAskAgainQuestion() found in \a settings,
409  so all these message boxes are shown again.
410  */
411 // cppcheck-suppress unusedFunction
413 {
414  //Q_ASSERT(settings, return);
415  settings->beginGroup(QLatin1String(kDoNotAskAgainKey));
416  settings->remove(QString());
417  settings->endGroup();
418 }
419 
420 /*!
421  Returns whether any message boxes from doNotAskAgainQuestion() are suppressed
422  in the \a settings.
423 */
424 // cppcheck-suppress unusedFunction
426 {
427  //Q_ASSERT(settings, return false);
428  bool hasSuppressed = false;
429  settings->beginGroup(QLatin1String(kDoNotAskAgainKey));
430  foreach (const QString &subKey, settings->childKeys())
431  {
432  if (settings->value(subKey, false).toBool())
433  {
434  hasSuppressed = true;
435  break;
436  }
437  }
438  settings->endGroup();
439  return hasSuppressed;
440 }
441 
442 /*!
443  Returns the standard \gui {Do not ask again} check box text.
444  \sa doNotAskAgainQuestion()
445 */
447 {
448  return QApplication::translate("Utils::CheckableMessageBox", "Do not &ask again");
449 }
450 
451 /*!
452  Returns the standard \gui {Do not show again} check box text.
453  \sa doNotShowAgainInformation()
454 */
456 {
457  return QApplication::translate("Utils::CheckableMessageBox", "Do not &show again");
458 }
459 
460 } // namespace Utils
static const char kDoNotAskAgainKey[]
The CheckableMessageBox class implements a message box suitable for questions with a "Do not ask me a...
static QDialogButtonBox::StandardButton doNotAskAgainQuestion(QWidget *parent, const QString &title, const QString &text, QSettings *settings, const QString &settingsSubKey, QDialogButtonBox::StandardButtons buttons=QDialogButtonBox::Yes|QDialogButtonBox::No, QDialogButtonBox::StandardButton defaultButton=QDialogButtonBox::No, QDialogButtonBox::StandardButton acceptButton=QDialogButtonBox::Yes)
Shows a message box with given title and text, and a \gui {Do not ask again} check box.
static QMessageBox::StandardButton dialogButtonBoxToMessageBoxButton(QDialogButtonBox::StandardButton)
static QString msgDoNotShowAgain()
Returns the standard \gui {Do not show again} check box text.
CheckableMessageBoxPrivate * d
QDialogButtonBox::StandardButtons buttons
QPushButton * button(QDialogButtonBox::StandardButton b) const
virtual ~CheckableMessageBox() Q_DECL_OVERRIDE
void setStandardButtons(QDialogButtonBox::StandardButtons s)
void slotClicked(QAbstractButton *b)
static void doNotAskAgain(QSettings *settings, const QString &settingsSubKey)
static void resetAllDoNotAskAgainQuestions(QSettings *settings)
Resets all suppression settings for doNotAskAgainQuestion() found in settings, so all these message b...
QDialogButtonBox::StandardButton clickedStandardButton() const
static QDialogButtonBox::StandardButton doNotShowAgainInformation(QWidget *parent, const QString &title, const QString &text, QSettings *settings, const QString &settingsSubKey, QDialogButtonBox::StandardButtons buttons=QDialogButtonBox::Ok, QDialogButtonBox::StandardButton defaultButton=QDialogButtonBox::NoButton)
Shows a message box with given title and text, and a \gui {Do not show again} check box.
void setCheckBoxText(const QString &)
static void initDoNotAskAgainMessageBox(CheckableMessageBox &messageBox, const QString &title, const QString &text, QDialogButtonBox::StandardButtons buttons, QDialogButtonBox::StandardButton defaultButton, DoNotAskAgainType type)
static bool hasSuppressedQuestions(QSettings *settings)
Returns whether any message boxes from doNotAskAgainQuestion() are suppressed in the settings.
static bool askAgain(QSettings *settings, const QString &settingsSubKey)
void setIconPixmap(const QPixmap &p)
static QString msgDoNotAskAgain()
Returns the standard \gui {Do not ask again} check box text.
QDialogButtonBox::StandardButtons standardButtons() const
static QDialogButtonBox::StandardButton question(QWidget *parent, const QString &title, const QString &question, const QString &checkBoxText, bool *checkBoxSetting, QDialogButtonBox::StandardButtons buttons=QDialogButtonBox::Yes|QDialogButtonBox::No, QDialogButtonBox::StandardButton defaultButton=QDialogButtonBox::No)
QDialogButtonBox::StandardButton defaultButton
QPushButton * addButton(const QString &text, QDialogButtonBox::ButtonRole role)
QAbstractButton * clickedButton() const
void setDefaultButton(QDialogButtonBox::StandardButton s)
static QDialogButtonBox::StandardButton information(QWidget *parent, const QString &title, const QString &text, const QString &checkBoxText, bool *checkBoxSetting, QDialogButtonBox::StandardButtons buttons=QDialogButtonBox::Ok, QDialogButtonBox::StandardButton defaultButton=QDialogButtonBox::NoButton)
#define translate(context, source)
Definition: vcmdexport.cpp:41