KDEUI
kwidgetitemdelegatepool.cpp
Go to the documentation of this file.00001
00022 #include "kwidgetitemdelegatepool_p.h"
00023
00024 #include <math.h>
00025
00026 #include <QtCore/qobjectdefs.h>
00027 #include <QtCore/QMetaObject>
00028 #include <QtCore/QMetaMethod>
00029 #include <QtCore/QMetaProperty>
00030 #include <QtCore/QPair>
00031 #include <QtCore/QHash>
00032 #include <QtCore/QList>
00033 #include <QtGui/QWidget>
00034 #include <QtGui/QAbstractItemView>
00035 #include <QtGui/QApplication>
00036 #include <QtGui/QInputEvent>
00037 #include <QtGui/QAbstractProxyModel>
00038
00039 #include "kwidgetitemdelegate.h"
00040 #include "kwidgetitemdelegate_p.h"
00041
00042 #define POOL_USAGE 0
00043
00048
00049 class EventListener
00050 : public QObject
00051 {
00052 public:
00053 EventListener(KWidgetItemDelegatePoolPrivate *poolPrivate, QObject *parent = 0)
00054 : QObject(parent)
00055 , poolPrivate(poolPrivate)
00056 {
00057 }
00058
00059 virtual bool eventFilter(QObject *watched, QEvent *event);
00060
00061 private:
00062 KWidgetItemDelegatePoolPrivate *poolPrivate;
00063 };
00064
00065 KWidgetItemDelegatePoolPrivate::KWidgetItemDelegatePoolPrivate(KWidgetItemDelegate *d)
00066 : delegate(d)
00067 , eventListener(new EventListener(this))
00068 {
00069 }
00070
00071 KWidgetItemDelegatePool::KWidgetItemDelegatePool(KWidgetItemDelegate *delegate)
00072 : d(new KWidgetItemDelegatePoolPrivate(delegate))
00073 {
00074 }
00075
00076 KWidgetItemDelegatePool::~KWidgetItemDelegatePool()
00077 {
00078 delete d->eventListener;
00079 delete d;
00080 }
00081
00082 QList<QWidget*> KWidgetItemDelegatePool::findWidgets(const QPersistentModelIndex &idx,
00083 const QStyleOptionViewItem &option,
00084 UpdateWidgetsEnum updateWidgets) const
00085 {
00086 QList<QWidget*> result;
00087
00088 if (!idx.isValid()) {
00089 return result;
00090 }
00091
00092 QModelIndex index;
00093 if (const QAbstractProxyModel *proxyModel = qobject_cast<const QAbstractProxyModel*>(idx.model())) {
00094 index = proxyModel->mapToSource(idx);
00095 } else {
00096 index = idx;
00097 }
00098
00099 if (!index.isValid()) {
00100 return result;
00101 }
00102
00103 if (d->usedWidgets.contains(index)) {
00104 result = d->usedWidgets[index];
00105 } else {
00106 result = d->delegate->createItemWidgets();
00107 d->allocatedWidgets << result;
00108 d->usedWidgets[index] = result;
00109 foreach (QWidget *widget, result) {
00110 d->widgetInIndex[widget] = index;
00111 widget->setParent(d->delegate->d->itemView->viewport());
00112 widget->installEventFilter(d->eventListener);
00113 widget->setVisible(true);
00114 }
00115 }
00116
00117 if (updateWidgets == UpdateWidgets) {
00118 foreach (QWidget *widget, result) {
00119 widget->setVisible(true);
00120 }
00121
00122 d->delegate->updateItemWidgets(result, option, idx);
00123
00124 foreach (QWidget *widget, result) {
00125 widget->move(widget->x() + option.rect.left(), widget->y() + option.rect.top());
00126 }
00127 }
00128
00129 return result;
00130 }
00131
00132 QList<QWidget*> KWidgetItemDelegatePool::invalidIndexesWidgets() const
00133 {
00134 QList<QWidget*> result;
00135 foreach (QWidget *widget, d->widgetInIndex.keys()) {
00136 const QAbstractProxyModel *proxyModel = qobject_cast<const QAbstractProxyModel*>(d->delegate->d->model);
00137 QModelIndex index;
00138 if (proxyModel) {
00139 index = proxyModel->mapFromSource(d->widgetInIndex[widget]);
00140 } else {
00141 index = d->widgetInIndex[widget];
00142 }
00143 if (!index.isValid()) {
00144 result << widget;
00145 }
00146 }
00147 return result;
00148 }
00149
00150 void KWidgetItemDelegatePool::fullClear()
00151 {
00152 qDeleteAll(d->widgetInIndex.keys());
00153 d->allocatedWidgets.clear();
00154 d->usedWidgets.clear();
00155 d->widgetInIndex.clear();
00156 }
00157
00158 bool EventListener::eventFilter(QObject *watched, QEvent *event)
00159 {
00160 QWidget *widget = static_cast<QWidget*>(watched);
00161 if (dynamic_cast<QInputEvent*>(event) && !poolPrivate->delegate->blockedEventTypes(widget).contains(event->type())) {
00162 QWidget *viewport = poolPrivate->delegate->d->itemView->viewport();
00163 switch(event->type()) {
00164 case QEvent::MouseMove:
00165 case QEvent::MouseButtonPress:
00166 case QEvent::MouseButtonRelease:
00167 case QEvent::MouseButtonDblClick: {
00168 QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
00169 QMouseEvent evt(event->type(), viewport->mapFromGlobal(mouseEvent->globalPos()),
00170 mouseEvent->button(), mouseEvent->buttons(), mouseEvent->modifiers());
00171 QApplication::sendEvent(viewport, &evt);
00172 }
00173 break;
00174 case QEvent::Wheel: {
00175 QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
00176 QWheelEvent evt(viewport->mapFromGlobal(wheelEvent->globalPos()),
00177 wheelEvent->delta(), wheelEvent->buttons(), wheelEvent->modifiers(),
00178 wheelEvent->orientation());
00179 QApplication::sendEvent(viewport, &evt);
00180 }
00181 break;
00182 case QEvent::TabletMove:
00183 case QEvent::TabletPress:
00184 case QEvent::TabletRelease:
00185 case QEvent::TabletEnterProximity:
00186 case QEvent::TabletLeaveProximity: {
00187 QTabletEvent *tabletEvent = static_cast<QTabletEvent*>(event);
00188 QTabletEvent evt(event->type(), viewport->mapFromGlobal(tabletEvent->globalPos()),
00189 tabletEvent->globalPos(), tabletEvent->hiResGlobalPos(), tabletEvent->device(),
00190 tabletEvent->pointerType(), tabletEvent->pressure(), tabletEvent->xTilt(),
00191 tabletEvent->yTilt(), tabletEvent->tangentialPressure(), tabletEvent->rotation(),
00192 tabletEvent->z(), tabletEvent->modifiers(), tabletEvent->uniqueId());
00193 QApplication::sendEvent(viewport, &evt);
00194 }
00195 break;
00196 default:
00197 QApplication::sendEvent(viewport, event);
00198 break;
00199 }
00200 }
00201
00202 return QObject::eventFilter(watched, event);
00203 }
00204