• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDEUI

kwidgetitemdelegate.cpp

Go to the documentation of this file.
00001 
00022 #include "kwidgetitemdelegate.h"
00023 #include "kwidgetitemdelegate_p.h"
00024 
00025 #include <QIcon>
00026 #include <QSize>
00027 #include <QStyle>
00028 #include <QEvent>
00029 #include <QHoverEvent>
00030 #include <QFocusEvent>
00031 #include <QCursor>
00032 #include <QTimer>
00033 #include <QBitmap>
00034 #include <QLayout>
00035 #include <QPainter>
00036 #include <QScrollBar>
00037 #include <QKeyEvent>
00038 #include <QApplication>
00039 #include <QStyleOption>
00040 #include <QPaintEngine>
00041 #include <QCoreApplication>
00042 #include <QAbstractItemView>
00043 #include <QAbstractProxyModel>
00044 
00045 #include "kwidgetitemdelegatepool_p.h"
00046 
00047 Q_DECLARE_METATYPE(QList<QEvent::Type>)
00048 
00049 
00053 //@cond PRIVATE
00054 KWidgetItemDelegatePrivate::KWidgetItemDelegatePrivate(KWidgetItemDelegate *q, QObject *parent)
00055     : QObject(parent)
00056     , itemView(0)
00057     , widgetPool(new KWidgetItemDelegatePool(q))
00058     , model(0)
00059     , q(q)
00060 {
00061 }
00062 
00063 KWidgetItemDelegatePrivate::~KWidgetItemDelegatePrivate()
00064 {
00065     delete widgetPool;
00066 }
00067 
00068 void KWidgetItemDelegatePrivate::_k_slotRowsInserted(const QModelIndex &parent, int start, int end)
00069 {
00070     updateRowRange(parent, start, end, false);
00071 }
00072 
00073 void KWidgetItemDelegatePrivate::_k_slotRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
00074 {
00075     updateRowRange(parent, start, end, true);
00076 }
00077 
00078 void KWidgetItemDelegatePrivate::_k_slotDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
00079 {
00080     for (int i = topLeft.row(); i <= bottomRight.row(); ++i) {
00081         for (int j = topLeft.column(); j <= bottomRight.column(); ++j) {
00082             const QModelIndex index = model->index(i, j, topLeft.parent());
00083             QStyleOptionViewItemV4 optionView;
00084             optionView.initFrom(itemView->viewport());
00085             optionView.rect = itemView->visualRect(index);
00086             widgetPool->findWidgets(index, optionView);
00087         }
00088     }
00089 }
00090 
00091 void KWidgetItemDelegatePrivate::_k_slotLayoutChanged()
00092 {
00093     foreach (QWidget *widget, widgetPool->invalidIndexesWidgets()) {
00094         widget->setVisible(false);
00095     }
00096     QTimer::singleShot(0, this, SLOT(initializeModel()));
00097 }
00098 
00099 void KWidgetItemDelegatePrivate::_k_slotModelReset()
00100 {
00101     widgetPool->fullClear();
00102     QTimer::singleShot(0, this, SLOT(initializeModel()));
00103 }
00104 
00105 void KWidgetItemDelegatePrivate::updateRowRange(const QModelIndex &parent, int start, int end, bool isRemoving)
00106 {
00107     int i = start;
00108     while (i <= end) {
00109         for (int j = 0; j < model->columnCount(parent); ++j) {
00110             const QModelIndex index = model->index(i, j, parent);
00111             QStyleOptionViewItemV4 optionView;
00112             optionView.initFrom(itemView->viewport());
00113             optionView.rect = itemView->visualRect(index);
00114 
00115             QList<QWidget*> widgetList = widgetPool->findWidgets(index, optionView, isRemoving ? KWidgetItemDelegatePool::NotUpdateWidgets
00116                                                                                                : KWidgetItemDelegatePool::UpdateWidgets);
00117             if (isRemoving) {
00118                 widgetPool->d->allocatedWidgets.removeAll(widgetList);
00119                 foreach (QWidget *widget, widgetList) {
00120                     const QModelIndex idx = widgetPool->d->widgetInIndex[widget];
00121                     widgetPool->d->usedWidgets.remove(idx);
00122                     widgetPool->d->widgetInIndex.remove(widget);
00123                     delete widget;
00124                 }
00125             }
00126         }
00127         i++;
00128     }
00129 }
00130 
00131 void KWidgetItemDelegatePrivate::initializeModel(const QModelIndex &parent)
00132 {
00133     for (int i = 0; i < model->rowCount(parent); ++i) {
00134         for (int j = 0; j < model->columnCount(parent); ++j) {
00135             const QModelIndex index = model->index(i, j, parent);
00136             if (index.isValid()) {
00137                 QStyleOptionViewItemV4 optionView;
00138                 optionView.initFrom(itemView->viewport());
00139                 optionView.rect = itemView->visualRect(index);
00140                 widgetPool->findWidgets(index, optionView);
00141             }
00142         }
00143         // Check if we need to go recursively through the children of parent (if any) to initialize
00144         // all possible indexes that are shown.
00145         const QModelIndex index = model->index(i, 0, parent);
00146         if (index.isValid() && model->hasChildren(index)) {
00147             initializeModel(index);
00148         }
00149     }
00150 }
00151 //@endcond
00152 
00153 KWidgetItemDelegate::KWidgetItemDelegate(QAbstractItemView *itemView, QObject *parent)
00154     : QAbstractItemDelegate(parent)
00155     , d(new KWidgetItemDelegatePrivate(this))
00156 {
00157     Q_ASSERT(itemView);
00158 
00159     itemView->setMouseTracking(true);
00160     itemView->viewport()->setAttribute(Qt::WA_Hover);
00161 
00162     d->itemView = itemView;
00163 
00164     itemView->viewport()->installEventFilter(d); // mouse events
00165     itemView->installEventFilter(d);             // keyboard events
00166 }
00167 
00168 KWidgetItemDelegate::~KWidgetItemDelegate()
00169 {
00170     delete d;
00171 }
00172 
00173 QAbstractItemView *KWidgetItemDelegate::itemView() const
00174 {
00175     return d->itemView;
00176 }
00177 
00178 QPersistentModelIndex KWidgetItemDelegate::focusedIndex() const
00179 {
00180     const QPersistentModelIndex idx = d->widgetPool->d->widgetInIndex.value(QApplication::focusWidget());
00181     if (idx.isValid()) {
00182         return idx;
00183     }
00184     // Use the mouse position, if the widget refused to take keyboard focus.
00185     const QPoint pos = d->itemView->viewport()->mapFromGlobal(QCursor::pos());
00186     return d->itemView->indexAt(pos);
00187 }
00188 
00189 void KWidgetItemDelegate::paintWidgets(QPainter *painter, const QStyleOptionViewItem &option,
00190                                        const QPersistentModelIndex &index) const
00191 {
00192     Q_UNUSED(painter);
00193     Q_UNUSED(option);
00194     Q_UNUSED(index);
00195 }
00196 
00197 //@cond PRIVATE
00198 bool KWidgetItemDelegatePrivate::eventFilter(QObject *watched, QEvent *event)
00199 {
00200     if (event->type() == QEvent::Destroy) {
00201         return false;
00202     }
00203 
00204     Q_UNUSED(watched);
00205     Q_ASSERT(itemView);
00206 
00207     if (model != itemView->model()) {
00208         if (model) {
00209             disconnect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), q, SLOT(_k_slotRowsInserted(QModelIndex,int,int)));
00210             disconnect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), q, SLOT(_k_slotRowsAboutToBeRemoved(QModelIndex,int,int)));
00211             disconnect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), q, SLOT(_k_slotDataChanged(QModelIndex,QModelIndex)));
00212             disconnect(model, SIGNAL(layoutChanged()), q, SLOT(_k_slotLayoutChanged()));
00213             disconnect(model, SIGNAL(modelReset()), q, SLOT(_k_slotModelReset()));
00214         }
00215         model = itemView->model();
00216         connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), q, SLOT(_k_slotRowsInserted(QModelIndex,int,int)));
00217         connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), q, SLOT(_k_slotRowsAboutToBeRemoved(QModelIndex,int,int)));
00218         connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), q, SLOT(_k_slotDataChanged(QModelIndex,QModelIndex)));
00219         connect(model, SIGNAL(layoutChanged()), q, SLOT(_k_slotLayoutChanged()));
00220         connect(model, SIGNAL(modelReset()), q, SLOT(_k_slotModelReset()));
00221         QTimer::singleShot(0, this, SLOT(initializeModel()));
00222     }
00223 
00224     switch (event->type()) {
00225         case QEvent::Polish:
00226         case QEvent::Resize:
00227             if (!qobject_cast<QAbstractItemView*>(watched)) {
00228                 QTimer::singleShot(0, this, SLOT(initializeModel()));
00229             }
00230             break;
00231         default:
00232             break;
00233     }
00234 
00235     return QObject::eventFilter(watched, event);
00236 }
00237 //@endcond
00238 
00239 void KWidgetItemDelegate::setBlockedEventTypes(QWidget *widget, QList<QEvent::Type> types) const
00240 {
00241     widget->setProperty("goya:blockedEventTypes", qVariantFromValue(types));
00242 }
00243 
00244 QList<QEvent::Type> KWidgetItemDelegate::blockedEventTypes(QWidget *widget) const
00245 {
00246     return widget->property("goya:blockedEventTypes").value<QList<QEvent::Type> >();
00247 }
00248 
00249 #include "kwidgetitemdelegate.moc"
00250 #include "kwidgetitemdelegate_p.moc"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal