ctkMessageBox.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0.txt
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. // Qt includes
  15. #include <QCheckBox>
  16. #include <QDebug>
  17. #include <QGridLayout>
  18. #include <QPushButton>
  19. #include <QSettings>
  20. #include <QTimer>
  21. // CTK includes
  22. #include "ctkMessageBox.h"
  23. //-----------------------------------------------------------------------------
  24. // ctkMessageBoxPrivate methods
  25. //-----------------------------------------------------------------------------
  26. class ctkMessageBoxPrivate
  27. {
  28. Q_DECLARE_PUBLIC(ctkMessageBox);
  29. protected:
  30. ctkMessageBox* const q_ptr;
  31. public:
  32. explicit ctkMessageBoxPrivate(ctkMessageBox& object);
  33. virtual ~ctkMessageBoxPrivate();
  34. void init();
  35. int dontShowAgainButtonOrRole();
  36. QAbstractButton* button(int buttonOrRole);
  37. int buttonFromSettings();
  38. void readSettings();
  39. void writeSettings(int button);
  40. public:
  41. QString DontShowAgainSettingsKey;
  42. QCheckBox* DontShowAgainCheckBox;
  43. bool SaveDontShowAgainSettingsOnAcceptOnly;
  44. };
  45. //-----------------------------------------------------------------------------
  46. ctkMessageBoxPrivate::ctkMessageBoxPrivate(ctkMessageBox& object)
  47. : q_ptr(&object)
  48. {
  49. this->DontShowAgainSettingsKey = QString();
  50. this->DontShowAgainCheckBox = 0;
  51. this->SaveDontShowAgainSettingsOnAcceptOnly = true;
  52. }
  53. //-----------------------------------------------------------------------------
  54. ctkMessageBoxPrivate::~ctkMessageBoxPrivate()
  55. {
  56. }
  57. //-----------------------------------------------------------------------------
  58. void ctkMessageBoxPrivate::init()
  59. {
  60. Q_Q(ctkMessageBox);
  61. this->DontShowAgainCheckBox = new QCheckBox(q);
  62. this->DontShowAgainCheckBox->setObjectName(QLatin1String("ctk_msgbox_dontshowcheckbox"));
  63. this->DontShowAgainCheckBox->setText(q->tr("Don't show this message again"));
  64. // The height policy being Fixed by default on a checkbox, if the message box icon
  65. // is bigger than the text+checkbox height, it would be truncated.
  66. this->DontShowAgainCheckBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
  67. this->DontShowAgainCheckBox->setChecked(false);
  68. this->DontShowAgainCheckBox->hide();
  69. }
  70. //-----------------------------------------------------------------------------
  71. int ctkMessageBoxPrivate::dontShowAgainButtonOrRole()
  72. {
  73. int buttonOrRole = QMessageBox::InvalidRole;
  74. if (this->DontShowAgainCheckBox->isChecked())
  75. {
  76. buttonOrRole = this->buttonFromSettings();
  77. if (buttonOrRole == QMessageBox::InvalidRole)
  78. {
  79. buttonOrRole = QMessageBox::AcceptRole;
  80. }
  81. }
  82. return buttonOrRole;
  83. }
  84. //-----------------------------------------------------------------------------
  85. QAbstractButton* ctkMessageBoxPrivate::button(int buttonOrRole)
  86. {
  87. Q_Q(ctkMessageBox);
  88. QAbstractButton* autoAcceptButton = 0;
  89. // Special case when no button is in a dialog, QMessageBox adds the Ok
  90. // button automatically.
  91. if (q->buttons().size() == 0 &&
  92. buttonOrRole != QMessageBox::InvalidRole)
  93. {
  94. q->addButton(QMessageBox::Ok);
  95. }
  96. if ( q->standardButtons() & buttonOrRole)
  97. {
  98. autoAcceptButton = q->button(static_cast<QMessageBox::StandardButton>(buttonOrRole));
  99. }
  100. else
  101. {
  102. foreach(QAbstractButton* button, q->buttons())
  103. {
  104. if (q->buttonRole(button) == buttonOrRole)
  105. {
  106. autoAcceptButton = button;
  107. break;
  108. }
  109. }
  110. }
  111. return autoAcceptButton;
  112. }
  113. //-----------------------------------------------------------------------------
  114. int ctkMessageBoxPrivate::buttonFromSettings()
  115. {
  116. QSettings settings;
  117. int button = settings.value(this->DontShowAgainSettingsKey,
  118. static_cast<int>(QMessageBox::InvalidRole)).toInt();
  119. return button;
  120. }
  121. //-----------------------------------------------------------------------------
  122. void ctkMessageBoxPrivate::readSettings()
  123. {
  124. if (this->DontShowAgainSettingsKey.isEmpty())
  125. {
  126. return;
  127. }
  128. int button = this->buttonFromSettings();
  129. this->DontShowAgainCheckBox->setChecked(button != QMessageBox::InvalidRole);
  130. }
  131. //-----------------------------------------------------------------------------
  132. void ctkMessageBoxPrivate::writeSettings(int button)
  133. {
  134. if (this->DontShowAgainSettingsKey.isEmpty())
  135. {
  136. return;
  137. }
  138. QSettings settings;
  139. settings.setValue(this->DontShowAgainSettingsKey,
  140. QVariant(this->DontShowAgainCheckBox->isChecked() ?
  141. button : QMessageBox::InvalidRole));
  142. }
  143. //-----------------------------------------------------------------------------
  144. // ctkMessageBox methods
  145. //-----------------------------------------------------------------------------
  146. ctkMessageBox::ctkMessageBox(QWidget* newParent)
  147. : Superclass(newParent)
  148. , d_ptr(new ctkMessageBoxPrivate(*this))
  149. {
  150. Q_D(ctkMessageBox);
  151. d->init();
  152. }
  153. //-----------------------------------------------------------------------------
  154. ctkMessageBox::ctkMessageBox(Icon icon, const QString& title,
  155. const QString& text, StandardButtons buttons,
  156. QWidget* parent, Qt::WindowFlags f)
  157. : QMessageBox(icon, title, text, buttons, parent, f)
  158. {
  159. Q_D(ctkMessageBox);
  160. d->init();
  161. }
  162. //-----------------------------------------------------------------------------
  163. ctkMessageBox::~ctkMessageBox()
  164. {
  165. }
  166. //-----------------------------------------------------------------------------
  167. void ctkMessageBox::setDontShowAgainVisible(bool visible)
  168. {
  169. Q_D(ctkMessageBox);
  170. if (!visible)
  171. {
  172. this->layout()->removeWidget(d->DontShowAgainCheckBox);
  173. d->DontShowAgainCheckBox->hide();
  174. return;
  175. }
  176. QGridLayout *grid = static_cast<QGridLayout *>(this->layout());
  177. d->DontShowAgainCheckBox->setVisible(true);
  178. grid->addWidget(d->DontShowAgainCheckBox, 1, 1, 1, 1);
  179. }
  180. //-----------------------------------------------------------------------------
  181. bool ctkMessageBox::isDontShowAgainVisible()const
  182. {
  183. Q_D(const ctkMessageBox);
  184. return d->DontShowAgainCheckBox->isVisibleTo(const_cast<ctkMessageBox*>(this));
  185. }
  186. //-----------------------------------------------------------------------------
  187. void ctkMessageBox::setDontShowAgainSettingsKey(const QString& key)
  188. {
  189. Q_D(ctkMessageBox);
  190. if (key == d->DontShowAgainSettingsKey)
  191. {
  192. return;
  193. }
  194. d->DontShowAgainSettingsKey = key;
  195. d->readSettings();
  196. this->setDontShowAgainVisible(!key.isEmpty());
  197. }
  198. //-----------------------------------------------------------------------------
  199. QString ctkMessageBox::dontShowAgainSettingsKey()const
  200. {
  201. Q_D(const ctkMessageBox);
  202. return d->DontShowAgainSettingsKey;
  203. }
  204. //-----------------------------------------------------------------------------
  205. bool ctkMessageBox::dontShowAgain()const
  206. {
  207. Q_D(const ctkMessageBox);
  208. return d->DontShowAgainCheckBox->isChecked();
  209. }
  210. //-----------------------------------------------------------------------------
  211. void ctkMessageBox::setDontShowAgain(bool dontShow)
  212. {
  213. Q_D(ctkMessageBox);
  214. d->DontShowAgainCheckBox->setChecked(dontShow);
  215. // We don't write into settings here because we want the same behavior
  216. // as if the user clicked on the checkbox.
  217. // If you want to save the preference into settings even if the user
  218. // escape/cancel/reject the dialog, then you must set the QSettings value
  219. // manually
  220. }
  221. //-----------------------------------------------------------------------------
  222. void ctkMessageBox::done(int resultCode)
  223. {
  224. Q_D(ctkMessageBox);
  225. // Don't save if the button is not an accepting button
  226. if (!d->SaveDontShowAgainSettingsOnAcceptOnly ||
  227. this->buttonRole( this->clickedButton() ) == QMessageBox::AcceptRole )
  228. {
  229. d->writeSettings(resultCode);
  230. }
  231. this->Superclass::done(resultCode);
  232. }
  233. //-----------------------------------------------------------------------------
  234. void ctkMessageBox::setVisible(bool visible)
  235. {
  236. Q_D(ctkMessageBox);
  237. if (visible)
  238. {
  239. int dontShowAgainButtonOrRole = d->dontShowAgainButtonOrRole();
  240. QAbstractButton* autoAcceptButton = d->button(dontShowAgainButtonOrRole);
  241. if (autoAcceptButton)
  242. {
  243. // Don't call click now, it would destroy the message box. The calling
  244. // function might expect the message box to be still valid after
  245. // setVisible() return.
  246. QTimer::singleShot(0, autoAcceptButton, SLOT(click()));
  247. return;
  248. }
  249. }
  250. this->Superclass::setVisible(visible);
  251. }
  252. //-----------------------------------------------------------------------------
  253. bool ctkMessageBox
  254. ::confirmExit(const QString& dontShowAgainKey, QWidget* parentWidget)
  255. {
  256. ctkMessageBox dialog(parentWidget);
  257. dialog.setText(tr("Are you sure you want to exit?"));
  258. dialog.setIcon(QMessageBox::Question);
  259. dialog.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
  260. dialog.setDontShowAgainSettingsKey(dontShowAgainKey);
  261. return dialog.exec() == QMessageBox::Ok;
  262. }