1/* This file is part of the KDE libraries
2 Copyright (C) 2005-2006 Olivier Goffart <ogoffart at kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
17*/
18
19
20#ifndef KNOTIFICATION_H
21#define KNOTIFICATION_H
22
23#include <kdeui_export.h>
24#include <kcomponentdata.h>
25
26#include <QtGui/QPixmap>
27#include <QtCore/QObject>
28#include <QtCore/QPair>
29
30class QWidget;
31class QDBusError;
32
33/**
34 * KNotification is used to notify the user of an event.
35 *
36 * \section introduction
37 *
38 * There are two main kinds of notifications:
39 *
40 * @li Feedback events:
41 * For notifying the user that he/she just performed an operation, like maximizing a
42 * window. This allows us to play sounds when a dialog appears.
43 * This is an instant notification. It ends automatically after a small timeout.
44 *
45 * @li persistant notifications:
46 * Notify when the user received a new message, or when something else important happened
47 * the user has to know about. This notification has a start and a end. It begins when
48 * the event actually occurs, and finishes when the message is acknowledged or read.
49 *
50 * Example of a persistent notification in an instant messaging application:
51 * The application emits the notification when the message is actually received, and closes it only
52 * when the user has read the message (when the message window has received the focus) using the close() slot
53 * Persistent notifications must have the Persistent flag.
54 *
55 * By default a notification will use the application name as title, but you
56 * can also provide a brief text in the title and a more precise description in
57 * the body text. This is especially useful for notifications coming from
58 * applications which should be considered "part of the system", like a battery
59 * monitor or a network connection manager.
60 * For example a battery indicator could use "Low Battery" as a title and "Only
61 * 12 minutes left." as a body text.
62 *
63 * In order to perform a notification, you need to create a description file, which contains
64 * default parameters of the notification, and use KNotification::event at the place in the
65 * application code where the notification occurs.
66 * The returned KNotification pointer may be used to connect signals or slots
67 *
68 * \section file The global config file
69 * Your application should install a file called:
70 * <em>$KDEDIR/share/apps/appname/appname.notifyrc</em>
71 *
72 * You can do this with the following CMake command:
73 * install( FILES appname.notifyrc DESTINATION ${DATA_INSTALL_DIR}/appname))
74 *
75 * This file contains mainly 3 parts
76 * <ol><li>\ref global "Global information"</li>
77 * <li>\ref context "Context information"</li>
78 * <li>\ref events "Definition of individual events"</li></ol>
79 *
80 * \subsection global Global information
81 * The global part looks like that
82 * <pre>
83 [Global]
84 IconName=Filename
85 Comment=Friendly Name of app
86 Name=Name of app
87 * </pre>
88 * The icon filename is just the name, without extension, it's found with the KIconLoader.
89 * The Comment field will be used in KControl to describe the application.
90 * The Name field is optional and may be used as the application name for popup,
91 * if Name is not present, Comment is used instead
92 *
93 * \subsection context Context information
94 *
95 * This part consists of hints for the configuration widget
96 * <pre>
97 [Context/group]
98 Name=Group name
99 Comment=The name of the group for contacts
100
101 [Context/folder]
102 Name=Group name
103 * </pre>
104 * The second part of the groupname is the context identifier.
105 * It should not contain special characters.
106 * The Name field is the one the user will see (and which is translated)
107 *
108 * \subsection events Definition of Events
109 *
110 * The definition of the events forms the most important part of the config file
111 * <pre>
112 [Event/newmail]
113 Name=New email
114 Comment=You have got a new email
115 Contexts=folder,group
116 Action=Sound|Popup
117
118 [Event/contactOnline]
119 Name=Contact goes online
120 Comment=One of your contact has been connected
121 Contexts=group
122 Sound=filetoplay.ogg
123 Action=None
124 * </pre>
125 * These are the default settings for each notifiable event.
126 * Action is the string representing the action. Actions can be added to
127 * the KNotify daemon as plugins, by deriving from KNotifyPlugin.
128 * At the time of writing, the following actions are available: Taskbar,
129 * Sound, Popup, Logfile, KTTS, Execute.
130 * Actions can be combined by seperating them with '|'.
131 *
132 * Contexts is a comma separated list of possible context for this event.
133 *
134 * \section userfile The user's config file
135 *
136 * This is an implementation detail, and is described here for your information.
137 *
138 * In the config file, there are two parts: the event configuration, and the context information
139 * \subsection context Context information
140 * These are hints for the configuration dialog. They contain both the internal id of the context, and the user visible string.
141 * <pre>
142 [Context/group]
143 Values=1:Friends,2:Work,3:Family
144 * </pre>
145 * \subsection event Events configuration
146 * This contains the configuration of events for the user.
147 * It contains the same fields as the description file.
148 * The key of groups is in the form
149 * <em>Event/&lt;EventName&gt;/&lt;ContextName&gt;/&lt;ContextValue&gt;</em>
150 * <pre>
151 [Event/contactOnline]
152 Action=Sound
153 Sound=/usr/share/sounds/super.ogg
154
155 [Event/contactOnline/group/1]
156 Action=Popup|Sound
157 * </pre>
158 *
159 * \section example Example of code
160 *
161 * This portion of code will fire the event for the "contactOnline" event
162 *
163 * @code
164 KNotification *notification= new KNotification ( "contactOnline", widget );
165 notification->setText( i18n("The contact <i>%1</i> has gone online", contact->name() );
166 notification->setPixmap( contact->pixmap() );
167 notification->setActions( QStringList( i18n( "Open chat" ) ) );
168
169 foreach( const QString &group , contact->groups() ) {
170 notification->addContext( "group" , group ) ;
171 }
172
173 connect(notification, SIGNAL(activated(unsigned int )), contact , SLOT(slotOpenChat()) );
174
175 notification->sendEvent();
176 * @endcode
177 *
178 * @author Olivier Goffart \<ogoffart at kde.org\>
179 */
180class KDEUI_EXPORT KNotification : public QObject
181{
182 Q_OBJECT
183
184public:
185 /**
186 * Sometimes the user may want different notifications for the same event,
187 * depending the source of the event. Example, you want to be notified for mails
188 * that arrive in your folder "personal inbox" but not for those in "spam" folder
189 *
190 * A notification context is a pair of two strings.
191 * The first string is a key from what the context is. example "group" or
192 * "filter" (not translated).
193 * The second is the id of the context. In our example, the group id or the
194 * filter id in the applications.
195 * These strings are the ones present in the config file, and are in theory not
196 * shown in the user interface.
197 *
198 * The order of contexts in the list is is important, the most important context
199 * should be placed first. They are processed in that order when the notification occurs.
200 *
201 * @see event
202 */
203 typedef QPair<QString,QString> Context;
204 typedef QList< Context > ContextList;
205
206 enum NotificationFlag
207 {
208 /**
209 * When the notification is activated, raise the notification's widget.
210 *
211 * This will change the desktop, raise the window, and switch to the tab.
212 * @todo doesn't work yet
213 */
214 RaiseWidgetOnActivation=0x01,
215
216 /**
217 * The notification will be automatically closed after a timeout. (this is the default)
218 */
219 CloseOnTimeout=0x00,
220
221 /**
222 * The notification will NOT be automatically closed after a timeout.
223 * You will have to track the notification, and close it with the
224 * close function manually when the event is done, otherwise there will be a memory leak
225 */
226 Persistent=0x02,
227
228 /**
229 * The notification will be automatically closed if the widget() becomes
230 * activated.
231 *
232 * If the widget is already activated when the notification occurs, the
233 * notification will be closed after a small timeout.
234 *
235 * This only works if the widget is the toplevel widget
236 * @todo make it work with tabulated widget
237 */
238 CloseWhenWidgetActivated=0x04,
239 /**
240 * DEPRECATED - Misspelling of 'Persistent'. Do not use in new code.
241 */
242 Persistant = Persistent,
243 /**
244 * @internal
245 * The event is a standard kde event, and not an event of the application
246 */
247 DefaultEvent=0xF000
248
249 };
250
251 Q_DECLARE_FLAGS(NotificationFlags , NotificationFlag)
252
253 /**
254 * default events you can use in the event function
255 */
256 enum StandardEvent { Notification , Warning , Error , Catastrophe };
257
258 /**
259 * Create a new notification.
260 *
261 * You have to use sendEvent to show the notification.
262 *
263 * The pointer is automatically deleted when the event is closed.
264 *
265 * Make sure you use one of the NotificationFlags CloseOnTimeOut or
266 * CloseWhenWidgetActivated, if not,
267 * you have to close the notification yourself.
268 *
269 * @param eventId is the name of the event
270 * @param widget is a widget where the notification reports to
271 * @param flags is a bitmask of NotificationFlag
272 */
273 explicit KNotification(const QString & eventId , QWidget *widget=0L, const NotificationFlags &flags=CloseOnTimeout);
274
275 /**
276 * Create a new notification.
277 *
278 * You have to use sendEvent to show the notification.
279 *
280 * The pointer is automatically deleted when the event is closed.
281 *
282 * Make sure you use one of the NotificationFlags CloseOnTimeOut or
283 * CloseWhenWidgetActivated, if not,
284 * you have to close the notification yourself.
285 *
286 * @since 4.4
287 *
288 * @param eventId is the name of the event
289 * @param flags is a bitmask of NotificationFlag
290 * @param parent parent object
291 */
292 // KDE5: Clean up this mess
293 // Only this constructor should stay with saner argument order and
294 // defaults. Because of binary and source compatibility issues it has to
295 // stay this way for now. The second argument CANNOT have a default
296 // argument. if someone needs a widget associated with the notification he
297 // should use setWidget after creating the object (or some xyz_cast magic)
298 explicit KNotification(const QString & eventId , const NotificationFlags &flags, QObject *parent = NULL );
299
300 ~KNotification();
301
302 /**
303 * @brief the widget associated to the notification
304 *
305 * If the widget is destroyed, the notification will be automatically cancelled.
306 * If the widget is activated, the notification will be automatically closed if the NotificationFlags specify that
307 *
308 * When the notification is activated, the widget might be raised.
309 * Depending on the configuration, the taskbar entry of the window containing the widget may blink.
310 */
311 QWidget *widget() const;
312
313 /**
314 * Set the widget associated to the notification.
315 * The notification is reparented to the new widget.
316 * \see widget()
317 * @param widget the new widget
318 */
319 void setWidget(QWidget *widget);
320
321
322 /**
323 * @return the name of the event
324 */
325 QString eventId() const;
326
327 /**
328 * @return the notification title
329 * @see setTitle
330 * @since 4.3
331 */
332 QString title() const;
333
334 /**
335 * Set the title of the notification popup.
336 * If no title is set, the application name will be used.
337 *
338 * @param title the title
339 * @since 4.3
340 */
341 void setTitle(const QString &title);
342
343 /**
344 * @return the notification text
345 * @see setText
346 */
347 QString text() const ;
348
349 /**
350 * Set the notification text that will appear in the popup.
351 *
352 * The text is shown in a QLabel, you should make sure to escape any html that is needed.
353 * You can use some of the qt basic html tags.
354 *
355 * @param text the text
356 */
357 void setText(const QString &text);
358
359 /**
360 * \return the pixmap shown in the popup
361 * \see setPixmap
362 */
363 QPixmap pixmap() const;
364 /**
365 * set the pixmap that will be shown in the popup.
366 * @param pix the pixmap
367 */
368 void setPixmap(const QPixmap &pix);
369
370 /**
371 * @return the list of actions
372 */
373 QStringList actions() const;
374
375 /**
376 * Set the list of actions link shown in the popup.
377 * @param actions the list of actions
378 */
379 void setActions(const QStringList& actions);
380
381 /**
382 * @return the list of contexts, see KNotification::Context
383 */
384 ContextList contexts() const;
385 /**
386 * set the list of contexts, see KNotification::Context
387 *
388 * The list of contexts must be set before calling sendEvent;
389 */
390 void setContexts( const ContextList &contexts);
391 /**
392 * append a context at the list of contexts, see KNotificaiton::Context
393 * @param context the context which is added
394 */
395 void addContext( const Context & context);
396 /**
397 * @overload
398 * @param context_key is the key of the context
399 * @param context_value is the value of the context
400 */
401 void addContext( const QString & context_key, const QString & context_value );
402
403 /**
404 * @return the notification flags.
405 */
406 NotificationFlags flags() const;
407
408 /**
409 * Set the notification flags.
410 * should be called before sendEvent().
411 */
412 void setFlags(const NotificationFlags &flags);
413
414 /**
415 * The componentData is used to determine the location of the config file. By default, kapp is used
416 * @param componentData the new componentData
417 */
418 void setComponentData(const KComponentData &componentData);
419
420 Q_SIGNALS:
421 /**
422 * Emit only when the default activation has occurred
423 */
424 void activated();
425 /**
426 * Emit when an action has been activated.
427 * @param action will be 0 is the default aciton was activated, or any action id
428 */
429 void activated(unsigned int action);
430
431 /**
432 * Convenience signal that is emitted when the first action is activated.
433 */
434 void action1Activated();
435
436 /**
437 * \overload
438 */
439 void action2Activated();
440
441 /**
442 * \overload
443 */
444 void action3Activated();
445
446 /**
447 * Emitted when the notification is closed. Both when it is activated or if it is just ignored.
448 */
449 void closed();
450
451 /**
452 * The notification has been ignored
453 */
454 void ignored();
455
456public Q_SLOTS:
457 /**
458 * @brief Activate the action specified action
459 * If the action is zero, then the default action is activated
460 */
461 void activate(unsigned int action=0);
462
463 /**
464 * Close the notification without activating it.
465 *
466 * This will delete the notification.
467 */
468 void close();
469
470 /**
471 * @brief Raise the widget.
472 * This will change the desktop, activate the window, and the tab if needed.
473 */
474 void raiseWidget();
475
476 /**
477 * The notification will automatically be closed if all presentations are finished.
478 * if you want to show your own presentation in your application, you should use this
479 * function, so it will not be automatically closed when there is nothing to show.
480 *
481 * don't forgot to deref, or the notification may be never closed if there is no timeout.
482 * @see ref
483 */
484 void ref();
485 /**
486 * remove a reference made with ref()
487 * the notification may be closed when calling this.
488 * @see ref
489 */
490 void deref();
491
492 /**
493 * Emit or re-emit the event.
494 */
495 void sendEvent();
496
497 /**
498 * @internal
499 * update the texts, the icon, and the actions of one existing notification
500 */
501 void update();
502
503private Q_SLOTS:
504 void slotReceivedId(int);
505 void slotReceivedIdError(const QDBusError&);
506
507private:
508 struct Private;
509 Private *const d;
510
511protected:
512 /**
513 * reimplemented for internal reasons
514 */
515 virtual bool eventFilter( QObject * watched, QEvent * event );
516
517
518public:
519 /**
520 * @brief emit an event
521 *
522 * This method creates the KNotification, setting every parameter, and fire the event.
523 * You don't need to call sendEvent
524 *
525 * A popup may be displayed or a sound may be played, depending the config.
526 *
527 * @return a KNotification . You may use that pointer to connect some signals or slot.
528 * the pointer is automatically deleted when the event is closed.
529 *
530 * Make sure you use one of the CloseOnTimeOut or CloseWhenWidgetActivated, if not,
531 * you have to close yourself the notification.
532 *
533 * @note the text is shown in a QLabel, you should escape HTML, if needed.
534 *
535 * @param eventId is the name of the event
536 * @param title is title of the notification to show in the popup.
537 * @param text is the text of the notification to show in the popup.
538 * @param pixmap is a picture which may be shown in the popup.
539 * @param widget is a widget where the notification reports to
540 * @param flags is a bitmask of NotificationFlag
541 * @param componentData used to determine the location of the config file. by default, kapp is used
542 * @since 4.4
543 */
544 static KNotification *event(const QString &eventId , const QString &title, const QString &text,
545 const QPixmap &pixmap = QPixmap(), QWidget *widget = 0L,
546 const NotificationFlags &flags = CloseOnTimeout,
547 const KComponentData &componentData = KComponentData());
548
549 /**
550 * @brief emit a standard event
551 *
552 * @overload
553 *
554 * This will emit a standard event
555 *
556 * @param eventId is the name of the event
557 * @param text is the text of the notification to show in the popup.
558 * @param pixmap is a picture which may be shown in the popup.
559 * @param widget is a widget where the notification reports to
560 * @param flags is a bitmask of NotificationFlag
561 * @param componentData used to determine the location of the config file. by default, kapp is used
562 */
563 static KNotification *event(const QString &eventId , const QString &text = QString(),
564 const QPixmap &pixmap = QPixmap(), QWidget *widget = 0L,
565 const NotificationFlags &flags = CloseOnTimeout,
566 const KComponentData &componentData = KComponentData());
567
568 /**
569 * @brief emit a standard event
570 *
571 * @overload
572 *
573 * This will emit a standard event
574 *
575 * @param eventId is the name of the event
576 * @param text is the text of the notification to show in the popup
577 * @param pixmap is a picture which may be shown in the popup
578 * @param widget is a widget where the notification reports to
579 * @param flags is a bitmask of NotificationFlag
580 */
581 static KNotification *event( StandardEvent eventId , const QString& text=QString(),
582 const QPixmap& pixmap=QPixmap(), QWidget *widget=0L,
583 const NotificationFlags& flags=CloseOnTimeout);
584
585 /**
586 * @brief emit a standard event
587 *
588 * @overload
589 *
590 * This will emit a standard event
591 *
592 * @param eventId is the name of the event
593 * @param title is title of the notification to show in the popup.
594 * @param text is the text of the notification to show in the popup
595 * @param pixmap is a picture which may be shown in the popup
596 * @param widget is a widget where the notification reports to
597 * @param flags is a bitmask of NotificationFlag
598 * @since 4.4
599 */
600 static KNotification *event( StandardEvent eventId , const QString& title, const QString& text,
601 const QPixmap& pixmap=QPixmap(), QWidget *widget=0L,
602 const NotificationFlags& flags=CloseOnTimeout);
603
604 /**
605 * This is a simple substitution for QApplication::beep()
606 *
607 * @param reason a short text explaining what has happened (may be empty)
608 * @param widget the widget the notification refers to
609 */
610 static void beep( const QString& reason = QString() , QWidget *widget=0L);
611
612 //prevent warning
613 using QObject::event;
614};
615
616Q_DECLARE_OPERATORS_FOR_FLAGS(KNotification::NotificationFlags)
617
618#endif
619