1 | /* |
2 | Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org> |
3 | Copyright (c) 2008 Stephen Kelly <steveire@gmail.com> |
4 | Copyright (c) 2009 Kevin Ottens <ervin@kde.org> |
5 | |
6 | This library is free software; you can redistribute it and/or modify it |
7 | under the terms of the GNU Library General Public License as published by |
8 | the Free Software Foundation; either version 2 of the License, or (at your |
9 | option) any later version. |
10 | |
11 | This library is distributed in the hope that it will be useful, but WITHOUT |
12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
14 | License for more details. |
15 | |
16 | You should have received a copy of the GNU Library General Public License |
17 | along with this library; see the file COPYING.LIB. If not, write to the |
18 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
19 | 02110-1301, USA. |
20 | */ |
21 | |
22 | #include "entitylistview.h" |
23 | |
24 | #include "dragdropmanager_p.h" |
25 | #include "favoritecollectionsmodel.h" |
26 | |
27 | #include <QtCore/QDebug> |
28 | #include <QtCore/QTimer> |
29 | #include <QDragMoveEvent> |
30 | #include <QMenu> |
31 | |
32 | #include <kdebug.h> |
33 | #include <kxmlguiclient.h> |
34 | #include <KXMLGUIFactory> |
35 | |
36 | #include <akonadi/collection.h> |
37 | #include <akonadi/control.h> |
38 | #include <akonadi/item.h> |
39 | #include <akonadi/entitytreemodel.h> |
40 | |
41 | #include <progressspinnerdelegate_p.h> |
42 | |
43 | using namespace Akonadi; |
44 | |
45 | /** |
46 | * @internal |
47 | */ |
48 | class EntityListView::Private |
49 | { |
50 | public: |
51 | Private(EntityListView *parent) |
52 | : mParent(parent) |
53 | #ifndef QT_NO_DRAGANDDROP |
54 | , mDragDropManager(new DragDropManager(mParent)) |
55 | #endif |
56 | , mXmlGuiClient(0) |
57 | { |
58 | } |
59 | |
60 | void init(); |
61 | void itemClicked(const QModelIndex &index); |
62 | void itemDoubleClicked(const QModelIndex &index); |
63 | void itemCurrentChanged(const QModelIndex &index); |
64 | |
65 | EntityListView *mParent; |
66 | DragDropManager *mDragDropManager; |
67 | KXMLGUIClient *mXmlGuiClient; |
68 | }; |
69 | |
70 | void EntityListView::Private::init() |
71 | { |
72 | mParent->setEditTriggers(QAbstractItemView::EditKeyPressed); |
73 | mParent->setAcceptDrops(true); |
74 | #ifndef QT_NO_DRAGANDDROP |
75 | mParent->setDropIndicatorShown(true); |
76 | mParent->setDragDropMode(DragDrop); |
77 | mParent->setDragEnabled(true); |
78 | #endif |
79 | mParent->connect(mParent, SIGNAL(clicked(QModelIndex)), |
80 | mParent, SLOT(itemClicked(QModelIndex))); |
81 | mParent->connect(mParent, SIGNAL(doubleClicked(QModelIndex)), |
82 | mParent, SLOT(itemDoubleClicked(QModelIndex))); |
83 | |
84 | DelegateAnimator *animator = new DelegateAnimator(mParent); |
85 | ProgressSpinnerDelegate *customDelegate = new ProgressSpinnerDelegate(animator, mParent); |
86 | mParent->setItemDelegate(customDelegate); |
87 | |
88 | Control::widgetNeedsAkonadi(mParent); |
89 | } |
90 | |
91 | void EntityListView::Private::itemClicked(const QModelIndex &index) |
92 | { |
93 | if (!index.isValid()) { |
94 | return; |
95 | } |
96 | |
97 | const Collection collection = index.model()->data(index, EntityTreeModel::CollectionRole).value<Collection>(); |
98 | if (collection.isValid()) { |
99 | emit mParent->clicked(collection); |
100 | } else { |
101 | const Item item = index.model()->data(index, EntityTreeModel::ItemRole).value<Item>(); |
102 | if (item.isValid()) { |
103 | emit mParent->clicked(item); |
104 | } |
105 | } |
106 | } |
107 | |
108 | void EntityListView::Private::itemDoubleClicked(const QModelIndex &index) |
109 | { |
110 | if (!index.isValid()) { |
111 | return; |
112 | } |
113 | |
114 | const Collection collection = index.model()->data(index, EntityTreeModel::CollectionRole).value<Collection>(); |
115 | if (collection.isValid()) { |
116 | emit mParent->doubleClicked(collection); |
117 | } else { |
118 | const Item item = index.model()->data(index, EntityTreeModel::ItemRole).value<Item>(); |
119 | if (item.isValid()) { |
120 | emit mParent->doubleClicked(item); |
121 | } |
122 | } |
123 | } |
124 | |
125 | void EntityListView::Private::itemCurrentChanged(const QModelIndex &index) |
126 | { |
127 | if (!index.isValid()) { |
128 | return; |
129 | } |
130 | |
131 | const Collection collection = index.model()->data(index, EntityTreeModel::CollectionRole).value<Collection>(); |
132 | if (collection.isValid()) { |
133 | emit mParent->currentChanged(collection); |
134 | } else { |
135 | const Item item = index.model()->data(index, EntityTreeModel::ItemRole).value<Item>(); |
136 | if (item.isValid()) { |
137 | emit mParent->currentChanged(item); |
138 | } |
139 | } |
140 | } |
141 | |
142 | EntityListView::EntityListView(QWidget *parent) |
143 | : QListView(parent) |
144 | , d(new Private(this)) |
145 | { |
146 | setSelectionMode(QAbstractItemView::SingleSelection); |
147 | d->init(); |
148 | } |
149 | |
150 | EntityListView::EntityListView(KXMLGUIClient *xmlGuiClient, QWidget *parent) |
151 | : QListView(parent) |
152 | , d(new Private(this)) |
153 | { |
154 | d->mXmlGuiClient = xmlGuiClient; |
155 | d->init(); |
156 | } |
157 | |
158 | EntityListView::~EntityListView() |
159 | { |
160 | delete d->mDragDropManager; |
161 | delete d; |
162 | } |
163 | |
164 | void EntityListView::setModel(QAbstractItemModel *model) |
165 | { |
166 | if (selectionModel()) { |
167 | disconnect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), |
168 | this, SLOT(itemCurrentChanged(QModelIndex))); |
169 | } |
170 | |
171 | QListView::setModel(model); |
172 | |
173 | connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), |
174 | SLOT(itemCurrentChanged(QModelIndex))); |
175 | } |
176 | |
177 | #ifndef QT_NO_DRAGANDDROP |
178 | void EntityListView::dragMoveEvent(QDragMoveEvent *event) |
179 | { |
180 | if (d->mDragDropManager->dropAllowed(event) || |
181 | qobject_cast<Akonadi::FavoriteCollectionsModel *>(model())) { |
182 | // All urls are supported. process the event. |
183 | QListView::dragMoveEvent(event); |
184 | return; |
185 | } |
186 | |
187 | event->setDropAction(Qt::IgnoreAction); |
188 | } |
189 | |
190 | void EntityListView::dropEvent(QDropEvent *event) |
191 | { |
192 | bool = false; |
193 | if (d->mDragDropManager->processDropEvent(event, menuCanceled) && |
194 | !menuCanceled) { |
195 | if (menuCanceled) { |
196 | return; |
197 | } |
198 | QListView::dropEvent(event); |
199 | } else if (qobject_cast<Akonadi::FavoriteCollectionsModel *>(model()) && |
200 | !menuCanceled) { |
201 | QListView::dropEvent(event); |
202 | } |
203 | } |
204 | #endif |
205 | |
206 | #ifndef QT_NO_CONTEXTMENU |
207 | void EntityListView::(QContextMenuEvent *event) |
208 | { |
209 | if (!d->mXmlGuiClient) { |
210 | return; |
211 | } |
212 | |
213 | const QModelIndex index = indexAt(event->pos()); |
214 | |
215 | QMenu * = 0; |
216 | |
217 | // check if the index under the cursor is a collection or item |
218 | const Collection collection = model()->data(index, EntityTreeModel::CollectionRole).value<Collection>(); |
219 | if (collection.isValid()) { |
220 | popup = static_cast<QMenu *>(d->mXmlGuiClient->factory()->container( |
221 | QLatin1String("akonadi_favoriteview_contextmenu" ), d->mXmlGuiClient)); |
222 | } else { |
223 | popup = static_cast<QMenu *>(d->mXmlGuiClient->factory()->container( |
224 | QLatin1String("akonadi_favoriteview_emptyselection_contextmenu" ), d->mXmlGuiClient)); |
225 | } |
226 | |
227 | if (popup) { |
228 | popup->exec(event->globalPos()); |
229 | } |
230 | } |
231 | #endif |
232 | |
233 | void EntityListView::setXmlGuiClient(KXMLGUIClient *xmlGuiClient) |
234 | { |
235 | d->mXmlGuiClient = xmlGuiClient; |
236 | } |
237 | |
238 | KXMLGUIClient *EntityListView::xmlGuiClient() const |
239 | { |
240 | return d->mXmlGuiClient; |
241 | } |
242 | |
243 | #ifndef QT_NO_DRAGANDDROP |
244 | void EntityListView::startDrag(Qt::DropActions supportedActions) |
245 | { |
246 | d->mDragDropManager->startDrag(supportedActions); |
247 | } |
248 | #endif |
249 | |
250 | void EntityListView::(bool enabled) |
251 | { |
252 | #ifndef QT_NO_DRAGANDDROP |
253 | d->mDragDropManager->setShowDropActionMenu(enabled); |
254 | #endif |
255 | } |
256 | |
257 | bool EntityListView::() const |
258 | { |
259 | #ifndef QT_NO_DRAGANDDROP |
260 | return d->mDragDropManager->showDropActionMenu(); |
261 | #else |
262 | return false; |
263 | #endif |
264 | } |
265 | |
266 | #include "moc_entitylistview.cpp" |
267 | |