1 /***************************************************************************
2 * notificationwidget.cpp *
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> *
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. *
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. *
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>
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
48 NotificationWidgetPrivate(NotificationWidget
*q
)
52 body(new QGraphicsTextItem(q
)),
54 signalMapper(new QSignalMapper(q
))
58 void setTextFields(const QString
&applicationName
, const QString
&summary
, const QString
&message
);
59 void completeDetach();
61 void updateNotification();
64 NotificationWidget
*q
;
66 SystemTray::Notification
*notification
;
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))
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
);
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();
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()
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
);
137 extenderItem
->setTitle(i18n("Notification from %1", applicationName
));
140 body
->setHtml(message
);
143 void NotificationWidgetPrivate::completeDetach()
148 delete actionsWidget
;
152 void NotificationWidgetPrivate::updateActions()
154 if (actions
.isEmpty() || actionsWidget
) {
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();
200 //set the correct size hint and display a close action if no actions are provided by the
202 qreal bodyHeight
= body
->boundingRect().height();
204 extenderItem
->hideCloseButton();
205 q
->setPreferredHeight(bodyHeight
+ actionsWidget
->size().height());
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()) {
220 extenderItem
->destroy();
226 #include "notificationwidget.moc"