1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2005-2006 Olivier Goffart <ogoffart at kde.org>
4 SPDX-FileCopyrightText: 2013-2015 Martin Klapetek <mklapetek@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#ifndef KNOTIFICATION_H
10#define KNOTIFICATION_H
11
12#include <knotifications_export.h>
13
14#include <QList>
15#include <QObject>
16#include <QPair>
17#include <QPixmap>
18#include <QUrl>
19#include <QVariant>
20#include <QWindow>
21
22#include <memory>
23
24class KNotificationReplyAction;
25class KNotificationAction;
26
27class KNotificationActionPrivate;
28
29/**
30 * @class KNotificationAction knotification.h KNotificationAction
31 *
32 * This class represents a notification. This can be a button on the notification
33 * popup, or triggered by clicking the notification popup itself.
34 *
35 * @since 6.0
36 */
37class KNOTIFICATIONS_EXPORT KNotificationAction : public QObject
38{
39 Q_OBJECT
40 /**
41 * @copydoc label
42 */
43 Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged)
44
45public:
46 explicit KNotificationAction(QObject *parent = nullptr);
47
48 /**
49 * Creates an action with given label
50 * @param label The label for the action
51 */
52 explicit KNotificationAction(const QString &label);
53
54 ~KNotificationAction() override;
55
56 /**
57 * The user-facing label for the action
58 */
59 QString label() const;
60
61 /**
62 * Set the user-facing label for the action
63 */
64 void setLabel(const QString &label);
65
66Q_SIGNALS:
67 /**
68 * Emitted when the user activates the action
69 */
70 void activated();
71
72 /**
73 * Emitted when @p label changed.
74 */
75 void labelChanged(const QString &label);
76
77private:
78 friend class KNotification;
79 friend class NotifyByPortalPrivate;
80 friend class NotifyByPopup;
81 friend class NotifyBySnore;
82 friend class NotifyByAndroid;
83
84 void setId(const QString &id);
85 QString id() const;
86
87 std::unique_ptr<KNotificationActionPrivate> const d;
88};
89
90/**
91 * @class KNotification knotification.h KNotification
92 *
93 * KNotification is the main class for creating notifications.
94 */
95class KNOTIFICATIONS_EXPORT KNotification : public QObject
96{
97 Q_OBJECT
98 /**
99 * @copydoc setEventId
100 * @since 5.88
101 */
102 Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged)
103 /**
104 * @copydoc setTitle
105 * @since 5.88
106 */
107 Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
108 /**
109 * @copydoc setText
110 * @since 5.88
111 */
112 Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
113 /**
114 * @copydoc setIconName
115 * @since 5.88
116 */
117 Q_PROPERTY(QString iconName READ iconName WRITE setIconName NOTIFY iconNameChanged)
118 /**
119 * @copydoc setFlags
120 * @since 5.88
121 */
122 Q_PROPERTY(NotificationFlags flags READ flags WRITE setFlags NOTIFY flagsChanged)
123 /**
124 * @copydoc setComponentName
125 * @since 5.88
126 */
127 Q_PROPERTY(QString componentName READ componentName WRITE setComponentName NOTIFY componentNameChanged)
128 /**
129 * @copydoc setUrls
130 * @since 5.88
131 */
132 Q_PROPERTY(QList<QUrl> urls READ urls WRITE setUrls NOTIFY urlsChanged)
133 /**
134 * @copydoc setUrgency
135 * @since 5.88
136 */
137 Q_PROPERTY(Urgency urgency READ urgency WRITE setUrgency NOTIFY urgencyChanged)
138 /**
139 * @copydoc setAutoDelete
140 * @since 5.88
141 */
142 Q_PROPERTY(bool autoDelete READ isAutoDelete WRITE setAutoDelete NOTIFY autoDeleteChanged)
143 /**
144 * @since 5.90
145 */
146 Q_PROPERTY(QString xdgActivationToken READ xdgActivationToken NOTIFY xdgActivationTokenChanged)
147 /**
148 * @copydoc setHint
149 * @since 5.101
150 */
151 Q_PROPERTY(QVariantMap hints READ hints WRITE setHints NOTIFY hintsChanged)
152
153public:
154 /**
155 * @see NotificationFlags
156 */
157 enum NotificationFlag {
158 /**
159 * The notification will be automatically closed after a timeout. (this is the default)
160 */
161 CloseOnTimeout = 0x00,
162
163 /**
164 * The notification will NOT be automatically closed after a timeout.
165 * You will have to track the notification, and close it with the
166 * close function manually when the event is done, otherwise there will be a memory leak
167 */
168 Persistent = 0x02,
169
170 /**
171 * The audio plugin will loop the sound until the notification is closed
172 */
173 LoopSound = 0x08,
174
175 /**
176 * Sends a hint to Plasma to skip grouping for this notification
177 *
178 * @since 5.18
179 */
180 SkipGrouping = 0x10,
181
182 /**
183 * The notification will be automatically closed if the window() becomes
184 * activated.
185 *
186 * You need to set a window using setWindow().
187 *
188 * @since 6.0
189 */
190 CloseWhenWindowActivated = 0x20,
191
192 /**
193 * @internal
194 * The event is a standard kde event, and not an event of the application
195 */
196 DefaultEvent = 0xF000,
197
198 };
199
200 /**
201 * Stores a combination of #NotificationFlag values.
202 */
203 Q_DECLARE_FLAGS(NotificationFlags, NotificationFlag)
204 Q_FLAG(NotificationFlags)
205
206 /**
207 * default events you can use in the event function
208 */
209 enum StandardEvent {
210 Notification,
211 Warning,
212 Error,
213 Catastrophe,
214 };
215
216 /**
217 * The urgency of a notification.
218 *
219 * @since 5.58
220 * @sa setUrgency
221 */
222 enum Urgency {
223 DefaultUrgency = -1,
224 LowUrgency = 10,
225 NormalUrgency = 50,
226 HighUrgency = 70,
227 CriticalUrgency = 90,
228 };
229 Q_ENUM(Urgency)
230
231 /**
232 * Create a new notification.
233 *
234 * You have to use sendEvent to show the notification.
235 *
236 * The pointer is automatically deleted when the event is closed.
237 *
238 * @since 4.4
239 *
240 * @param eventId is the name of the event
241 * @param flags is a bitmask of NotificationFlag
242 * @param parent parent object
243 */
244 explicit KNotification(const QString &eventId, NotificationFlags flags = CloseOnTimeout, QObject *parent = nullptr);
245
246 ~KNotification() override;
247
248 /**
249 * @return the name of the event
250 */
251 QString eventId() const;
252 /**
253 * Set the event id, if not already passed to the constructor.
254 * @since 5.88
255 */
256 void setEventId(const QString &eventId);
257
258 /**
259 * @return the notification title
260 * @see setTitle
261 * @since 4.3
262 */
263 QString title() const;
264
265 /**
266 * Set the title of the notification popup.
267 * If no title is set, the application name will be used.
268 *
269 * @param title The title of the notification
270 * @since 4.3
271 */
272 void setTitle(const QString &title);
273
274 /**
275 * @return the notification text
276 * @see setText
277 */
278 QString text() const;
279
280 /**
281 * Set the notification text that will appear in the popup.
282 *
283 * In Plasma workspace, the text is shown in a QML label which uses Text.StyledText,
284 * ie. it supports a small subset of HTML entities (mostly just formatting tags)
285 *
286 * If the notifications server does not advertise "body-markup" capability,
287 * all HTML tags are stripped before sending it to the server
288 *
289 * @param text The text to display in the notification popup
290 */
291 void setText(const QString &text);
292
293 /**
294 * \return the icon shown in the popup
295 * \see setIconName
296 * \since 5.4
297 */
298 QString iconName() const;
299
300 /**
301 * Set the icon that will be shown in the popup.
302 *
303 * @param icon the icon
304 * @since 5.4
305 */
306 void setIconName(const QString &icon);
307
308 /**
309 * \return the pixmap shown in the popup
310 * \see setPixmap
311 */
312 QPixmap pixmap() const;
313 /**
314 * Set the pixmap that will be shown in the popup. If you want to use an icon from the icon theme use setIconName instead.
315 *
316 * @param pix the pixmap
317 */
318 void setPixmap(const QPixmap &pix);
319
320 /**
321 * @return the default action, or nullptr if none is set
322 * @since 6.0
323 */
324 KNotificationAction *defaultAction() const;
325
326 /**
327 * Add a default action that will be triggered when the notification is
328 * activated (typically, by clicking on the notification popup). The default
329 * action typically raises a window belonging to the application that sent it.
330 *
331 * The string will be used as a label for the action, so ideally it should
332 * be wrapped in i18n() or tr() calls.
333 *
334 * The visual representation of actions depends on the notification server.
335 * In Plasma and Gnome desktops, the actions are performed by clicking on
336 * the notification popup, and the label is not presented to the user.
337 *
338 * Calling this overrides the current default action
339 *
340 * @since 6.0
341 */
342 [[nodiscard]] KNotificationAction *addDefaultAction(const QString &label);
343
344 /**
345 * Add an action to the notification.
346 *
347 * The visual representation of actions depends
348 * on the notification server.
349 *
350 * @param label the user-visible label of the action
351 *
352 * @see KNotificationAction
353 *
354 * @since 6.0
355 */
356 [[nodiscard]] KNotificationAction *addAction(const QString &label);
357
358 /**
359 * Removes all actions previously added by addAction()
360 * from the notification.
361 *
362 * @see addAction
363 *
364 * @since 6.0
365 */
366 void clearActions();
367
368 /**
369 * @return the inline reply action.
370 * @since 5.81
371 */
372 KNotificationReplyAction *replyAction() const;
373
374 /**
375 * @brief Add an inline reply action to the notification.
376 *
377 * On supported platforms this lets the user type a reply to a notification,
378 * such as replying to a chat message, from the notification popup, for example:
379 *
380 * @code{.cpp}
381 * KNotification *notification = new KNotification(QStringLiteral("notification"));
382 * ...
383 * auto replyAction = std::make_unique<KNotificationReplyAction>(i18nc("@action:button", "Reply"));
384 * replyAction->setPlaceholderText(i18nc("@info:placeholder", "Reply to Dave..."));
385 * QObject::connect(replyAction.get(), &KNotificationReplyAction::replied, [](const QString &text) {
386 * qDebug() << "you replied with" << text;
387 * });
388 * notification->setReplyAction(std::move(replyAction));
389 * @endcode
390 *
391 * @param replyAction the reply action to set
392 * @since 5.81
393 */
394 void setReplyAction(std::unique_ptr<KNotificationReplyAction> replyAction);
395
396 /**
397 * @return the notification flags.
398 */
399 NotificationFlags flags() const;
400
401 /**
402 * Set the notification flags.
403 * These must be set before calling sendEvent()
404 */
405 void setFlags(const NotificationFlags &flags);
406
407 /**
408 * Returns the component name used to determine the location of the configuration file.
409 * @since 5.88
410 */
411 QString componentName() const;
412 /**
413 * The componentData is used to determine the location of the config file.
414 *
415 * If no componentName is set, the app name is used by default
416 *
417 * @param componentName the new component name
418 */
419 void setComponentName(const QString &componentName);
420
421 /**
422 * URLs associated with this notification
423 * @since 5.29
424 */
425 QList<QUrl> urls() const;
426
427 /**
428 * Sets URLs associated with this notification
429 *
430 * For example, a screenshot application might want to provide the
431 * URL to the file that was just taken so the notification service
432 * can show a preview.
433 *
434 * @note This feature might not be supported by the user's notification service
435 *
436 * @param urls A list of URLs
437 * @since 5.29
438 */
439 void setUrls(const QList<QUrl> &urls);
440
441 /**
442 * The urgency of the notification.
443 * @since 5.58
444 */
445 Urgency urgency() const;
446
447 /**
448 * Sets the urgency of the notification.
449 *
450 * This defines the importance of the notification. For example,
451 * a track change in a media player would be a low urgency.
452 * "You have new mail" would be normal urgency. "Your battery level
453 * is low" would be a critical urgency.
454 *
455 * Use critical notifications with care as they might be shown even
456 * when giving a presentation or when notifications are turned off.
457 *
458 * @param urgency The urgency.
459 * @since 5.58
460 */
461 void setUrgency(Urgency urgency);
462
463 /**
464 * Sets the window associated with this notification.
465 * This is relevant when using the CloseWhenWindowActivated flag.
466 *
467 * @since 6.0
468 */
469 void setWindow(QWindow *window);
470
471 /**
472 * The window associated with this notification. nullptr by default.
473 * @return the window set by setWindow()
474 *
475 * @since 6.0
476 */
477 QWindow *window() const;
478
479 /**
480 * @internal
481 * appname used for the D-Bus object
482 */
483 QString appName() const;
484
485 /**
486 * Returns whether this notification object will be automatically deleted after closing.
487 * @since 5.88
488 */
489 bool isAutoDelete() const;
490 /**
491 * Sets whether this notification object will be automatically deleted after closing.
492 * This is on by default for C++, and off by default for QML.
493 * @since 5.88
494 */
495 void setAutoDelete(bool autoDelete);
496
497 /**
498 * Returns the activation token to use to activate a window.
499 * @since 5.90
500 */
501 QString xdgActivationToken() const;
502
503Q_SIGNALS:
504 /**
505 * Emitted when the notification is closed.
506 *
507 * Can be closed either by the user clicking the close button,
508 * the timeout running out or when an action was triggered.
509 */
510 void closed();
511
512 /**
513 * The notification has been ignored
514 */
515 void ignored();
516
517 /**
518 * Emitted when @c eventId changed.
519 * @since 5.88
520 */
521 void eventIdChanged();
522 /**
523 * Emitted when @c title changed.
524 * @since 5.88
525 */
526 void titleChanged();
527 /**
528 * Emitted when @c text changed.
529 * @since 5.88
530 */
531 void textChanged();
532 /**
533 * Emitted when @c iconName changed.
534 * @since 5.88
535 */
536 void iconNameChanged();
537 /**
538 * Emitted when @c defaultAction changed.
539 * @since 5.88
540 */
541 void defaultActionChanged();
542 /**
543 * Emitted when @c actions changed.
544 * @since 5.88
545 */
546 void actionsChanged();
547 /**
548 * Emitted when @p flags changed.
549 * @since 5.88
550 */
551 void flagsChanged();
552 /**
553 * Emitted when @p componentName changed.
554 * @since 5.88
555 */
556 void componentNameChanged();
557 /**
558 * Emitted when @p urls changed.
559 * @since 5.88
560 */
561 void urlsChanged();
562 /**
563 * Emitted when @p urgency changed.
564 * @since 5.88
565 */
566 void urgencyChanged();
567 /**
568 * Emitted when @p autoDelete changed.
569 * @since 5.88
570 */
571 void autoDeleteChanged();
572 /**
573 * Emitted when @p xdgActivationToken changes.
574 * @since 5.90
575 */
576 void xdgActivationTokenChanged();
577 /**
578 * Emitted when @p hints changes.
579 * @since 5.101
580 */
581 void hintsChanged();
582
583public Q_SLOTS:
584 /**
585 * Close the notification without activating it.
586 *
587 * This will delete the notification.
588 */
589 void close();
590
591 /**
592 * Send the notification to the server.
593 *
594 * This will cause all the configured plugins to execute their actions on this notification
595 * (eg. a sound will play, a popup will show, a command will be executed etc).
596 */
597 void sendEvent();
598
599 /**
600 * @since 5.57
601 * Adds a custom hint to the notification. Those are key-value pairs that can be interpreted by the respective notification backend to trigger additional,
602 * non-standard features.
603 * @param hint the hint's key
604 * @param value the hint's value
605 */
606 Q_INVOKABLE void setHint(const QString &hint, const QVariant &value);
607
608 /**
609 * @since 5.57
610 * Returns the custom hints set by setHint()
611 */
612 QVariantMap hints() const;
613
614 /**
615 * @since 5.101
616 * Set custom hints on the notification.
617 * @sa setHint
618 */
619 void setHints(const QVariantMap &hints);
620
621private:
622 friend class KNotificationManager;
623 friend class NotificationWrapper;
624 friend class NotifyByPopup;
625 friend class NotifyByPortal;
626 friend class NotifyByPortalPrivate;
627 friend class NotifyByExecute;
628 friend class NotifyBySnore;
629 friend class NotifyByAndroid;
630 friend class NotifyByMacOSNotificationCenter;
631 struct Private;
632
633 KNOTIFICATIONS_NO_EXPORT void slotWindowActiveChanged();
634
635 /**
636 * @brief Activate the action specified action
637 * If the action is zero, then the default action is activated
638 */
639 KNOTIFICATIONS_NO_EXPORT void activate(const QString &action);
640
641 /**
642 * @internal
643 * the id given by the notification manager
644 */
645 KNOTIFICATIONS_NO_EXPORT int id();
646
647 /**
648 * @internal
649 * update the texts, the icon, and the actions of one existing notification
650 */
651 KNOTIFICATIONS_NO_EXPORT void update();
652
653 /**
654 * The notification will automatically be closed if all presentations are finished.
655 * if you want to show your own presentation in your application, you should use this
656 * function, so it will not be automatically closed when there is nothing to show.
657 *
658 * Don't forgot to deref, or the notification may be never closed if there is no timeout.
659 *
660 * @see deref
661 */
662 KNOTIFICATIONS_NO_EXPORT void ref();
663
664 /**
665 * Remove a reference made with ref(). If the ref counter hits zero,
666 * the notification will be closed and deleted.
667 *
668 * @see ref
669 */
670 KNOTIFICATIONS_NO_EXPORT void deref();
671
672 // Like setActions, but doesn't take ownership
673 void setActionsQml(QList<KNotificationAction *> actions);
674 void setDefaultActionQml(KNotificationAction *action);
675 QList<KNotificationAction *> actions() const;
676
677 static QString standardEventToEventId(StandardEvent event);
678 static QString standardEventToIconName(StandardEvent event);
679
680 std::unique_ptr<Private> const d;
681
682public:
683 /**
684 * @brief emit an event
685 *
686 * This method creates the KNotification, setting every parameter, and fire the event.
687 * You don't need to call sendEvent
688 *
689 * A popup may be displayed or a sound may be played, depending the config.
690 *
691 * @return a KNotification . You may use that pointer to connect some signals or slot.
692 * the pointer is automatically deleted when the event is closed.
693 *
694 * @param eventId is the name of the event
695 * @param title is title of the notification to show in the popup.
696 * @param text is the text of the notification to show in the popup.
697 * @param pixmap is a picture which may be shown in the popup.
698 * @param flags is a bitmask of NotificationFlag
699 * @param componentName used to determine the location of the config file. by default, appname is used
700 * @since 4.4
701 */
702 static KNotification *event(const QString &eventId,
703 const QString &title,
704 const QString &text,
705 const QPixmap &pixmap = QPixmap(),
706 const NotificationFlags &flags = CloseOnTimeout,
707 const QString &componentName = QString());
708
709 /**
710 * @brief emit a standard event
711 *
712 * @overload
713 *
714 * This will emit a standard event
715 *
716 * @param eventId is the name of the event
717 * @param text is the text of the notification to show in the popup.
718 * @param pixmap is a picture which may be shown in the popup.
719 * @param flags is a bitmask of NotificationFlag
720 * @param componentName used to determine the location of the config file. by default, plasma_workspace is used
721 */
722 static KNotification *event(const QString &eventId,
723 const QString &text = QString(),
724 const QPixmap &pixmap = QPixmap(),
725 const NotificationFlags &flags = CloseOnTimeout,
726 const QString &componentName = QString());
727
728 /**
729 * @brief emit a standard event
730 *
731 * @overload
732 *
733 * This will emit a standard event
734 *
735 * @param eventId is the name of the event
736 * @param text is the text of the notification to show in the popup
737 * @param pixmap is a picture which may be shown in the popup
738 * @param flags is a bitmask of NotificationFlag
739 */
740 static KNotification *
741 event(StandardEvent eventId, const QString &text = QString(), const QPixmap &pixmap = QPixmap(), const NotificationFlags &flags = CloseOnTimeout);
742
743 /**
744 * @brief emit a standard event
745 *
746 * @overload
747 *
748 * This will emit a standard event
749 *
750 * @param eventId is the name of the event
751 * @param title is title of the notification to show in the popup.
752 * @param text is the text of the notification to show in the popup
753 * @param pixmap is a picture which may be shown in the popup
754 * @param flags is a bitmask of NotificationFlag
755 * @since 4.4
756 */
757 static KNotification *
758 event(StandardEvent eventId, const QString &title, const QString &text, const QPixmap &pixmap, const NotificationFlags &flags = CloseOnTimeout);
759
760 /**
761 * @brief emit a standard event with the possibility of setting an icon by icon name
762 *
763 * @overload
764 *
765 * This will emit a standard event
766 *
767 * @param eventId is the name of the event
768 * @param title is title of the notification to show in the popup.
769 * @param text is the text of the notification to show in the popup
770 * @param iconName a Freedesktop compatible icon name to be shown in the popup
771 * @param flags is a bitmask of NotificationFlag
772 * @param componentName used to determine the location of the config file. by default, plasma_workspace is used
773 * @since 5.4
774 */
775 static KNotification *event(const QString &eventId,
776 const QString &title,
777 const QString &text,
778 const QString &iconName,
779 const NotificationFlags &flags = CloseOnTimeout,
780 const QString &componentName = QString());
781
782 /**
783 * @brief emit a standard event with the possibility of setting an icon by icon name
784 *
785 * @overload
786 *
787 * This will emit a standard event with a custom icon
788 *
789 * @param eventId the type of the standard (not app-defined) event
790 * @param title is title of the notification to show in the popup.
791 * @param text is the text of the notification to show in the popup
792 * @param iconName a Freedesktop compatible icon name to be shown in the popup
793 * @param flags is a bitmask of NotificationFlag
794 * @since 5.9
795 */
796 static KNotification *
797 event(StandardEvent eventId, const QString &title, const QString &text, const QString &iconName, const NotificationFlags &flags = CloseOnTimeout);
798
799 /**
800 * @brief emit a standard event
801 *
802 * @overload
803 *
804 * This will emit a standard event with its standard icon
805 *
806 * @param eventId the type of the standard (not app-defined) event
807 * @param title is title of the notification to show in the popup.
808 * @param text is the text of the notification to show in the popup
809 * @param flags is a bitmask of NotificationFlag
810 * @since 5.9
811 */
812 static KNotification *event(StandardEvent eventId, const QString &title, const QString &text, const NotificationFlags &flags = CloseOnTimeout);
813
814 /**
815 * This is a simple substitution for QApplication::beep()
816 *
817 * @param reason a short text explaining what has happened (may be empty)
818 */
819 static void beep(const QString &reason = QString());
820
821 // prevent warning
822 using QObject::event;
823};
824
825Q_DECLARE_OPERATORS_FOR_FLAGS(KNotification::NotificationFlags)
826
827#endif
828

source code of knotifications/src/knotification.h