1 /****************************************************************************
3 ** Copyright (C) Qxt Foundation. Some rights reserved.
5 ** This file is part of the QxtGui module of the Qt eXTension library
7 ** This library is free software; you can redistribute it and/or modify it
8 ** under the terms of th Common Public License, version 1.0, as published by
11 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
12 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
13 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
14 ** FITNESS FOR A PARTICULAR PURPOSE.
16 ** You should have received a copy of the CPL along with this file.
17 ** See the LICENSE file and the cpl1.0.txt file included with the source
18 ** distribution for more information. If you did not receive a copy of the
19 ** license, contact the Qxt Foundation.
21 ** <http://libqxt.sourceforge.net> <foundation@libqxt.org>
23 ****************************************************************************/
24 #include "qxtconfirmationmessage.h"
26 #include <QCoreApplication>
27 #if QT_VERSION >= 0x040200
28 #include <QDialogButtonBox>
30 #include <QPushButton>
31 #include <QGridLayout>
34 static const QLatin1String DEFAULT_ORGANIZATION("QxtGui");
35 static const QLatin1String DEFAULT_APPLICATION("QxtConfirmationMessage");
37 class QxtConfirmationMessagePrivate : public QxtPrivate<QxtConfirmationMessage>
40 QXT_DECLARE_PUBLIC(QxtConfirmationMessage);
41 void init(const QString& message = QString());
43 static QString key(const QString& title, const QString& text, const QString& informativeText = QString());
45 void doNotShowAgain(int result);
46 static void reset(const QString& title, const QString& text, const QString& informativeText);
50 static QSettings::Scope scope;
53 QString QxtConfirmationMessagePrivate::path;
54 QSettings::Scope QxtConfirmationMessagePrivate::scope = QSettings::UserScope;
56 void QxtConfirmationMessagePrivate::init(const QString& message)
58 #if QT_VERSION >= 0x040200
59 confirm = new QCheckBox(&qxt_p());
60 if (!message.isNull())
61 confirm->setText(message);
63 confirm->setText(QxtConfirmationMessage::tr("Do not show again."));
65 QGridLayout* grid = qobject_cast<QGridLayout*>(qxt_p().layout());
66 QDialogButtonBox* buttons = qFindChild<QDialogButtonBox*>(&qxt_p());
69 const int idx = grid->indexOf(buttons);
70 int row, column, rowSpan, columnSpan = 0;
71 grid->getItemPosition(idx, &row, &column, &rowSpan, &columnSpan);
72 QLayoutItem* buttonsItem = grid->takeAt(idx);
73 grid->addWidget(confirm, row, column, rowSpan, columnSpan, Qt::AlignLeft | Qt::AlignTop);
74 grid->addItem(buttonsItem, ++row, column, rowSpan, columnSpan);
79 QString QxtConfirmationMessagePrivate::key() const
81 #if QT_VERSION >= 0x040200
82 return key(qxt_p().windowTitle(), qxt_p().text(), qxt_p().informativeText());
84 return key(qxt_p().windowTitle(), qxt_p().text());
88 QString QxtConfirmationMessagePrivate::key(const QString& title, const QString& text, const QString& informativeText)
90 const QString all = title + text + informativeText;
91 const QByteArray data = all.toLocal8Bit();
92 return QString::number(qChecksum(data.constData(), data.length()));
95 int QxtConfirmationMessagePrivate::showAgain()
97 QString organization = QCoreApplication::organizationName();
98 QString application = QCoreApplication::applicationName();
99 if (organization.isEmpty())
100 organization = DEFAULT_ORGANIZATION;
101 if (application.isEmpty())
102 application = DEFAULT_APPLICATION;
103 QSettings settings(scope, organization, application);
105 settings.beginGroup(path);
106 return settings.value(key(), -1).toInt();
109 void QxtConfirmationMessagePrivate::doNotShowAgain(int result)
111 QString organization = QCoreApplication::organizationName();
112 QString application = QCoreApplication::applicationName();
113 if (organization.isEmpty())
114 organization = DEFAULT_ORGANIZATION;
115 if (application.isEmpty())
116 application = DEFAULT_APPLICATION;
117 QSettings settings(scope, organization, application);
119 settings.beginGroup(path);
120 settings.setValue(key(), result);
123 void QxtConfirmationMessagePrivate::reset(const QString& title, const QString& text, const QString& informativeText)
125 QString organization = QCoreApplication::organizationName();
126 QString application = QCoreApplication::applicationName();
127 if (organization.isEmpty())
128 organization = DEFAULT_ORGANIZATION;
129 if (application.isEmpty())
130 application = DEFAULT_APPLICATION;
131 QSettings settings(scope, organization, application);
133 settings.beginGroup(path);
134 settings.remove(key(title, text, informativeText));
138 \class QxtConfirmationMessage QxtConfirmationMessage
140 \brief A confirmation message.
142 QxtConfirmationMessage is a confirmation message with checkable
143 <b>"Do not show again."</b> option. A checked and accepted confirmation
144 message is no more shown until reseted.
148 void MainWindow::closeEvent(QCloseEvent* event)
150 static const QString text(tr("Are you sure you want to quit?"));
151 if (QxtConfirmationMessage::confirm(this, tr("Confirm"), text) == QMessageBox::No)
156 \image html qxtconfirmationmessage.png "QxtConfirmationMessage in action."
158 \note \b QCoreApplication::organizationName and \b QCoreApplication::applicationName
159 are used for storing settings. In case these properties are empty, \b "QxtGui" and
160 \b "QxtConfirmationMessage" are used, respectively.
162 \note Requires Qt 4.2 or newer.
166 Constructs a new QxtConfirmationMessage with \a parent.
168 QxtConfirmationMessage::QxtConfirmationMessage(QWidget* parent)
169 : QMessageBox(parent)
171 QXT_INIT_PRIVATE(QxtConfirmationMessage);
176 Constructs a new QxtConfirmationMessage with \a icon, \a title, \a text, \a confirmation, \a buttons, \a parent and \a flags.
178 #if QT_VERSION >= 0x040200
179 QxtConfirmationMessage::QxtConfirmationMessage(QMessageBox::Icon icon, const QString& title, const QString& text, const QString& confirmation,
180 QMessageBox::StandardButtons buttons, QWidget* parent, Qt::WindowFlags flags)
181 : QMessageBox(icon, title, text, buttons, parent, flags)
183 QXT_INIT_PRIVATE(QxtConfirmationMessage);
184 qxt_d().init(confirmation);
189 Destructs the confirmation message.
191 QxtConfirmationMessage::~QxtConfirmationMessage()
194 // QMessageBox::StandardButton showNewMessageBox() (qmessagebox.cpp)
195 #if QT_VERSION >= 0x040200
196 QMessageBox::StandardButton QxtConfirmationMessage::confirm(QWidget* parent,
197 const QString& title, const QString& text, const QString& confirmation,
198 QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
200 QxtConfirmationMessage msgBox(QMessageBox::NoIcon, title, text, confirmation, QMessageBox::NoButton, parent);
201 QDialogButtonBox* buttonBox = qFindChild<QDialogButtonBox*>(&msgBox);
202 Q_ASSERT(buttonBox != 0);
204 uint mask = QMessageBox::FirstButton;
205 while (mask <= QMessageBox::LastButton)
207 uint sb = buttons & mask;
211 QPushButton* button = msgBox.addButton((QMessageBox::StandardButton)sb);
212 // Choose the first accept role as the default
213 if (msgBox.defaultButton())
215 if ((defaultButton == QMessageBox::NoButton && buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole)
216 || (defaultButton != QMessageBox::NoButton && sb == uint(defaultButton)))
217 msgBox.setDefaultButton(button);
219 if (msgBox.exec() == -1)
220 return QMessageBox::Cancel;
221 return msgBox.standardButton(msgBox.clickedButton());
226 \property QxtConfirmationMessage::confirmationText
227 \brief This property holds the confirmation text
229 The default value is <b>"Do not show again."</b>
231 QString QxtConfirmationMessage::confirmationText() const
233 return qxt_d().confirm->text();
236 void QxtConfirmationMessage::setConfirmationText(const QString& confirmation)
238 qxt_d().confirm->setText(confirmation);
242 \return The scope used for storing settings.
244 The default value is \b QSettings::UserScope.
246 QSettings::Scope QxtConfirmationMessage::settingsScope()
248 return QxtConfirmationMessagePrivate::scope;
252 Sets the scope used for storing settings.
254 void QxtConfirmationMessage::setSettingsScope(QSettings::Scope scope)
256 QxtConfirmationMessagePrivate::scope = scope;
260 \return The path used for storing settings.
262 The default value is an empty string.
264 QString QxtConfirmationMessage::settingsPath()
266 return QxtConfirmationMessagePrivate::path;
270 Sets the path used for storing settings.
272 void QxtConfirmationMessage::setSettingsPath(const QString& path)
274 QxtConfirmationMessagePrivate::path = path;
278 Shows the confirmation message if necessary. The confirmation message is not
279 shown in case <b>"Do not show again."</b> has been checked while the same
280 confirmation message was earlierly accepted.
282 A confirmation message is identified by the combination of title,
283 \b QMessageBox::text and optional \b QMessageBox::informativeText.
285 A clicked button with role \b QDialogButtonBox::AcceptRole or
286 \b QDialogButtonBox::YesRole is considered as "accepted".
288 \warning This function does not reimplement but shadows \b QMessageBox::exec().
290 \sa QWidget::windowTitle, QMessageBox::text, QMessageBox::informativeText
292 int QxtConfirmationMessage::exec()
294 int res = qxt_d().showAgain();
296 res = QMessageBox::exec();
300 void QxtConfirmationMessage::done(int result)
302 #if QT_VERSION >= 0x040200
303 QDialogButtonBox* buttons = qFindChild<QDialogButtonBox*>(this);
304 Q_ASSERT(buttons != 0);
306 int role = buttons->buttonRole(clickedButton());
307 if (qxt_d().confirm->isChecked() &&
308 (role == QDialogButtonBox::AcceptRole || role == QDialogButtonBox::YesRole))
310 qxt_d().doNotShowAgain(result);
313 QMessageBox::done(result);
317 Resets confirmation message with given \a title, \a text and optional
318 \a informativeText. A reseted confirmation message is shown again until
319 user checks <b>"Do not show again."</b> and accepts the confirmation message.
321 void QxtConfirmationMessage::reset(const QString& title, const QString& text, const QString& informativeText)
323 QxtConfirmationMessagePrivate::reset(title, text, informativeText);
327 Resets this instance of QxtConfirmationMessage. A reseted confirmation
328 message is shown again until user checks <b>"Do not show again."</b> and
329 accepts the confirmation message.
331 void QxtConfirmationMessage::reset()
333 #if QT_VERSION >= 0x040200
334 QxtConfirmationMessagePrivate::reset(windowTitle(), text(), informativeText());