22 #include "entitytreeview.h" 24 #include "dragdropmanager_p.h" 26 #include <QtCore/QDebug> 27 #include <QtCore/QTimer> 28 #include <QApplication> 29 #include <QDragMoveEvent> 30 #include <QHeaderView> 33 #include <akonadi/collection.h> 34 #include <akonadi/control.h> 35 #include <akonadi/item.h> 36 #include <akonadi/entitytreemodel.h> 39 #include <kxmlguiclient.h> 40 #include <KXMLGUIFactory> 42 #include "progressspinnerdelegate_p.h" 49 class EntityTreeView::Private
54 #ifndef QT_NO_DRAGANDDROP
55 , mDragDropManager(new DragDropManager(mParent))
58 , mDefaultPopupMenu(QLatin1String(
"akonadi_collectionview_contextmenu"))
63 void itemClicked(
const QModelIndex &index);
64 void itemDoubleClicked(
const QModelIndex &index);
65 void itemCurrentChanged(
const QModelIndex &index);
67 void slotSelectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected);
70 QBasicTimer mDragExpandTimer;
71 DragDropManager *mDragDropManager;
72 KXMLGUIClient *mXmlGuiClient;
73 QString mDefaultPopupMenu;
76 void EntityTreeView::Private::init()
78 Akonadi::DelegateAnimator *animator =
new Akonadi::DelegateAnimator(mParent);
79 Akonadi::ProgressSpinnerDelegate *customDelegate =
new Akonadi::ProgressSpinnerDelegate(animator, mParent);
80 mParent->setItemDelegate(customDelegate);
82 mParent->header()->setClickable(
true);
83 mParent->header()->setStretchLastSection(
false);
92 mParent->setSortingEnabled(
true);
93 mParent->sortByColumn(0, Qt::AscendingOrder);
94 mParent->setEditTriggers(QAbstractItemView::EditKeyPressed);
95 mParent->setAcceptDrops(
true);
96 #ifndef QT_NO_DRAGANDDROP 97 mParent->setDropIndicatorShown(
true);
98 mParent->setDragDropMode(DragDrop);
99 mParent->setDragEnabled(
true);
102 mParent->connect(mParent, SIGNAL(clicked(QModelIndex)),
103 mParent, SLOT(itemClicked(QModelIndex)));
104 mParent->connect(mParent, SIGNAL(doubleClicked(QModelIndex)),
105 mParent, SLOT(itemDoubleClicked(QModelIndex)));
110 void EntityTreeView::Private::slotSelectionChanged(
const QItemSelection &selected,
const QItemSelection &)
112 const int column = 0;
113 foreach (
const QItemSelectionRange &range, selected) {
114 const QModelIndex index = range.topLeft();
116 if (index.column() > 0) {
120 for (
int row = index.row(); row <= range.bottomRight().row(); ++row) {
123 mParent->model()->fetchMore(index.sibling(row, column));
127 if (selected.size() == 1) {
128 const QItemSelectionRange &range = selected.first();
129 if (range.topLeft().row() == range.bottomRight().row()) {
130 mParent->scrollTo(range.topLeft(), QTreeView::EnsureVisible);
135 void EntityTreeView::Private::itemClicked(
const QModelIndex &index)
137 if (!index.isValid()) {
140 QModelIndex idx = index.sibling(index.row(), 0);
143 if (collection.isValid()) {
144 emit mParent->clicked(collection);
147 if (item.isValid()) {
148 emit mParent->clicked(item);
153 void EntityTreeView::Private::itemDoubleClicked(
const QModelIndex &index)
155 if (!index.isValid()) {
158 QModelIndex idx = index.sibling(index.row(), 0);
160 if (collection.isValid()) {
161 emit mParent->doubleClicked(collection);
164 if (item.isValid()) {
165 emit mParent->doubleClicked(item);
170 void EntityTreeView::Private::itemCurrentChanged(
const QModelIndex &index)
172 if (!index.isValid()) {
175 QModelIndex idx = index.sibling(index.row(), 0);
177 if (collection.isValid()) {
178 emit mParent->currentChanged(collection);
181 if (item.isValid()) {
182 emit mParent->currentChanged(item);
189 , d(new Private(this))
191 setSelectionMode(QAbstractItemView::SingleSelection);
197 , d(new Private(this))
205 delete d->mDragDropManager;
211 if (selectionModel()) {
212 disconnect(selectionModel(), SIGNAL(
currentChanged(QModelIndex,QModelIndex)),
213 this, SLOT(itemCurrentChanged(QModelIndex)));
215 disconnect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
216 this, SLOT(slotSelectionChanged(QItemSelection,QItemSelection)));
219 QTreeView::setModel(model);
220 header()->setStretchLastSection(
true);
222 connect(selectionModel(), SIGNAL(
currentChanged(QModelIndex,QModelIndex)),
223 SLOT(itemCurrentChanged(QModelIndex)));
225 connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
226 SLOT(slotSelectionChanged(QItemSelection,QItemSelection)));
229 void EntityTreeView::timerEvent(QTimerEvent *event)
231 if (event->timerId() == d->mDragExpandTimer.timerId()) {
232 const QPoint pos = viewport()->mapFromGlobal(QCursor::pos());
233 if (state() == QAbstractItemView::DraggingState && viewport()->rect().contains(pos)) {
234 setExpanded(indexAt(pos),
true);
238 QTreeView::timerEvent(event);
241 #ifndef QT_NO_DRAGANDDROP 242 void EntityTreeView::dragMoveEvent(QDragMoveEvent *event)
244 d->mDragExpandTimer.start(QApplication::startDragTime() ,
this);
246 if (d->mDragDropManager->dropAllowed(event)) {
248 QTreeView::dragMoveEvent(event);
252 event->setDropAction(Qt::IgnoreAction);
255 void EntityTreeView::dropEvent(QDropEvent *event)
257 d->mDragExpandTimer.stop();
258 bool menuCanceled =
false;
259 if (d->mDragDropManager->processDropEvent(event, menuCanceled, (dropIndicatorPosition() == QAbstractItemView::OnItem))) {
260 QTreeView::dropEvent(event);
265 #ifndef QT_NO_CONTEXTMENU 266 void EntityTreeView::contextMenuEvent(QContextMenuEvent *event)
268 if (!d->mXmlGuiClient || !model()) {
272 const QModelIndex index = indexAt(event->pos());
273 QString popupName = d->mDefaultPopupMenu;
275 if (index.isValid()) {
278 popupName = (item.isValid() ? QLatin1String(
"akonadi_itemview_contextmenu") :
279 QLatin1String(
"akonadi_collectionview_contextmenu"));
282 QMenu *popup = static_cast<QMenu *>(d->mXmlGuiClient->factory()->container(popupName, d->mXmlGuiClient));
284 popup->exec(event->globalPos());
296 return d->mXmlGuiClient;
299 #ifndef QT_NO_DRAGANDDROP 300 void EntityTreeView::startDrag(Qt::DropActions supportedActions)
302 d->mDragDropManager->startDrag(supportedActions);
308 #ifndef QT_NO_DRAGANDDROP 309 d->mDragDropManager->setShowDropActionMenu(enabled);
315 #ifndef QT_NO_DRAGANDDROP 316 return d->mDragDropManager->showDropActionMenu();
324 #ifndef QT_NO_DRAGANDDROP 325 d->mDragDropManager->setManualSortingActive(active);
331 #ifndef QT_NO_DRAGANDDROP 332 return d->mDragDropManager->isManualSortingActive();
340 d->mDefaultPopupMenu = name;
343 #include "moc_entitytreeview.cpp" virtual ~EntityTreeView()
Destroys the entity tree view.
void setDefaultPopupMenu(const QString &name)
Set the name of the default popup menu (retrieved from the application's XMLGUI file).
Represents a collection of PIM items.
bool isManualSortingActive() const
Return true if we use an manual sorting Necessary to fix dnd menu We must show just move when we move...
void setManualSortingActive(bool active)
Set true if we automatic sorting.
A view to show an item/collection tree provided by an EntityTreeModel.
static void widgetNeedsAkonadi(QWidget *widget)
Disable the given widget when Akonadi is not operational and show an error overlay (given enough spac...
bool isDropActionMenuEnabled() const
Returns whether the drop action menu is enabled and will be shown on drop operation.
void setDropActionMenuEnabled(bool enabled)
Sets whether the drop action menu is enabled and will be shown on drop operation.
EntityTreeView(QWidget *parent=0)
Creates a new entity tree view.
KXMLGUIClient * xmlGuiClient() const
Return the XML GUI client which the view is used in.
FreeBusyManager::Singleton.
virtual void setModel(QAbstractItemModel *model)
void setXmlGuiClient(KXMLGUIClient *xmlGuiClient)
Sets the XML GUI client which the view is used in.
void currentChanged(const Akonadi::Collection &collection)
This signal is emitted whenever the current collection in the view has changed.