2
* Copyright 2010 Chani Armitage <chani@kde.org>
3
* Copyright 2010 Ivan Cukic <ivan.cukic(at)kde.org>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU Library/Lesser General Public License
7
* version 2, or (at your option) any later version, as published by the
8
* Free Software Foundation
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details
15
* You should have received a copy of the GNU Library/Lesser General Public
16
* License along with this program; if not, write to the
17
* Free Software Foundation, Inc.,
18
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
#include "activityicon.h"
24
#include "activitycontrols.h"
25
#include "desktopcorona.h"
26
#include "plasmaapp.h"
28
#include <QGraphicsLinearLayout>
29
#include <QGraphicsSceneMouseEvent>
30
#include <QGraphicsGridLayout>
33
#include <QSizePolicy>
35
#include <KIconLoader>
37
#include <KStandardDirs>
38
#include <KGlobalSettings>
40
#include <Plasma/Label>
41
#include <Plasma/PushButton>
42
#include <Plasma/LineEdit>
43
#include <Plasma/IconWidget>
44
#include <Plasma/Package>
46
#include <scripting/layouttemplatepackagestructure.h>
47
#include "scripting/desktopscriptengine.h"
49
#define REMOVE_ICON KIcon("edit-delete")
50
#define STOP_ICON KIcon("media-playback-stop")
51
#define START_ICON KIcon("media-playback-start")
52
#define CONFIGURE_ICON KIcon("configure")
54
class ActivityActionWidget: public QGraphicsWidget {
56
ActivityActionWidget(ActivityIcon * parent, const QString & slot,
57
const KIcon & icon, const QString & tooltip, const QSize & size = QSize(16, 16))
58
: QGraphicsWidget(parent), m_parent(parent), m_slot(slot), m_iconSize(size), m_icon(icon)
61
setMinimumSize(m_iconSize);
62
setPreferredSize(m_iconSize);
63
setMaximumSize(m_iconSize);
65
setGeometry(0, 0, m_iconSize.width(), m_iconSize.height());
69
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
71
QGraphicsWidget::paint(painter, option, widget);
72
painter->drawPixmap(0, 0, m_icon.pixmap(m_iconSize));
75
void mousePressEvent(QGraphicsSceneMouseEvent * event)
77
QGraphicsWidget::mouseReleaseEvent(event);
79
if (event->button() != Qt::LeftButton)
82
QMetaObject::invokeMethod(m_parent, m_slot.toAscii());
87
ActivityIcon * m_parent;
94
ActivityIcon::ActivityIcon(const QString &id)
101
m_inlineWidgetAnim(0)
103
DesktopCorona *c = qobject_cast<DesktopCorona*>(PlasmaApp::self()->corona());
104
m_activity = c->activity(id);
108
connect(this, SIGNAL(clicked(Plasma::AbstractIcon*)), m_activity, SLOT(activate()));
109
connect(m_activity, SIGNAL(stateChanged()), this, SLOT(updateButtons()));
110
connect(m_activity, SIGNAL(infoChanged()), this, SLOT(updateContents()));
111
connect(m_activity, SIGNAL(currentStatusChanged()), this, SLOT(currentStatusChanged()));
112
setName(m_activity->name());
113
currentStatusChanged();
115
setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
118
ActivityIcon::ActivityIcon(const QString &name, const QString &icon, const QString &plugin)
123
m_buttonConfigure(0),
126
m_pluginName(plugin),
129
m_inlineWidgetAnim(0)
131
DesktopCorona *c = qobject_cast<DesktopCorona*>(PlasmaApp::self()->corona());
135
connect(this, SIGNAL(clicked(Plasma::AbstractIcon*)),
136
this, SLOT(createActivity(Plasma::AbstractIcon*)));
138
currentStatusChanged();
140
setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
143
void ActivityIcon::createActivity(Plasma::AbstractIcon * icon)
145
KService::Ptr service = KService::serviceByStorageId(m_pluginName);
147
KPluginInfo info(service);
148
Plasma::PackageStructure::Ptr structure(new WorkspaceScripting::LayoutTemplatePackageStructure);
150
const QString path = KStandardDirs::locate("data", structure->defaultPackageRoot() + '/' + info.pluginName() + '/');
151
if (!path.isEmpty()) {
152
Plasma::Package package(path, structure);
153
const QString scriptFile = package.filePath("mainscript");
154
const QStringList startupApps = service->property("X-Plasma-ContainmentLayout-ExecuteOnCreation", QVariant::StringList).toStringList();
156
if (!scriptFile.isEmpty() || !startupApps.isEmpty()) {
157
PlasmaApp::self()->createActivityFromScript(
166
KConfig config("plasma-desktoprc");
167
KConfigGroup group(&config, "ActivityManager HiddenTemplates");
169
group.writeEntry(m_pluginName, true);
172
emit requestsRemoval(false);
176
ActivityIcon::~ActivityIcon()
180
QPixmap ActivityIcon::pixmap(const QSize &size)
183
return m_activity->pixmap(size);
185
return m_icon.pixmap(size);
189
QMimeData* ActivityIcon::mimeData()
191
//TODO: how shall we use d&d?
195
class MakeRoomAnimation : public QAbstractAnimation
198
MakeRoomAnimation(ActivityIcon *icon, qreal addedWidth, QObject *parent)
199
: QAbstractAnimation(parent),
201
m_addWidth(addedWidth)
203
m_startSize = icon->geometry().size();
204
m_icon->getContentsMargins(0, 0, &m_startRightMargin, 0);
212
void updateCurrentTime(int currentTime)
214
const qreal delta = currentTime / (float) duration();
216
m_icon->setPreferredSize(m_startSize + QSizeF(m_addWidth * delta, 0));
218
qreal left, top, right, bottom;
219
m_icon->getContentsMargins(&left, &top, &right, &bottom);
221
right = m_startRightMargin + m_addWidth * delta;
223
m_icon->setContentsMargins(left, top, right, bottom);
227
ActivityIcon * m_icon;
230
qreal m_startRightMargin;
233
void ActivityIcon::showInlineWidget(ActivityControls * w)
235
hideInlineWidget(true);
237
connect(w, SIGNAL(closed()), this, SLOT(hideInlineWidget()));
239
w->setMaximumSize(QSize(0, size().height()));
241
w->setPos(contentsRect().topRight() + QPoint(4, 0));
245
QTimer::singleShot(0, this, SLOT(startInlineAnim()));
248
void ActivityIcon::showRemovalConfirmation()
250
ActivityControls * w = new ActivityRemovalConfirmation(this);
253
connect(w, SIGNAL(removalConfirmed()), m_activity, SLOT(remove()));
255
connect(w, SIGNAL(removalConfirmed()), this, SLOT(hideTemplate()));
260
void ActivityIcon::showConfiguration()
263
showInlineWidget(new ActivityConfiguration(this, m_activity));
266
void ActivityIcon::startInlineAnim()
268
QGraphicsWidget * w = m_inlineWidget.data();
269
//kDebug() << "Booh yah!" << w;
274
//kDebug() << w->preferredSize() << w->layout()->preferredSize();
275
if (!m_inlineWidgetAnim) {
276
m_inlineWidgetAnim = new MakeRoomAnimation(this, w->layout()->preferredSize().width() + 4, this);
277
connect(m_inlineWidgetAnim, SIGNAL(finished()), this, SLOT(makeInlineWidgetVisible()));
280
m_inlineWidgetAnim->start();
283
void ActivityIcon::hideInlineWidget(bool aboutToShowAnother)
285
if (m_inlineWidget) {
286
m_inlineWidget.data()->deleteLater();
287
m_inlineWidget.data()->hide();
290
if (m_inlineWidgetAnim && !aboutToShowAnother) {
291
m_inlineWidgetAnim->setDirection(QAbstractAnimation::Backward);
292
if (m_inlineWidgetAnim->state() != QAbstractAnimation::Running) {
293
m_inlineWidgetAnim->start(QAbstractAnimation::DeleteWhenStopped);
294
m_inlineWidgetAnim = 0;
299
void ActivityIcon::makeInlineWidgetVisible()
301
if (m_inlineWidget) {
302
m_inlineWidget.data()->show();
306
void ActivityIcon::setClosable(bool closable)
308
if (closable == m_closable) {
312
m_closable = closable;
316
Activity* ActivityIcon::activity()
321
void ActivityIcon::activityRemoved()
327
void ActivityIcon::setGeometry(const QRectF & geometry)
329
Plasma::AbstractIcon::setGeometry(geometry);
333
void ActivityIcon::updateLayout()
335
QRectF rect = contentsRect();
338
(rect.width() - iconSize()) / 2,
339
rect.height() - iconSize(),
340
- (rect.width() - iconSize()) / 2,
345
m_buttonStop->setGeometry(QRectF(
346
rect.topRight() - QPointF(m_buttonStop->m_iconSize.width(), 0),
347
m_buttonStop->m_iconSize
351
if (m_buttonRemove) {
352
m_buttonRemove->setGeometry(QRectF(
353
rect.topRight() - QPointF(m_buttonRemove->m_iconSize.width(), 0),
354
m_buttonRemove->m_iconSize
358
if (m_buttonConfigure) {
359
m_buttonConfigure->setGeometry(QRectF(
360
rect.bottomRight() - QPointF(m_buttonConfigure->m_iconSize.width(), m_buttonConfigure->m_iconSize.height()),
361
m_buttonConfigure->m_iconSize
366
m_buttonStart->setGeometry(QRectF(
367
rect.center() - QPointF(m_buttonStart->m_iconSize.width() / 2, m_buttonStart->m_iconSize.height() / 2),
368
m_buttonStart->m_iconSize
373
void ActivityIcon::updateButtons()
377
if (!m_buttonConfigure) {
378
m_buttonConfigure = new ActivityActionWidget(this, "showConfiguration", CONFIGURE_ICON, i18n("Configure activity"));
381
#define DESTROY_ACTIVITY_ACTION_WIDIGET(A) \
388
switch (m_activity->state()) {
389
case KActivityInfo::Running:
390
DESTROY_ACTIVITY_ACTION_WIDIGET(m_buttonStart);
391
DESTROY_ACTIVITY_ACTION_WIDIGET(m_buttonRemove);
395
m_buttonStop = new ActivityActionWidget(this, "stopActivity", STOP_ICON, i18n("Stop activity"));
398
DESTROY_ACTIVITY_ACTION_WIDIGET(m_buttonStop);
402
case KActivityInfo::Stopped:
403
DESTROY_ACTIVITY_ACTION_WIDIGET(m_buttonStop);
405
if (!m_buttonRemove) {
406
m_buttonRemove = new ActivityActionWidget(this, "showRemovalConfirmation", REMOVE_ICON, i18n("Stop activity"));
409
if (!m_buttonStart) {
410
m_buttonStart = new ActivityActionWidget(this, "startActivity", START_ICON, i18n("Start activity"), QSize(32, 32));
414
case KActivityInfo::Invalid:
415
DESTROY_ACTIVITY_ACTION_WIDIGET(m_buttonConfigure);
418
default: //transitioning or invalid: don't let the user mess with it
419
DESTROY_ACTIVITY_ACTION_WIDIGET(m_buttonStart);
420
DESTROY_ACTIVITY_ACTION_WIDIGET(m_buttonRemove);
421
DESTROY_ACTIVITY_ACTION_WIDIGET(m_buttonStop);
424
#undef DESTROY_ACTIVITY_ACTION_WIDIGET
427
if (!m_buttonRemove) {
428
m_buttonRemove = new ActivityActionWidget(this, "showRemovalConfirmation", REMOVE_ICON, i18n("Stop activity"));
435
void ActivityIcon::stopActivity()
442
void ActivityIcon::startActivity()
447
void ActivityIcon::updateContents()
450
setName(m_activity->name());
454
void ActivityIcon::currentStatusChanged()
457
setSelected(m_activity->isCurrent());
460
void ActivityIcon::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
462
if (m_inlineWidget && m_inlineWidget.data()->hidesContents()) {
463
paintBackground(painter, option, widget);
467
AbstractIcon::paint(painter, option, widget);
470
void ActivityIcon::hideTemplate()
472
KConfig config("plasma-desktoprc");
473
KConfigGroup group(&config, "ActivityManager HiddenTemplates");
475
group.writeEntry(m_pluginName, true);
478
emit requestsRemoval(true);
481
#include "activityicon.moc"