add more spacing
[personal-kdebase.git] / workspace / plasma / applets / systemtray / ui / notificationwidget.cpp
blob347d657b93cd4ed47c1f807dc381304c7de237c1
1 /***************************************************************************
2 * notificationwidget.cpp *
3 * *
4 * Copyright (C) 2008 Dmitry Suzdalev <dimsuz@gmail.com> *
5 * Copyright (C) 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl> *
6 * Copyright (C) 2008 Jason Stubbs <jasonbstubbs@gmail.com> *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Library General Public License as *
10 * published by the Free Software Foundation; either version 2 of the *
11 * License, or (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Library General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Library General Public *
19 * License along with this library; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
22 ***************************************************************************/
24 #include "notificationwidget.h"
26 #include <QSignalMapper>
28 #include <QtGui/QGraphicsLinearLayout>
29 #include <QtGui/QTextDocument>
30 #include <QtGui/QFontMetrics>
31 #include <QtGui/QGraphicsSceneResizeEvent>
32 #include <QtGui/QPainter>
34 #include <KColorScheme>
35 #include <KPushButton>
36 #include <KGlobalSettings>
37 #include <KIcon>
38 #include <KLocalizedString>
40 #include <plasma/extender.h>
41 #include <plasma/extenderitem.h>
42 #include <plasma/theme.h>
43 #include <plasma/widgets/pushbutton.h>
45 class NotificationWidgetPrivate
47 public:
48 NotificationWidgetPrivate(NotificationWidget *q)
49 : q(q),
50 notification(0),
51 destroyOnClose(true),
52 body(new QGraphicsTextItem(q)),
53 actionsWidget(0),
54 signalMapper(new QSignalMapper(q))
58 void setTextFields(const QString &applicationName, const QString &summary, const QString &message);
59 void completeDetach();
60 void updateActions();
61 void updateNotification();
62 void destroy();
64 NotificationWidget *q;
66 SystemTray::Notification *notification;
67 bool destroyOnClose;
69 QString message;
70 QGraphicsTextItem *body;
71 QGraphicsWidget *actionsWidget;
72 QHash<QString, QString> actions;
73 QStringList actionOrder;
75 QSignalMapper *signalMapper;
78 NotificationWidget::NotificationWidget(SystemTray::Notification *notification, Plasma::ExtenderItem *extenderItem)
79 : QGraphicsWidget(extenderItem),
80 d(new NotificationWidgetPrivate(this))
82 setMinimumWidth(300);
83 setPreferredWidth(400);
85 Plasma::Theme *theme = Plasma::Theme::defaultTheme();
86 d->body->setFont(theme->font(Plasma::Theme::DefaultFont));
87 d->body->setDefaultTextColor(theme->color(Plasma::Theme::TextColor));
89 QTextOption option = d->body->document()->defaultTextOption();
90 option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
91 d->body->document()->setDefaultTextOption(option);
93 if (notification) {
94 d->notification = notification;
96 connect(d->signalMapper, SIGNAL(mapped(const QString &)),
97 d->notification, SLOT(triggerAction(const QString &)));
98 connect(notification, SIGNAL(changed()),
99 this, SLOT(updateNotification()));
100 connect(notification, SIGNAL(destroyed()),
101 this, SLOT(destroy()));
103 d->updateNotification();
104 } else {
105 d->setTextFields(extenderItem->config().readEntry("applicationName", ""),
106 extenderItem->config().readEntry("summary", ""),
107 extenderItem->config().readEntry("message", ""));
108 qreal bodyHeight = d->body->boundingRect().height();
109 setPreferredHeight(bodyHeight);
110 extenderItem->showCloseButton();
114 NotificationWidget::~NotificationWidget()
116 delete d;
119 void NotificationWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
121 d->body->setTextWidth(event->newSize().width());
122 d->body->setPos(0, 0);
123 if (d->actionsWidget) {
124 d->actionsWidget->setPos(event->newSize().width() - d->actionsWidget->size().width(),
125 event->newSize().height() - d->actionsWidget->size().height());
129 void NotificationWidgetPrivate::setTextFields(const QString &applicationName,
130 const QString &summary, const QString &message)
132 Plasma::ExtenderItem *extenderItem = dynamic_cast<Plasma::ExtenderItem*>(q->parentWidget());
134 if (!summary.isEmpty()) {
135 extenderItem->setTitle(summary);
136 } else {
137 extenderItem->setTitle(i18n("Notification from %1", applicationName));
140 body->setHtml(message);
143 void NotificationWidgetPrivate::completeDetach()
145 actions.clear();
146 actionOrder.clear();
148 delete actionsWidget;
149 actionsWidget = 0;
152 void NotificationWidgetPrivate::updateActions()
154 if (actions.isEmpty() || actionsWidget) {
155 return;
158 actionsWidget = new QGraphicsWidget(q);
159 QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(actionsWidget);
160 layout->setOrientation(Qt::Horizontal);
161 actionsWidget->setContentsMargins(0, 0, 0, 0);
163 foreach (const QString &actionId, actionOrder) {
164 Plasma::PushButton *button = new Plasma::PushButton(actionsWidget);
165 QString &action = actions[actionId];
166 button->setText(action);
167 button->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
168 //TODO: we need smaller buttons but I don't like this method of accomplishing it.
169 button->setPreferredHeight(button->minimumHeight() - 6);
171 q->connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
172 signalMapper->setMapping(button, actionId);
174 layout->addItem(button);
177 layout->updateGeometry();
178 actionsWidget->setPos(q->size().width() - actionsWidget->size().width(),
179 q->size().width() - actionsWidget->size().height());
182 void NotificationWidgetPrivate::updateNotification()
184 Plasma::ExtenderItem *extenderItem = dynamic_cast<Plasma::ExtenderItem*>(q->parentWidget());
186 //store the notification
187 extenderItem->config().writeEntry("applicationName", notification->applicationName());
188 extenderItem->config().writeEntry("summary", notification->summary());
189 extenderItem->config().writeEntry("message", notification->message());
191 //set text fields and icon
192 setTextFields(notification->applicationName(), notification->summary(), notification->message());
193 extenderItem->setIcon(notification->applicationIcon());
195 //set the actions provided
196 actions = notification->actions();
197 actionOrder = notification->actionOrder();
198 updateActions();
200 //set the correct size hint and display a close action if no actions are provided by the
201 //notification
202 qreal bodyHeight = body->boundingRect().height();
203 if (actionsWidget) {
204 extenderItem->hideCloseButton();
205 q->setPreferredHeight(bodyHeight + actionsWidget->size().height());
206 } else {
207 extenderItem->showCloseButton();
208 q->setPreferredHeight(bodyHeight);
212 void NotificationWidgetPrivate::destroy()
214 Plasma::ExtenderItem *extenderItem = dynamic_cast<Plasma::ExtenderItem *>(q->parentItem());
216 if (extenderItem->isDetached()) {
217 completeDetach();
218 } else {
219 completeDetach();
220 extenderItem->destroy();
223 notification = 0;
226 #include "notificationwidget.moc"