1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
|
/***************************************************************************
* Copyright (C) 2011 by Peter Penz <[email protected]> *
* *
* Based on the Itemviews NG project from Trolltech Labs: *
* http://qt.gitorious.org/qt-labs/itemviews-ng *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef KITEMLISTCONTROLLER_H
#define KITEMLISTCONTROLLER_H
#include "libdolphin_export.h"
#include "kitemset.h"
#include <QObject>
#include <QPointF>
class QTimer;
class KItemModelBase;
class KItemListKeyboardSearchManager;
class KItemListSelectionManager;
class KItemListView;
class KItemListWidget;
class QGraphicsSceneHoverEvent;
class QGraphicsSceneDragDropEvent;
class QGraphicsSceneMouseEvent;
class QGraphicsSceneResizeEvent;
class QGraphicsSceneWheelEvent;
class QHideEvent;
class QInputMethodEvent;
class QKeyEvent;
class QShowEvent;
class QTransform;
/**
* @brief Controls the view, model and selection of an item-list.
*
* For a working item-list it is mandatory to set a compatible view and model
* with KItemListController::setView() and KItemListController::setModel().
*
* @see KItemListView
* @see KItemModelBase
* @see KItemListSelectionManager
*/
class LIBDOLPHINPRIVATE_EXPORT KItemListController : public QObject
{
Q_OBJECT
Q_ENUMS(SelectionBehavior)
Q_PROPERTY(KItemModelBase* model READ model WRITE setModel)
Q_PROPERTY(KItemListView *view READ view WRITE setView)
Q_PROPERTY(SelectionBehavior selectionBehavior READ selectionBehavior WRITE setSelectionBehavior)
Q_PROPERTY(AutoActivationBehavior autoActivationBehavior READ autoActivationBehavior WRITE setAutoActivationBehavior)
Q_PROPERTY(MouseDoubleClickAction mouseDoubleClickAction READ mouseDoubleClickAction WRITE setMouseDoubleClickAction)
public:
enum SelectionBehavior {
NoSelection,
SingleSelection,
MultiSelection
};
enum AutoActivationBehavior {
ActivationAndExpansion,
ExpansionOnly
};
enum MouseDoubleClickAction {
ActivateAndExpandItem,
ActivateItemOnly
};
/**
* @param model Model of the controller. The ownership is passed to the controller.
* @param view View of the controller. The ownership is passed to the controller.
* @param parent Optional parent object.
*/
KItemListController(KItemModelBase* model, KItemListView* view, QObject* parent = 0);
virtual ~KItemListController();
void setModel(KItemModelBase* model);
KItemModelBase* model() const;
void setView(KItemListView* view);
KItemListView* view() const;
KItemListSelectionManager* selectionManager() const;
void setSelectionBehavior(SelectionBehavior behavior);
SelectionBehavior selectionBehavior() const;
void setAutoActivationBehavior(AutoActivationBehavior behavior);
AutoActivationBehavior autoActivationBehavior() const;
void setMouseDoubleClickAction(MouseDoubleClickAction action);
MouseDoubleClickAction mouseDoubleClickAction() const;
/**
* Sets the delay in milliseconds when dragging an object above an item
* until the item gets activated automatically. A value of -1 indicates
* that no automatic activation will be done at all (= default value).
*
* The hovered item must support dropping (see KItemModelBase::supportsDropping()),
* otherwise the automatic activation is not available.
*
* After activating the item the signal itemActivated() will be
* emitted. If the view supports the expanding of items
* (KItemListView::supportsItemExpanding() returns true) and the item
* itself is expandable (see KItemModelBase::isExpandable()) then instead
* of activating the item it gets expanded instead (see
* KItemModelBase::setExpanded()).
*/
void setAutoActivationDelay(int delay);
int autoActivationDelay() const;
/**
* If set to true, the signals itemActivated() and itemsActivated() are emitted
* after a single-click of the left mouse button. If set to false (the default),
* the setting from KGlobalSettings::singleClick() is used.
*/
void setSingleClickActivationEnforced(bool singleClick);
bool singleClickActivationEnforced() const;
virtual bool showEvent(QShowEvent* event);
virtual bool hideEvent(QHideEvent* event);
virtual bool keyPressEvent(QKeyEvent* event);
virtual bool inputMethodEvent(QInputMethodEvent* event);
virtual bool mousePressEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform);
virtual bool mouseMoveEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform);
virtual bool mouseReleaseEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform);
virtual bool mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform);
virtual bool dragEnterEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform);
virtual bool dragLeaveEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform);
virtual bool dragMoveEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform);
virtual bool dropEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform);
virtual bool hoverEnterEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform);
virtual bool hoverMoveEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform);
virtual bool hoverLeaveEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform);
virtual bool wheelEvent(QGraphicsSceneWheelEvent* event, const QTransform& transform);
virtual bool resizeEvent(QGraphicsSceneResizeEvent* event, const QTransform& transform);
virtual bool processEvent(QEvent* event, const QTransform& transform);
signals:
/**
* Is emitted if exactly one item has been activated by e.g. a mouse-click
* or by pressing Return/Enter.
*/
void itemActivated(int index);
/**
* Is emitted if more than one item has been activated by pressing Return/Enter
* when having a selection.
*/
void itemsActivated(const KItemSet& indexes);
void itemMiddleClicked(int index);
/**
* Emitted if a context-menu is requested for the item with
* the index \a index. It is assured that the index is valid.
*/
void itemContextMenuRequested(int index, const QPointF& pos);
/**
* Emitted if a context-menu is requested for the KItemListView.
*/
void viewContextMenuRequested(const QPointF& pos);
/**
* Emitted if a context-menu is requested for the header of the KItemListView.
*/
void headerContextMenuRequested(const QPointF& pos);
/**
* Is emitted if the item with the index \p index gets hovered.
*/
void itemHovered(int index);
/**
* Is emitted if the item with the index \p index gets unhovered.
* It is assured that the signal itemHovered() for this index
* has been emitted before.
*/
void itemUnhovered(int index);
/**
* Is emitted if a mouse-button has been pressed above an item.
* If the index is smaller than 0, the mouse-button has been pressed
* above the viewport.
*/
void mouseButtonPressed(int itemIndex, Qt::MouseButtons buttons);
/**
* Is emitted if a mouse-button has been released above an item.
* It is assured that the signal mouseButtonPressed() has been emitted before.
* If the index is smaller than 0, the mouse-button has been pressed
* above the viewport.
*/
void mouseButtonReleased(int itemIndex, Qt::MouseButtons buttons);
void itemExpansionToggleClicked(int index);
/**
* Is emitted if a drop event is done above the item with the index
* \a index. If \a index is < 0 the drop event is done above an
* empty area of the view.
* TODO: Introduce a new signal viewDropEvent(QGraphicsSceneDragDropEvent),
* which is emitted if the drop event occurs on an empty area in
* the view, and make sure that index is always >= 0 in itemDropEvent().
*/
void itemDropEvent(int index, QGraphicsSceneDragDropEvent* event);
/**
* Is emitted if a drop event is done between the item with the index
* \a index and the previous item.
*/
void aboveItemDropEvent(int index, QGraphicsSceneDragDropEvent* event);
/**
* Is emitted if the Escape key is pressed.
*/
void escapePressed();
void modelChanged(KItemModelBase* current, KItemModelBase* previous);
void viewChanged(KItemListView* current, KItemListView* previous);
private slots:
void slotViewScrollOffsetChanged(qreal current, qreal previous);
/**
* Is invoked when the rubberband boundaries have been changed and will select
* all items that are touched by the rubberband.
*/
void slotRubberBandChanged();
void slotChangeCurrentItem(const QString& text, bool searchFromNextItem);
void slotAutoActivationTimeout();
private:
/**
* Creates a QDrag object and initiates a drag-operation.
*/
void startDragging();
/**
* @return Widget that is currently in the hovered state. 0 is returned
* if no widget is marked as hovered.
*/
KItemListWidget* hoveredWidget() const;
/**
* @return Widget that is below the position \a pos. 0 is returned
* if no widget is below the position.
*/
KItemListWidget* widgetForPos(const QPointF& pos) const;
/**
* Updates m_keyboardAnchorIndex and m_keyboardAnchorPos. If no anchor is
* set, it will be adjusted to the current item. If it is set it will be
* checked whether it is still valid, otherwise it will be reset to the
* current item.
*/
void updateKeyboardAnchor();
/**
* @return Index for the next row based on \a index.
* If there is no next row \a index will be returned.
*/
int nextRowIndex(int index) const;
/**
* @return Index for the previous row based on \a index.
* If there is no previous row \a index will be returned.
*/
int previousRowIndex(int index) const;
/**
* Helper method for updateKeyboardAnchor(), previousRowIndex() and nextRowIndex().
* @return The position of the keyboard anchor for the item with the index \a index.
* If a horizontal scrolling is used the y-position of the item will be returned,
* for the vertical scrolling the x-position will be returned.
*/
qreal keyboardAnchorPos(int index) const;
/**
* Dependent on the selection-behavior the extendedSelectionRegion-property
* of the KItemListStyleOption from the view should be adjusted: If no
* rubberband selection is used the property should be enabled.
*/
void updateExtendedSelectionRegion();
private:
bool m_singleClickActivationEnforced;
bool m_selectionTogglePressed;
bool m_clearSelectionIfItemsAreNotDragged;
SelectionBehavior m_selectionBehavior;
AutoActivationBehavior m_autoActivationBehavior;
MouseDoubleClickAction m_mouseDoubleClickAction;
KItemModelBase* m_model;
KItemListView* m_view;
KItemListSelectionManager* m_selectionManager;
KItemListKeyboardSearchManager* m_keyboardManager;
int m_pressedIndex;
QPointF m_pressedMousePos;
QTimer* m_autoActivationTimer;
/**
* When starting a rubberband selection during a Shift- or Control-key has been
* pressed the current selection should never be deleted. To be able to restore
* the current selection it is remembered in m_oldSelection before the
* rubberband gets activated.
*/
KItemSet m_oldSelection;
/**
* Assuming a view is given with a vertical scroll-orientation, grouped items and
* a maximum of 4 columns:
*
* 1 2 3 4
* 5 6 7
* 8 9 10 11
* 12 13 14
*
* If the current index is on 4 and key-down is pressed, then item 7 gets the current
* item. Now when pressing key-down again item 11 should get the current item and not
* item 10. This makes it necessary to keep track of the requested column to have a
* similar behavior like in a text editor:
*/
int m_keyboardAnchorIndex;
qreal m_keyboardAnchorPos;
};
#endif
|