2
* Copyright 2009 by Artur Duque de Souza <asouza@kde.org>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU Library General Public License version 2,
7
* or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details
14
* You should have received a copy of the GNU Library General Public
15
* License along with this program; if not, write to the
16
* Free Software Foundation, Inc.,
17
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
#include "stripwidget.h"
21
#include "models/favouritesmodel.h"
22
#include "models/krunnermodel.h"
23
#include "models/kservicemodel.h"
24
#include "models/commonmodel.h"
26
#include <QGraphicsGridLayout>
27
#include <QGraphicsScene>
31
#include <KIconLoader>
34
#include <Plasma/Animation>
35
#include <Plasma/Animator>
36
#include <Plasma/Frame>
37
#include <Plasma/ToolButton>
38
#include <Plasma/IconWidget>
39
#include <Plasma/AbstractRunner>
40
#include <Plasma/RunnerManager>
41
#include <Plasma/ScrollWidget>
45
#include "iconactioncollection.h"
47
StripWidget::StripWidget(QGraphicsWidget *parent)
48
: QGraphicsWidget(parent),
51
m_iconActionCollection(0),
53
m_startupCompleted(false)
55
m_favouritesModel = new FavouritesModel(this);
57
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
60
Plasma::Applet *applet = qobject_cast<Plasma::Applet *>(parent);
62
m_iconActionCollection = new IconActionCollection(applet, this);
65
m_arrowsLayout = new QGraphicsLinearLayout(this);
66
m_arrowsLayout->setContentsMargins(0, 0, 0, 0);
67
setFocusPolicy(Qt::StrongFocus);
69
m_leftArrow = new Plasma::ToolButton(this);
70
m_leftArrow->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
71
m_leftArrow->setPreferredWidth(KIconLoader::SizeMedium);
72
m_leftArrow->setImage("widgets/arrows", "left-arrow");
73
connect(m_leftArrow, SIGNAL(clicked()), this, SLOT(goLeft()));
74
connect(m_leftArrow, SIGNAL(pressed()), this, SLOT(scrollTimeout()));
76
m_rightArrow = new Plasma::ToolButton(this);
77
m_rightArrow->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
78
m_rightArrow->setPreferredWidth(KIconLoader::SizeMedium);
79
m_rightArrow->setImage("widgets/arrows", "right-arrow");
80
connect(m_rightArrow, SIGNAL(clicked()), this, SLOT(goRight()));
81
connect(m_rightArrow, SIGNAL(pressed()), this, SLOT(scrollTimeout()));
83
m_leftArrow->setEnabled(false);
84
m_rightArrow->setEnabled(false);
88
m_itemView = new ItemView(this);
89
m_itemView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
90
m_itemView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
91
m_itemView->installEventFilter(this);
92
m_itemView->setOrientation(Qt::Horizontal);
93
m_itemView->setIconSize(KIconLoader::SizeLarge);
94
m_itemView->setDragAndDropMode(ItemContainer::MoveDragAndDrop);
95
m_itemView->setModel(m_favouritesModel);
97
connect(m_itemView, SIGNAL(itemActivated(const QModelIndex &)), this, SLOT(launchFavourite(const QModelIndex &)));
98
connect(m_itemView, SIGNAL(scrollBarsNeededChanged(ItemView::ScrollBarFlags)), this, SLOT(arrowsNeededChanged(ItemView::ScrollBarFlags)));
99
connect(m_itemView, SIGNAL(itemAskedReorder(const QModelIndex &, const QPointF &)), this, SLOT(reorderItem(const QModelIndex &, const QPointF&)));
100
connect(m_itemView, SIGNAL(dragStartRequested(const QModelIndex &)), this, SLOT(showDeleteTarget()));
102
m_arrowsLayout->addItem(m_leftArrow);
103
m_arrowsLayout->addItem(m_itemView);
104
m_arrowsLayout->addItem(m_rightArrow);
106
m_scrollTimer = new QTimer(this);
107
m_scrollTimer->setSingleShot(false);
108
connect(m_scrollTimer, SIGNAL(timeout()), this, SLOT(scrollTimeout()));
111
StripWidget::~StripWidget()
115
void StripWidget::showDeleteTarget()
117
if (!m_deleteTarget) {
118
m_deleteTarget = new Plasma::IconWidget();
119
scene()->addItem(m_deleteTarget);
120
m_deleteTarget->setIcon("user-trash");
121
m_deleteTarget->resize(KIconLoader::SizeHuge, KIconLoader::SizeHuge);
122
m_deleteTarget->setZValue(99);
124
m_deleteTarget->setPos(mapToScene(boundingRect().bottomLeft()));
125
m_deleteTarget->show();
126
Plasma::Animation *zoomAnim = Plasma::Animator::create(Plasma::Animator::ZoomAnimation);
127
zoomAnim->setTargetWidget(m_deleteTarget);
128
zoomAnim->setProperty("zoom", 1.0);
129
zoomAnim->start(QAbstractAnimation::DeleteWhenStopped);
132
void StripWidget::setImmutability(Plasma::ImmutabilityType immutability)
134
if (immutability == Plasma::Mutable) {
135
m_itemView->setDragAndDropMode(ItemContainer::MoveDragAndDrop);
137
m_itemView->setDragAndDropMode(ItemContainer::NoDragAndDrop);
142
void StripWidget::reorderItem(const QModelIndex &index, const QPointF &pos)
144
if (m_deleteTarget && m_deleteTarget->geometry().contains(m_itemView->widget()->mapToItem(this, pos))) {
145
m_favouritesModel->removeRow(index.row());
147
QList<QStandardItem *>items = m_favouritesModel->takeRow(index.row());
148
int row = m_itemView->rowForPosition(pos);
150
m_favouritesModel->insertRow(row, items);
153
Plasma::Animation *zoomAnim = Plasma::Animator::create(Plasma::Animator::ZoomAnimation);
154
zoomAnim->setTargetWidget(m_deleteTarget);
155
zoomAnim->start(QAbstractAnimation::DeleteWhenStopped);
158
void StripWidget::save(KConfigGroup &cg)
160
m_favouritesModel->save(cg);
163
void StripWidget::restore(KConfigGroup &cg)
165
m_favouritesModel->restore(cg);
168
void StripWidget::launchFavourite(const QModelIndex &index)
170
KUrl url(index.data(CommonModel::Url).value<QString>());
171
if (!KServiceItemHandler::openUrl(url)) {
172
KRunnerItemHandler::openUrl(url);
176
void StripWidget::add(const QUrl &url)
178
m_favouritesModel->add(url);
182
void StripWidget::goRight()
184
QRectF rect(m_itemView->boundingRect());
185
rect.moveLeft(rect.right() - m_itemView->widget()->pos().x());
186
rect.setWidth(rect.width()/4);
188
m_itemView->ensureRectVisible(rect);
191
void StripWidget::goLeft()
193
QRectF rect(m_itemView->boundingRect());
194
rect.setWidth(rect.width()/4);
195
rect.moveRight(- m_itemView->widget()->pos().x());
197
m_itemView->ensureRectVisible(rect);
200
void StripWidget::scrollTimeout()
202
if (!m_scrollTimer->isActive()) {
203
m_scrollTimer->start(250);
204
} else if (m_leftArrow->isDown()) {
206
} else if (m_rightArrow->isDown()) {
209
m_scrollTimer->stop();
213
void StripWidget::setIconSize(int iconSize)
215
m_itemView->setIconSize(iconSize);
218
int StripWidget::iconSize() const
220
return m_itemView->iconSize();
223
void StripWidget::arrowsNeededChanged(ItemView::ScrollBarFlags flags)
225
bool leftNeeded = false;
226
bool rightNeeded = false;
228
if (flags & ItemView::HorizontalScrollBar) {
229
leftNeeded = m_itemView->scrollPosition().x() > 0;
230
rightNeeded = m_itemView->contentsSize().width() - m_itemView->scrollPosition().x() > m_itemView->size().width();
233
m_leftArrow->setEnabled(leftNeeded);
234
m_rightArrow->setEnabled(rightNeeded);
235
m_leftArrow->setVisible(leftNeeded|rightNeeded);
236
m_rightArrow->setVisible(leftNeeded|rightNeeded);
237
m_arrowsLayout->invalidate();
242
void StripWidget::focusInEvent(QFocusEvent *event)
246
m_itemView->setFocus();
249
void StripWidget::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
251
event->setAccepted(event->mimeData()->hasFormat("application/x-plasma-salquerymatch") || event->mimeData()->hasFormat("text/uri-list"));
254
void StripWidget::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
256
m_itemView->setScrollPositionFromDragPosition(event->pos());
257
m_itemView->showSpacer(m_itemView->widget()->mapFromScene(event->scenePos()));
260
void StripWidget::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
264
m_itemView->showSpacer(QPointF());
267
void StripWidget::dropEvent(QGraphicsSceneDragDropEvent *event)
269
m_itemView->showSpacer(QPointF());
270
if (event->mimeData()->hasFormat("application/x-plasma-salquerymatch")) {
271
QByteArray itemData = event->mimeData()->data("application/x-plasma-salquerymatch");
272
QDataStream dataStream(&itemData, QIODevice::ReadOnly);
278
int row = m_itemView->rowForPosition(m_itemView->widget()->mapFromScene(event->scenePos()));
279
QModelIndex index = m_favouritesModel->index(row, 0, QModelIndex());
281
m_favouritesModel->add(url.toString(), index);
284
} else if (event->mimeData()->urls().size() > 0) {
285
int row = m_itemView->rowForPosition(m_itemView->widget()->mapFromScene(event->scenePos()));
286
QModelIndex index = m_favouritesModel->index(row, 0, QModelIndex());
287
m_favouritesModel->add(event->mimeData()->urls().first().path(), index);