File indexing completed on 2025-02-16 13:11:44
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2020 Ahmad Samir <a.samirh78@gmail.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0006 */ 0007 0008 #ifndef KMESSAGEDIALOG_H 0009 #define KMESSAGEDIALOG_H 0010 0011 #include <kwidgetsaddons_export.h> 0012 0013 #include <KStandardGuiItem> 0014 0015 #include <QDialog> 0016 #include <QDialogButtonBox> 0017 #include <QMessageBox> 0018 0019 #include <memory> 0020 0021 class KMessageDialogPrivate; 0022 class KGuiItem; 0023 0024 /** 0025 * @class KMessageDialog kmessagedialog.h <KMessageDialog> 0026 * 0027 * 0028 * @brief KMessageDialog creates a message box similar to the ones you get from KMessageBox, 0029 * but that can be used asynchronously, i.e. you can show the dialog by using @c show() 0030 * or @c open(). 0031 * 0032 * This class contructs a dialog similar to the dialogs the KMessageBox convenience functions 0033 * create. The main difference is that the KMessageBox methods typically use @c exec() to show 0034 * the dialogs; one of the main disadvantages of using @c exec(), is that it starts a nested 0035 * eventloop, which could lead to nasty crashes. 0036 * 0037 * Another difference is that the API is supposed to be slightly easier to use as it has 0038 * various methods to set up the dialog, e.g. @ref setCaption(), @ref setDetails() ...etc. 0039 * 0040 * By default, appropriate buttons based on the dialog type are added (since 5.85) (e.g. an 0041 * "OK" button is added to an Information dialog), you can set custom buttons by using the 0042 * @ref setButtons() method. 0043 * 0044 * The @ref QDialog::done() slot is called to set the result of the dialog, which will emit the 0045 * @ref QDialog::finished() signal with that result. The result is one of the 0046 * KMessageDialog::ButtonType enum. This is useful as you can tell exactly which button 0047 * was clicked by the user. E.g.: 0048 * - the secondary action button having been clicked, in which case you may still want to save the status 0049 * of the "Do not ask again" CheckBox 0050 * - the "Cancel" button having been clicked, in which case you ideally will ignore the status 0051 * of the "Do not ask again" CheckBox 0052 * 0053 * For "warning" dialogs, i.e. dialogs with a potentially destructive action, the default 0054 * button is set to a button with the QDialogButtonBox::RejectRole. If the "Cancel" button 0055 + * is used, it will be the default, otherwise the secondary action button. 0056 * 0057 * This class intends to be very flexible with the buttons that can be used, since you can 0058 * call the @ref setButtons() method with a KGuiItem that has custom text/icon. 0059 * 0060 * Since Frameworks 5.97 a notification sound is played when the dialog opens like KMessageBox 0061 * does, this can be controlled using the @ref setNotifyEnabled() method. 0062 * 0063 * Example: 0064 * @code 0065 * auto *dlg = new KMessageDialog(KMessageDialog::QuestionTwoActionsCancel, 0066 * QStringLiteral("Back or forward?"), 0067 * nullptr); 0068 * 0069 * dlg->setCaption(QStringLiteral("Window Title")); 0070 * dlg->setButtons(KStandardGuiItem::back(), KStandardGuiItem::forward(), KStandardGuiItem::cancel()); 0071 * dlg->setListWidgetItems(QStringList{QStringLiteral("file1"), QStringLiteral("file2")}); 0072 * dlg->setDetails(QStringLiteral("Some more details.")); 0073 * dlg->setDontAskAgainText(QStringLiteral("Do not ask again")); 0074 * dlg->setDontAskAgainChecked(false); 0075 * 0076 * // Delete the dialog when it's closed 0077 * dlg->setAttribute(Qt::WA_DeleteOnClose); 0078 * // Make the dialog window modal 0079 * dlg->setWindowModality(Qt::WindowModal); 0080 * 0081 * QObject::connect(dlg, &QDialog::finished, &app, [dlg](int result) { 0082 * auto button = static_cast<KMessageDialog::ButtonType>(result); 0083 * switch(button) { 0084 * case KMessageDialog::Ok: 0085 * case KMessageDialog::PrimaryAction: 0086 * // The user clicked the primary action, handle the result... 0087 * // save the "do not ask again" box status... 0088 * break; 0089 * case KMessageDialog::SecondaryAction: 0090 * // The user clicked the secondary action, handle the result... 0091 * // save the "do not ask again" box status... 0092 * break; 0093 * case KMessageDialog::Cancel: 0094 * // The user clicked cancel, reject the changes... 0095 * break; 0096 * default: 0097 * break; 0098 * } 0099 * }); 0100 * 0101 * dlg->show(); 0102 * @endcode 0103 * 0104 * @since 5.77 0105 */ 0106 0107 class KWIDGETSADDONS_EXPORT KMessageDialog : public QDialog 0108 { 0109 Q_OBJECT 0110 0111 public: 0112 /** 0113 * Button types 0114 * @since 5.100 0115 */ 0116 enum ButtonType { 0117 /// For backward-compatibility with KF < 5.100 only, use @c QDialogButtonBox::Ok. 0118 Ok = QDialogButtonBox::Ok, 0119 /// For backward-compatibility with KF < 5.100 only, use @c QDialogButtonBox::Cancel. 0120 Cancel = QDialogButtonBox::Cancel, 0121 /// For backward-compatibility with KF < 5.100 only, use @c QDialogButtonBox::Yes. 0122 PrimaryAction = QDialogButtonBox::Yes, 0123 /// For backward-compatibility with KF < 5.100 only, use @c QDialogButtonBox::No. 0124 SecondaryAction = QDialogButtonBox::No, 0125 }; 0126 0127 enum Type { 0128 QuestionTwoActions = 1, ///< @since 5.100 0129 QuestionTwoActionsCancel = 2, ///< @since 5.100 0130 WarningTwoActions = 3, ///< @since 5.100 0131 WarningTwoActionsCancel = 4, ///< @since 5.100 0132 WarningContinueCancel = 5, 0133 Information = 6, 0134 #if KWIDGETSADDONS_ENABLE_DEPRECATED_SINCE(5, 97) 0135 Sorry ///< @deprecated Since 5.97, use Error. 0136 KWIDGETSADDONS_ENUMERATOR_DEPRECATED_VERSION(5, 97, "Use Error.") = 7, 0137 #endif 0138 Error = 8, 0139 #if KWIDGETSADDONS_ENABLE_DEPRECATED_SINCE(5, 100) 0140 /// @deprecated Since 5.100, use QuestionTwoActions. 0141 QuestionYesNo KWIDGETSADDONS_ENUMERATOR_DEPRECATED_VERSION(5, 100, "Use QuestionTwoActions.") = QuestionTwoActions, 0142 /// @deprecated Since 5.100, use QuestionTwoActionsCancel. 0143 QuestionYesNoCancel KWIDGETSADDONS_ENUMERATOR_DEPRECATED_VERSION(5, 100, "Use QuestionTwoActionsCancel.") = QuestionTwoActionsCancel, 0144 /// @deprecated Since 5.100, use WarningTwoActions. 0145 WarningYesNo KWIDGETSADDONS_ENUMERATOR_DEPRECATED_VERSION(5, 100, "Use WarningTwoActions.") = WarningTwoActions, 0146 /// @deprecated Since 5.100, use WarningTwoActionsCancel. 0147 WarningYesNoCancel KWIDGETSADDONS_ENUMERATOR_DEPRECATED_VERSION(5, 100, "Use WarningTwoActionsCancel.") = WarningTwoActionsCancel, 0148 #endif 0149 }; 0150 0151 /** 0152 * Constructs a KMessageDialog. 0153 * 0154 * Since 5.85 buttons based on the dialog type are set by default in some cases, 0155 * using KStandardGuiItem instances. For the dialog types Information, Sorry & Error 0156 * the button is set to KStandardGuiItem::ok(). For the type WarningContinueCancel 0157 * the buttons are set to KStandardGuiItem::cont() & KStandardGuiItem::cancel(). 0158 * 0159 * For the other Quesion* and Warning* types the buttons are to be set explicitly. 0160 * Since 5.85 and if KWidgetsAddons is built with support for deprecated API including 5.100, 0161 * also for these types the buttons are set by default, using KStandardGuiItem instances. 0162 * - QuestionTwoActions: KStandardGuiItem::yes(), KStandardGuiItem::no() 0163 * - QuestionTwoActionsCancel: KStandardGuiItem::yes(), KStandardGuiItem::no() 0164 * - WarningTwoActions: KStandardGuiItem::yes(), KStandardGuiItem::no() 0165 * - WarningTwoActionsCancel: KStandardGuiItem::yes(), KStandardGuiItem::no() 0166 * 0167 * @param type the dialog Type, one of KMessageDialog::Type enum 0168 * @param text the text message that is going to be displayed in the dialog 0169 * @param parent a QWidget* that will be set as the dialog parent 0170 */ 0171 explicit KMessageDialog(KMessageDialog::Type type, const QString &text, QWidget *parent = nullptr); 0172 0173 /** 0174 * This constructor takes the window Id of the parent window, instead of a QWidget*. 0175 * 0176 * @param type the dialog Type, one of KMessageDialog::Type enum 0177 * @param text the text message that is going to be displayed in the dialog 0178 * @param parent_id the native parent's window system identifier 0179 */ 0180 explicit KMessageDialog(KMessageDialog::Type type, const QString &text, WId parent_id); 0181 /** 0182 * Destructor 0183 */ 0184 ~KMessageDialog() override; 0185 0186 /** 0187 * This can be used to set the title of the dialog window. If you pass an 0188 * empty QString(), a generic title will be used depending on the dialog 0189 * Type. E.g. for KMessageDialog::WarningTwoActions, "Warning" will be used. 0190 */ 0191 void setCaption(const QString &caption); 0192 0193 /** 0194 * This can be used to set an icon that will be shown next to the main 0195 * text message. If you pass a null QIcon() a generic icon based on the dialog 0196 * Type will be used. E.g. for KMessageDialog::QuestionTwoActions, QMessageBox::Question 0197 * will be used. 0198 */ 0199 void setIcon(const QIcon &icon); 0200 0201 /** 0202 * This will add a QListWidget to the dialog and populate it with @p strlist. 0203 * If @p strlist is empty, the list widget will not be shown. 0204 */ 0205 void setListWidgetItems(const QStringList &strlist); 0206 0207 /** 0208 * This will add a KCollapsibleGroupBox with a title "Details", as the class name 0209 * implies it is collapsible (and collapsed by default); you can use it to add a 0210 * more detailed explanation of what the dialog is trying to tell the user. 0211 * 0212 * If @p details is empty, the details widget will not be shown. 0213 */ 0214 void setDetails(const QString &details); 0215 0216 /** 0217 * This will add a "Do not ask again" checkbox to the dialog with the text 0218 * from @p dontAskAgainText. You can set the initial status of the checkbox 0219 * by using setDontAskAgainChecked(). 0220 * 0221 * If @p dontAskAgainText is empty, no checkbox will be shown. 0222 * 0223 * Typical usage of this checkbox is for recurring questions, e.g. showing 0224 * a dialog to confirm moving files/directories to trash, the user can then 0225 * set the checkbox so as not to be asked about that again. 0226 * 0227 * You can get the state of the checkbox by using isDontAskAgainChecked(). 0228 */ 0229 void setDontAskAgainText(const QString &dontAskAgainText); 0230 0231 /** 0232 * This can be used to set the initial status of the "Do not ask again" checkbox, 0233 * checked or unchecked, by setting @p isChecked to @c true or @c false 0234 * respectively. 0235 * 0236 * You need to call setDontAskAgainText() first to actually show a checkbox in 0237 * the dialog, otherwise calling this function will have no effect. 0238 */ 0239 void setDontAskAgainChecked(bool isChecked); 0240 0241 /** 0242 * This can be used to query the status of the "Do not ask again" checkbox; 0243 * returns @c true if the box is checked and @c false otherwise. 0244 * 0245 * @note This method will return @c false if a checkbox widget isn't shown in 0246 * the dialog. The dialog will not show a checkbox if setDontAskAgainText() was 0247 * not used previously to add a checkbox to begin with. 0248 */ 0249 bool isDontAskAgainChecked() const; 0250 0251 /** 0252 * Sets the text labels in the dialog to either allow opening external links or not. 0253 */ 0254 void setOpenExternalLinks(bool isAllowed); 0255 0256 /** 0257 * Whether a KNotification is emitted when the dialog is shown. 0258 * 0259 * This typically plays a notification sound. Default is true. 0260 * 0261 * @since 5.97 0262 * @sa KMessageBox::Notify 0263 */ 0264 bool isNotifyEnabled() const; 0265 0266 /** 0267 * Whether to emit a KNotification when the dialog is shown. 0268 * 0269 * This typically plays a notification sound. 0270 * 0271 * @since 5.97 0272 * @sa KMessageBox::Notify 0273 */ 0274 void setNotifyEnabled(bool enable); 0275 0276 /** 0277 * Sets the buttons in the buttom box. 0278 * 0279 * Using this method, you can customize the behavior based on your use-case, by 0280 * using a KGuiItem to get a button with custom text and icon. 0281 * 0282 * Since 5.85 buttons based on the dialog type are added by default (see 0283 * KMessageDialog(KMessageDialog::Type, const QString &, QWidget *) for details). 0284 * Before, this method had to be called explicitly to have any buttons added to the dialog. 0285 * 0286 * @note 0287 * - For WarningContinueCancel dialog Type, if primaryAction has the same text as 0288 * KStandardGuiItem::yes(), KStandardGuiItem::cont() will be used instead (as long 0289 * as KWidgetsAddons is built with the deprecated KStandardGuiItem::yes()). 0290 * - For dialog types Information, Sorry, and Error only one button 0291 * (KStandardGuiItem::ok()) is added to the dialog. 0292 * 0293 * @param primaryAction the action for the primary button. 0294 * Reported in the result for dialog types Information, Sorry, and Error 0295 * as KMessageDialog::Ok enum value, otherwise as KMessageDialog::PrimaryAction. 0296 * @param secondaryAction the action for the secondary button. 0297 * Reported in the result as KMessageDialog::SecondaryAction enum value. 0298 * Ignored with all dialog types without a "secondary" action. 0299 * @param cancelAction the action for the cancel button. 0300 * Reported in the result as KMessageDialog::Cancel enum value. 0301 * Ignored with all dialog types without a Cancel button. 0302 */ 0303 #if KWIDGETSADDONS_ENABLE_DEPRECATED_SINCE(5, 100) 0304 void setButtons(const KGuiItem &primaryAction = KStandardGuiItem::yes(), 0305 const KGuiItem &secondaryAction = KStandardGuiItem::no(), 0306 const KGuiItem &cancelAction = KStandardGuiItem::cancel()); 0307 #else 0308 void setButtons(const KGuiItem &primaryAction = KGuiItem(), const KGuiItem &secondaryAction = KGuiItem(), const KGuiItem &cancelAction = KGuiItem()); 0309 #endif 0310 0311 private: 0312 std::unique_ptr<KMessageDialogPrivate> const d; 0313 }; 0314 0315 #endif // KMESSAGEDIALOG_H