Kirigami-addons

MessageDialog.qml
1// SPDX-FileCopyrightText: 2021 Claudio Cambra <claudio.cambra@gmail.com>
2// SPDX-FileCopyrightText: 2023 Carl Schwan <carl@carlschwan.eu>
3// SPDX-License-Identifier: LGPL-2.1-or-later
4
5import QtQuick
6import QtQuick.Controls as QQC2
7import QtQuick.Templates as T
8import QtQuick.Layouts
9import org.kde.kirigami as Kirigami
10import org.kde.kirigamiaddons.components as Components
11import org.kde.kirigamiaddons.formcard as FormCard
12import org.kde.kirigamiaddons.delegates as Delegates
13
14/**
15 * A dialog to show a message. This dialog exists has 4 modes: success, warning, error, information.
16 *
17 * @image html messagedialog.png
18 */
19T.Dialog {
20 id: root
21
22 enum DialogType {
23 Success,
24 Warning,
25 Error,
26 Information
27 }
28
29 /**
30 * This property holds the dialogType. It can be either:
31 *
32 * - `MessageDialog.Success`: For a sucess message
33 * - `MessageDialog.Warning`: For a warning message
34 * - `MessageDialog.Error`: For an actual error
35 * - `MessageDialog.Information`: For an informational message
36 *
37 * By default, the dialogType is `MessageDialog.Success`
38 */
39 property int dialogType: Components.MessageDialog.Success
40
41 /**
42 * @brief This property holds the name of setting to store the "dont's show again" preference.
43 *
44 * If provided, a checkbox is added with which further notifications can be turned off.
45 * The string is used to lookup and store the setting in the applications config file.
46 * The setting is stored in the "Notification Messages" group.
47 *
48 * When set use, openDialog() instead of open() to open this dialog.
49 *
50 * @warning Overwriting the dialog's footer will disable this feature.
51 */
52 property string dontShowAgainName: ''
53
54 function standardButton(button) {
55 return dialogButtonBox.standardButton(button);
56 }
57
58 default property alias mainContent: mainLayout.data
59
60 property string iconName: switch (root.dialogType) {
61 case MessageDialog.Success:
62 return "data-success";
63 case MessageDialog.Warning:
64 return "data-warning";
65 case MessageDialog.Error:
66 return "data-error";
67 case MessageDialog.Information:
68 return "data-information";
69 default:
70 return "data-warning";
71 }
72
73 x: Math.round((parent.width - width) / 2)
74 y: Math.round((parent.height - height) / 2)
75 z: Kirigami.OverlayZStacking.z
76
77 parent: applicationWindow().QQC2.Overlay.overlay
78
79 implicitWidth: Math.min(parent.width - Kirigami.Units.gridUnit * 2, Kirigami.Units.gridUnit * 20)
80 implicitHeight: Math.min(Math.max(implicitBackgroundHeight + topInset + bottomInset,
81 contentHeight + topPadding + bottomPadding
82 + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0)
83 + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)), parent.height - Kirigami.Units.gridUnit * 2, Kirigami.Units.gridUnit * 30)
84
85 title: switch (root.dialogType) {
86 case MessageDialog.Success:
87 return i18ndc("kirigami-addons6", "@title:dialog", "Success");
88 case MessageDialog.Warning:
89 return i18ndc("kirigami-addons6", "@title:dialog", "Warning");
90 case MessageDialog.Error:
91 return i18ndc("kirigami-addons6", "@title:dialog", "Error");
92 case MessageDialog.Information:
93 return i18ndc("kirigami-addons6", "@title:dialog", "Information");
94 default:
95 return i18ndc("kirigami-addons6", "@title:dialog", "Warning");
96 }
97
98 padding: Kirigami.Units.largeSpacing * 2
99 bottomPadding: Kirigami.Units.largeSpacing
100
101 property bool _automaticallyClosed: false
102
103 /**
104 * Open the dialog only if the user didn't check the "do not remind me" checkbox
105 * previously.
106 */
107 function openDialog(): void {
108 if (root.dontShowAgainName.length > 0) {
109 if (root.standardButtons === QQC2.Dialog.Ok) {
110 const show = MessageDialogHelper.shouldBeShownContinue(root.dontShowAgainName);
111 if (!show) {
112 root._automaticallyClosed = true;
113 root.applied();
114 root.accepted();
115 } else {
116 checkbox.checked = false;
117 root._automaticallyClosed = false;
118 root.open();
119 }
120 } else {
121 const result = MessageDialogHelper.shouldBeShownTwoActions(root.dontShowAgainName);
122 if (!result.show) {
123 root._automaticallyClosed = true;
124 if (result.result) {
125 root.accepted();
126 root.applied();
127 } else {
128 root.discarded();
129 }
130 } else {
131 checkbox.checked = false;
132 root._automaticallyClosed = false;
133 root.open();
134 }
135 }
136 }
137 }
138
139 onApplied: {
140 if (root.dontShowAgainName && checkbox.checked && !root._automaticallyClosed) {
141 if (root.standardButtons === QQC2.Dialog.Ok) {
142 MessageDialogHelper.saveDontShowAgainContinue(root.dontShowAgainName);
143 } else {
144 MessageDialogHelper.saveDontShowAgainTwoActions(root.dontShowAgainName, true);
145 }
146 }
147 }
148
149 onAccepted: {
150 if (root.dontShowAgainName && checkbox.checked && !root._automaticallyClosed) {
151 if (root.standardButtons === QQC2.Dialog.Ok) {
152 MessageDialogHelper.saveDontShowAgainContinue(root.dontShowAgainName);
153 } else {
154 MessageDialogHelper.saveDontShowAgainTwoActions(root.dontShowAgainName, true);
155 }
156 }
157 }
158
159 onDiscarded: {
160 if (root.dontShowAgainName && checkbox.checked && !root._automaticallyClosed) {
161 if (root.standardButtons === QQC2.Dialog.Ok) {
162 MessageDialogHelper.saveDontShowAgainContinue(root.dontShowAgainName);
163 } else {
164 MessageDialogHelper.saveDontShowAgainTwoActions(root.dontShowAgainName, false);
165 }
166 }
167 }
168
169 contentItem: GridLayout {
170 id: gridLayout
171
172 columns: !icon.visible || root._mobileLayout ? 1 : 2
173 rowSpacing: 0
174
175 Kirigami.Icon {
176 id: icon
177
178 visible: root.iconName.length > 0
179 source: root.iconName
180 Layout.preferredWidth: Kirigami.Units.iconSizes.huge
181 Layout.preferredHeight: Kirigami.Units.iconSizes.huge
182 Layout.alignment: gridLayout.columns === 2 ? Qt.AlignTop : Qt.AlignHCenter
183 }
184
185 ColumnLayout {
186 id: mainLayout
187
188 spacing: Kirigami.Units.smallSpacing
189
190 Layout.fillWidth: true
191
192 Kirigami.Heading {
193 text: root.title
194 visible: root.title
195 elide: QQC2.Label.ElideRight
196 wrapMode: Text.WordWrap
197 horizontalAlignment: gridLayout.columns === 2 ? Qt.AlignLeft : Qt.AlignHCenter
198
199 Layout.fillWidth: true
200 }
201 }
202 }
203
204 readonly property bool _mobileLayout: {
205 if (root.width < Kirigami.Units.gridUnit * 20) {
206 return true;
207 }
208 if (!footer) {
209 return false;
210 }
211 let totalImplicitWidth = checkbox.implicitWidth + gridLayoutFooter.columnSpacing;
212 for (let i = 0; i < repeater.count; i++) {
213 totalImplicitWidth += repeater.itemAt(i).implicitWidth + gridLayoutFooter.columnSpacing
214 }
215
216 return totalImplicitWidth > footer.width;
217 }
218
219 footer: GridLayout {
220 id: gridLayoutFooter
221
222 columns: root._mobileLayout ? 1 : 1 + repeater.count + 1
223
224 rowSpacing: Kirigami.Units.mediumSpacing
225 columnSpacing: Kirigami.Units.mediumSpacing
226
227 FormCard.FormCheckDelegate {
228 id: checkbox
229
230 visible: dontShowAgainName.length > 0
231 text: i18ndc("kirigami-addons6", "@label:checkbox", "Do not show again")
232 background: null
233
234 Layout.fillWidth: true
235 }
236
237 Repeater {
238 id: repeater
239 model: dialogButtonBox.contentModel
240 }
241
242 T.DialogButtonBox {
243 id: dialogButtonBox
244
245 standardButtons: root.standardButtons
246
247 onAccepted: root.accepted();
248 onDiscarded: root.discarded();
249 onApplied: root.applied();
250 onHelpRequested: root.helpRequested();
251 onRejected: root.rejected();
252
253 implicitWidth: 0
254 implicitHeight: 0
255
256 contentItem: Item {}
257 delegate: QQC2.Button {
258 Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.DialogButton
259
260 Layout.fillWidth: root._mobileLayout
261 Layout.leftMargin: root._mobileLayout ? Kirigami.Units.largeSpacing : 0
262 Layout.rightMargin: root._mobileLayout ? Kirigami.Units.largeSpacing : 0
263 Layout.bottomMargin: root._mobileLayout ? 0 : 2
264 }
265 }
266 }
267
268 enter: Transition {
269 NumberAnimation {
270 property: "opacity"
271 from: 0
272 to: 1
273 easing.type: Easing.InOutQuad
274 duration: Kirigami.Units.longDuration
275 }
276 }
277
278 exit: Transition {
279 NumberAnimation {
280 property: "opacity"
281 from: 1
282 to: 0
283 easing.type: Easing.InOutQuad
284 duration: Kirigami.Units.longDuration
285 }
286 }
287
288 modal: true
289 focus: true
290
291 background: Components.DialogRoundedBackground {}
292
293 // black background, fades in and out
294 QQC2.Overlay.modal: Rectangle {
295 color: Qt.rgba(0, 0, 0, 0.3)
296
297 // the opacity of the item is changed internally by QQuickPopup on open/close
298 Behavior on opacity {
299 OpacityAnimator {
300 duration: Kirigami.Units.longDuration
301 easing.type: Easing.InOutQuad
302 }
303 }
304 }
305}
A single card that follows a form style.
Definition FormCard.qml:35
A dialog to show a message.
QString i18ndc(const char *domain, const char *context, const char *text, const TYPE &arg...)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:49:11 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.