diff options
author | Marius Bugge Monsen <mmonsen@trolltech.com> | 2009-07-28 20:03:49 +1000 |
---|---|---|
committer | Marius Bugge Monsen <mmonsen@trolltech.com> | 2009-07-28 20:03:49 +1000 |
commit | a5d037c51ccbaa3f2a71bd39db187414bd1c78fe (patch) | |
tree | 3dcf216e6a39b42c7a9921ab4c5acc2ea3fb6cad | |
parent | 65c6c19398cbf5f5a08e3b612e60f1a4d632e9f1 (diff) |
Update QGraphicsListView to be able to use QmlComponent for creating view items.
19 files changed, 372 insertions, 292 deletions
diff --git a/src/experimental/qgraphicsgridview.cpp b/src/experimental/qgraphicsgridview.cpp index c95813e..b8375c3 100644 --- a/src/experimental/qgraphicsgridview.cpp +++ b/src/experimental/qgraphicsgridview.cpp @@ -360,24 +360,25 @@ void QtGraphicsGridView::doLayout() d->scrollItems(firstVisibleIndex); int index = firstVisibleIndex; for (; index <= lastVisibleIndex; ++index) { - initStyleOption(&option, index); + //initStyleOption(&option, index); const int i = index - firstVisibleIndex; if (i >= d->items.count()) - d->items.append(d->creator->create(index, this)); - QtGraphicsListViewItem *item = d->items.at(i); + d->items.append(QPair<int,QGraphicsObject*>(index, d->creator->create(index, this))); + QGraphicsObject *item = d->items.at(i).second; const QPointF pos = d->gridPosition(index); - const QSizeF size = item->sizeHint(index, &option, Qt::PreferredSize, QSizeF(gridSize, gridSize)); + const QSizeF size = item->boundingRect().size(); const QRectF grid(pos.x(), pos.y(), gridSize, gridSize); const QRectF aligned = QStyle::alignedRect(option.direction, Qt::AlignCenter, size.toSize(), grid.toRect()); - item->setGeometry(aligned); + //item->setGeometry(aligned); + item->setPos(aligned.topLeft());//### FIXME } // remove unused items const int from = index - firstVisibleIndex; while (from < d->items.count()) - d->creator->recycle(d->items.takeLast()); + d->creator->recycle(d->items.takeLast().second); } /*! @@ -427,13 +428,14 @@ void QtGraphicsGridView::initStyleOption(QStyleOptionViewItemV4 *option) const /*! \reimp */ +/* void QtGraphicsGridView::initStyleOption(QStyleOptionViewItemV4 *option, int index) const { QtGraphicsListView::initStyleOption(option, index); option->state &= ~QStyle::State_HasFocus; option->state &= ~QStyle::State_Selected; } - +*/ QT_END_NAMESPACE #include "moc_qgraphicsgridview.cpp" diff --git a/src/experimental/qgraphicsgridview.h b/src/experimental/qgraphicsgridview.h index 48a02f2..a00dd0c 100644 --- a/src/experimental/qgraphicsgridview.h +++ b/src/experimental/qgraphicsgridview.h @@ -53,7 +53,7 @@ public: virtual QRectF itemGeometry(int index) const; virtual int itemAt(const QPointF &position) const; virtual void initStyleOption(QStyleOptionViewItemV4 *option) const; - virtual void initStyleOption(QStyleOptionViewItemV4 *option, int index) const; + //virtual void initStyleOption(QStyleOptionViewItemV4 *option, int index) const; protected: QtGraphicsGridView(QtGraphicsGridViewPrivate &, Qt::Orientation orientation, QGraphicsWidget *parent, Qt::WindowFlags wFlags = 0); diff --git a/src/experimental/qgraphicspathview.cpp b/src/experimental/qgraphicspathview.cpp index ed1876c..a20f8d5 100644 --- a/src/experimental/qgraphicspathview.cpp +++ b/src/experimental/qgraphicspathview.cpp @@ -165,9 +165,9 @@ void QtGraphicsPathView::doLayout() qreal progress = /*animationProgress()*/1 - (running && forward ? 1 : 0); while (!path.isEmpty() && counter < count) { - initStyleOption(&option, index); + //initStyleOption(&option, index); qreal c = qreal(counter) + progress; - QSizeF size = d->itemSizeHint(&option, index); + QSizeF size = d->itemSize(index); //qreal scale = (qreal(count - qAbs(c - (count / 2))) / qreal(count)); qreal t = qBound(qreal(0), c / qreal(count), qreal(1)); QPointF pos = path.pointAtPercent(t); @@ -176,15 +176,16 @@ void QtGraphicsPathView::doLayout() pos += boundingRect.topLeft(); // ### FIXME: look up and recycle the items - QtGraphicsListViewItem *item = 0; + QGraphicsObject *item = 0; if (counter >= d->items.count()) { item = d->creator->create(index, this); - d->items.append(item); + d->items.append(QPair<int,QGraphicsObject*>(index, item)); } else { - item = d->items.at(counter); - item->setIndex(index); // ### + item = d->items.at(counter).second; + d->creator->reassign(index, item, this); + //item->setIndex(index); // ### } - item->setGeometry(QRectF(pos, size)); + item->setPos(pos); ++index; if (index >= count) // loop diff --git a/src/experimental/qkineticlistcontroller.cpp b/src/experimental/qkineticlistcontroller.cpp index 8935d95..5fca8b5 100644 --- a/src/experimental/qkineticlistcontroller.cpp +++ b/src/experimental/qkineticlistcontroller.cpp @@ -95,15 +95,12 @@ bool QtKineticListControllerPrivate::kineticUpdateOffset(qreal *offset, qreal ma const QSizeF viewSize = view->size(); const QPointF viewCenter(viewSize.width() / 2, viewSize.height() / 2); const int centerIndex = view->itemAt(viewCenter); - // ### this should be done in the view - get item geometry - if (QtGraphicsListViewItem *centerItem = view->itemForIndex(centerIndex)) { - const QPointF itemCenter = centerItem->geometry().center(); - const QPointF delta = viewCenter - itemCenter; - if (view->orientation() == Qt::Horizontal) - scrollVelocity += l * delta.x(); - else - scrollVelocity += l * delta.y(); - } + const QPointF itemCenter = view->itemGeometry(centerIndex).center(); + const QPointF delta = viewCenter - itemCenter; + if (view->orientation() == Qt::Horizontal) + scrollVelocity += l * delta.x(); + else + scrollVelocity += l * delta.y(); scrollVelocity *= frictionFactor; return true; } diff --git a/src/qprinterlistview.cpp b/src/experimental/qprinterlistview.cpp index 689d9fb..689d9fb 100644 --- a/src/qprinterlistview.cpp +++ b/src/experimental/qprinterlistview.cpp diff --git a/src/qprinterlistview.h b/src/experimental/qprinterlistview.h index 99d0c96..99d0c96 100644 --- a/src/qprinterlistview.h +++ b/src/experimental/qprinterlistview.h diff --git a/src/qprinterlistview_p.h b/src/experimental/qprinterlistview_p.h index 31ae385..31ae385 100644 --- a/src/qprinterlistview_p.h +++ b/src/experimental/qprinterlistview_p.h diff --git a/src/qprintertableview.cpp b/src/experimental/qprintertableview.cpp index aa3fefb..aa3fefb 100644 --- a/src/qprintertableview.cpp +++ b/src/experimental/qprintertableview.cpp diff --git a/src/qprintertableview.h b/src/experimental/qprintertableview.h index be08ca6..be08ca6 100644 --- a/src/qprintertableview.h +++ b/src/experimental/qprintertableview.h diff --git a/src/qprintertableview_p.h b/src/experimental/qprintertableview_p.h index f2927c2..f2927c2 100644 --- a/src/qprintertableview_p.h +++ b/src/experimental/qprintertableview_p.h diff --git a/src/qdataroles_p.h b/src/qdataroles_p.h index e71c650..6eb8f5a 100644 --- a/src/qdataroles_p.h +++ b/src/qdataroles_p.h @@ -36,16 +36,52 @@ // #include <qmetaobject.h> +#include <qdebug.h> QT_BEGIN_NAMESPACE -struct QtDataRoles : private QObject +class QtDataRoles : private QObject { - static QHash<int, QString> roles() { - QHash<int,QString> roles; - const QMetaObject &staticMetaObject = static_cast<QtDataRoles*>(0)->staticQtMetaObject; - const int index = staticMetaObject.indexOfEnumerator("DataRoles"); - const QMetaEnum metaEnum = staticMetaObject.enumerator(index); + Q_OBJECT + Q_ENUMS(ItemDataRole) +public: + enum ItemDataRole { + DisplayRole = 0, + DecorationRole = 1, + EditRole = 2, + ToolTipRole = 3, + StatusTipRole = 4, + WhatsThisRole = 5, + // Metadata + FontRole = 6, + TextAlignmentRole = 7, + BackgroundColorRole = 8, + BackgroundRole = 8, + TextColorRole = 9, + ForegroundRole = 9, + CheckStateRole = 10, + // Accessibility + AccessibleTextRole = 11, + AccessibleDescriptionRole = 12, + // More general purpose + SizeHintRole = 13, + // Internal UiLib roles. Start worrying when public roles go that high. + DisplayPropertyRole = 27, + DecorationPropertyRole = 28, + ToolTipPropertyRole = 29, + StatusTipPropertyRole = 30, + WhatsThisPropertyRole = 31, + // Reserved + UserRole = 32 + }; + + static QHash<int, QByteArray> roles() { + QHash<int,QByteArray> roles; + const QMetaObject &metaObject = QtDataRoles().staticMetaObject;//static_cast<QtDataRoles*>(0)->staticQtMetaObject; + const int index = metaObject.indexOfEnumerator("ItemDataRole"); + if (index == -1) + qWarning() << "QtDataRoles: could not find ItemDataRoles enumerator"; + const QMetaEnum metaEnum = metaObject.enumerator(index); for (int i = 0; i < metaEnum.keyCount(); ++i) roles.insert(metaEnum.value(i), metaEnum.key(i)); return roles; diff --git a/src/qgraphicslistview.cpp b/src/qgraphicslistview.cpp index 85dd752..70d3ec6 100644 --- a/src/qgraphicslistview.cpp +++ b/src/qgraphicslistview.cpp @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE alter the individual list items appearance, for example; <ul> <li>Reimplement paint() to change the look for just this list.</li> - <li>Add any number of child QGraphicsItem objects that do the painting instead.</li> + <li>Add any number of child QGraphicsObject instances that do the painting instead.</li> <!-- we will have to refer to the kinetic items when they are done --> </ul> @@ -70,8 +70,8 @@ QtGraphicsListViewItem::QtGraphicsListViewItem(int index, QtGraphicsListView *vi : QGraphicsWidget(view, 0), d_ptr(new QtGraphicsListViewItemPrivate) { Q_D(QtGraphicsListViewItem); - Q_ASSERT(view); - setCacheMode(QGraphicsItem::ItemCoordinateCache); + setCacheMode(QGraphicsObject::ItemCoordinateCache); + setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); d->q_ptr = this; d->view = view; d->index = index; @@ -111,36 +111,38 @@ void QtGraphicsListViewItem::setIndex(int index) /*! \reimp */ -QSizeF QtGraphicsListViewItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const + +QRectF QtGraphicsListViewItem::boundingRect() const { - Q_D(const QtGraphicsListViewItem); - d->view->initStyleOption(&d->option); - d->view->initStyleOption(&d->option, d->index); - return sizeHint(d->index, &d->option, which, constraint); + return QRectF(QPointF(), geometry().size()); } /*! - Returns \a which size hint for the item indicated by the given \a index, - using the given \a option and \a constrainst. + \reimp */ -QSizeF QtGraphicsListViewItem::sizeHint(int index, const QStyleOptionViewItemV4 *option, Qt::SizeHint which, const QSizeF &constraint) const +QSizeF QtGraphicsListViewItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const { Q_D(const QtGraphicsListViewItem); - switch (which) { - case Qt::MinimumSize: - case Qt::PreferredSize: { - const QVariant value = d->view->d_func()->cachedData(index, Qt::SizeHintRole); - if (value.isValid()) - return qvariant_cast<QSizeF>(value); - else - return d->view->style()->sizeFromContents(QStyle::CT_ItemViewItem, option, QSize(), option->widget); - } - case Qt::MaximumSize: - return QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); - default: - break; + Q_UNUSED(constraint); + if (d->view) { + d->view->initStyleOption(&d->option); + initStyleOption(&d->option); + switch (which) { + case Qt::MinimumSize: + case Qt::PreferredSize: { + const QVariant value = d->view->d_func()->cachedData(d->index, Qt::SizeHintRole); + if (value.isValid()) + return qvariant_cast<QSizeF>(value); + else + return d->view->style()->sizeFromContents(QStyle::CT_ItemViewItem, &d->option, QSize(), d->option.widget); + } + case Qt::MaximumSize: + return QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + default: + break; + } } - return QGraphicsWidget::sizeHint(which, constraint); + return QSizeF(); } /*! @@ -151,11 +153,13 @@ void QtGraphicsListViewItem::paint(QPainter *painter, const QStyleOptionGraphics Q_D(QtGraphicsListViewItem); // ### this code is less than optimal, but we will hopefully get rid of the style calls // ### by moving to a purely scene-graph based approach for items - d->view->copyStyleOptionState(option, &d->option); - d->view->initStyleOption(&d->option); - d->view->initStyleOption(&d->option, d->index); - d->option.rect = rect().toRect(); - d->view->style()->drawControl(QStyle::CE_ItemViewItem, &d->option, painter, widget); + if (d->view) { + copyStyleOptionState(option, &d->option); + d->view->initStyleOption(&d->option); + initStyleOption(&d->option); + d->option.rect = boundingRect().toRect(); + d->view->style()->drawControl(QStyle::CE_ItemViewItem, &d->option, painter, widget); + } } /*! @@ -187,6 +191,128 @@ QHash<int, QVariant> QtGraphicsListViewItem::data(const QList<int> &roles) const } /*! + Initialize the given \a option with the settings and data + specific for the item at the given \a index. + */ +void QtGraphicsListViewItem::initStyleOption(QStyleOptionViewItemV4 *option) const +{ + Q_D(const QtGraphicsListViewItem); + Q_ASSERT(option); + + if (!d->view) + return; + + if (d->view->selectionManager()) { + // Current Item + if (d->view->selectionManager()->currentItem() == d->index) + option->state |= QStyle::State_HasFocus; + else + option->state &= ~QStyle::State_HasFocus; + // selectionManager + if (d->view->selectionManager()->isSelected(d->index)) + option->state |= QStyle::State_Selected; + else + option->state &= ~QStyle::State_Selected; + } + + // Data + QVariant value; + + // FontRole + value = d->view->cachedData(d->index, Qt::FontRole); + if (value.isValid()) { + option->font = qvariant_cast<QFont>(value).resolve(option->font); + option->fontMetrics = QFontMetrics(option->font); + } + + // TextAlignmentRole + value = d->view->cachedData(d->index, Qt::TextAlignmentRole); + if (value.isValid()) + option->displayAlignment = (Qt::Alignment)value.toInt(); + + // ForegroundRole + value = d->view->cachedData(d->index, Qt::ForegroundRole); + if (qVariantCanConvert<QBrush>(value)) + option->palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value)); + + // CheckStateRole + value = d->view->cachedData(d->index, Qt::CheckStateRole); + if (value.isValid()) { + option->features |= QStyleOptionViewItemV2::HasCheckIndicator; + option->checkState = static_cast<Qt::CheckState>(value.toInt()); + } + + // DecorationRole + value = d->view->cachedData(d->index, Qt::DecorationRole); + if (value.isValid()) { + option->features |= QStyleOptionViewItemV2::HasDecoration; + switch (value.type()) { + case QVariant::Icon: + option->icon = qvariant_cast<QIcon>(value); + break; + case QVariant::Color: { + QPixmap pixmap(option->decorationSize); + pixmap.fill(qvariant_cast<QColor>(value)); + option->icon = QIcon(pixmap); } + default: + break; + } + } + + // DisplayRole + value = d->view->cachedData(d->index, Qt::DisplayRole); + if (value.isValid()) { + option->features |= QStyleOptionViewItemV2::HasDisplay; + switch (value.type()) { + case QVariant::Double: + option->text = option->locale.toString(value.toDouble()); + break; + case QVariant::Int: + case QVariant::LongLong: + option->text = option->locale.toString(value.toLongLong()); + break; + case QVariant::UInt: + case QVariant::ULongLong: + option->text = option->locale.toString(value.toULongLong()); + break; + case QVariant::Date: + option->text = option->locale.toString(value.toDate(), QLocale::ShortFormat); + break; + case QVariant::Time: + option->text = option->locale.toString(value.toTime(), QLocale::ShortFormat); + break; + case QVariant::DateTime: + option->text = option->locale.toString(value.toDateTime().date(), QLocale::ShortFormat); + option->text += QLatin1Char(' '); + option->text += option->locale.toString(value.toDateTime().time(), QLocale::ShortFormat); + break; + default: { + QString text = value.toString(); + for (int i = 0; i < text.count(); ++i) + if (text.at(i).unicode() == '\n') + text[i] = QChar::LineSeparator; + option->text = text; + break; } + } + } +} + +/*! + Copies style option state information from the + given \a source to the given \a destination + */ +void QtGraphicsListViewItem::copyStyleOptionState(const QStyleOptionGraphicsItem *source, QStyleOptionViewItemV4 *destination) +{ + if (source && destination) { + destination->state = source->state; + destination->direction = source->direction; + destination->rect = source->rect; + destination->fontMetrics = source->fontMetrics; + destination->palette = source->palette; + } +} + +/*! Returns the view where this item is shown. */ QtGraphicsListView *QtGraphicsListViewItem::view() const @@ -219,17 +345,18 @@ QtGraphicsListViewItemCreatorBase::~QtGraphicsListViewItemCreatorBase() /*! This method basically does a recycle and a create in one go. */ -QtGraphicsListViewItem *QtGraphicsListViewItemCreatorBase::reassign(int index, QtGraphicsListViewItem *item) +QGraphicsObject *QtGraphicsListViewItemCreatorBase::reassign(int index, QGraphicsObject *item, QtGraphicsListView *view) { + Q_UNUSED(view); Q_ASSERT(item); - item->setIndex(index); + static_cast<QtGraphicsListViewItem*>(item)->setIndex(index); return item; } /*! Give back the \a item to the creator pool of unused objects. */ -void QtGraphicsListViewItemCreatorBase::recycle(QtGraphicsListViewItem *item) +void QtGraphicsListViewItemCreatorBase::recycle(QGraphicsObject *item) { delete item; } @@ -300,14 +427,14 @@ void QtGraphicsListViewPrivate::_q_itemsChanged(int index, int count, const QLis checkCache(index, count); //qDebug() << "QtGraphicsListViewPrivate::_q_itemsChanged" << index << count; for (int i = 0; i < items.count(); ++i) { - QtGraphicsListViewItem *item = items.at(i); - int itemIndex = item->index(); + QGraphicsObject *item = items.at(i).second; + int itemIndex = items.at(i).first; if (itemIndex >= index + count) // change happened above break; - //if (itemIndex < index + viewItems.count()) - // break; // change happened below - if (itemIndex >= index) - item->itemChanged(roles); + //if (itemIndex >= index && item->isWidget()) + // item->itemChanged(roles); + Q_UNUSED(roles); + item->update(); // ### } q->updateLayout(); // ### FIXME: be more discriminate } @@ -353,14 +480,14 @@ void QtGraphicsListViewPrivate::_q_selectionsChanged(const QtListSelectionChange { if (items.isEmpty()) return; - const int from = items.first()->index(); - const int to = items.last()->index(); + const int from = items.first().first; + const int to = items.last().first; if (from <= change.index() && (change.index() + change.count() - 1) <= to) { - const QList<int> indexes = change.indexes(); - for (int i = 0; i < indexes.count(); ++i) { - const int index = indexes.at(i); + const QList<int> changeIndexes = change.indexes(); + for (int i = 0; i < changeIndexes.count(); ++i) { + const int index = changeIndexes.at(i); if (from <= index && index <= to) - items.at(index - from)->update(); + items.at(index - from).second->update(); } } } @@ -370,13 +497,15 @@ void QtGraphicsListViewPrivate::_q_selectionsChanged(const QtListSelectionChange */ void QtGraphicsListViewPrivate::_q_currentChanged(int current, int previous) { + if (items.isEmpty()) + return; //qDebug() << "QtGraphicsListViewPrivate::_q_currentChanged" << current << previous; - const int from = items.first()->index(); - const int to = items.last()->index(); + const int from = items.first().first; + const int to = items.last().first; if (from <= current && current <= to) - items.at(current - from)->update(); + items.at(current - from).second->update(); if (from <= previous && previous <= to) - items.at(current - from)->update(); + items.at(current - from).second->update(); } /*! @@ -439,18 +568,21 @@ int QtGraphicsListViewPrivate::currentItem() const */ void QtGraphicsListViewPrivate::scrollItems(int firstVisibleIndex) { + Q_Q(QtGraphicsListView); // shift items around if (!items.isEmpty()) { // scrolling down or right - move from first to last - while (items.first()->index() < firstVisibleIndex) { - const int index = items.last()->index() + 1; - items.append(creator->reassign(index, items.takeFirst())); + while (items.first().first < firstVisibleIndex) { + const int index = items.last().first + 1; + QPair<int,QGraphicsObject*> item = items.takeFirst(); + items.append(QPair<int,QGraphicsObject*>(index, creator->reassign(index, item.second, q))); } // scrolling up or left - move from last to first (assuming same view size) const int firstNonVisibleIndex = firstVisibleIndex + items.count(); - while (items.last()->index() >= firstNonVisibleIndex) { - const int index = items.first()->index() - 1; - items.prepend(creator->reassign(index, items.takeLast())); + while (items.last().first >= firstNonVisibleIndex) { + const int index = items.first().first - 1; + QPair<int,QGraphicsObject*> item = items.takeLast(); + items.prepend(QPair<int,QGraphicsObject*>(index, creator->reassign(index, item.second, q))); } } } @@ -458,9 +590,28 @@ void QtGraphicsListViewPrivate::scrollItems(int firstVisibleIndex) /*! \internal */ -QSizeF QtGraphicsListViewPrivate::itemSizeHint(const QStyleOptionViewItemV4 *option, int index, const QSizeF &constraint) const -{ - return items.isEmpty() ? QSizeF() : items.first()->sizeHint(index, option, Qt::PreferredSize, constraint); +QSizeF QtGraphicsListViewPrivate::itemSize(int index) const +{ + Q_Q(const QtGraphicsListView); + const QSizeF constraint = (orientation == Qt::Horizontal + ? QSizeF(-1, q->size().height()) + : QSizeF(q->size().width(), -1)); + if (items.isEmpty()) { // construct an item + if (QGraphicsObject *item = creator->create(index, 0)) { + QSizeF size = (item->isWidget() + ? static_cast<QGraphicsWidget*>(item)->size() + : item->boundingRect().size()); // ### FIXME: don't use bounding rect + creator->recycle(item); // ### FIXME: save it for re-use later + return size; + } + qWarning() << "QtGraphicsListView: could not create a new item"; + return QSizeF(); + } + // average size of visible items + QSizeF size; + for (int i = 0; i < items.count(); ++i) + size += items.at(i).second->boundingRect().size(); + return size / items.count(); } // QtGraphicsListView @@ -666,17 +817,16 @@ QRectF QtGraphicsListView::itemGeometry(int index) const Q_D(const QtGraphicsListView); if (!d->model) return QRectF(); - if (QtGraphicsListViewItem *item = itemForIndex(index)) - return item->geometry(); - const QSizeF constraint = size(); + if (QGraphicsObject *item = itemForIndex(index)) + return QRectF(item->pos(), item->boundingRect().size()); + const QSizeF constraint = (d->orientation == Qt::Horizontal + ? QSizeF(-1, size().height()) + : QSizeF(size().width(), -1)); const int count = d->model->count(); - QStyleOptionViewItemV4 option; - initStyleOption(&option); if (d->orientation == Qt::Vertical) { qreal y = -d->offset; for (int i = d->firstIndex; i < count; ++i) { - initStyleOption(&option, i); - const QSizeF size = d->itemSizeHint(&option, i, constraint); + const QSizeF size = d->itemSize(i); if (i == index) return QRectF(QPointF(0, y), size); y += size.height(); @@ -684,8 +834,7 @@ QRectF QtGraphicsListView::itemGeometry(int index) const } else { // Horizontal qreal x = -d->offset; for (int i = d->firstIndex; i < count; ++i) { - initStyleOption(&option, i); - const QSizeF size = d->itemSizeHint(&option, i, constraint); + const QSizeF size = d->itemSize(i); if (i == index) return QRectF(QPointF(x, 0), size); x += size.width(); @@ -705,16 +854,15 @@ int QtGraphicsListView::itemAt(const QPointF &position) const if (!d->model) return -1; // ### FIXME: check the visible items first - const QSizeF constraint = size(); + const QSizeF constraint = (d->orientation == Qt::Horizontal + ? QSizeF(-1, size().height()) + : QSizeF(size().width(), -1)); const int count = d->model->count(); - QStyleOptionViewItemV4 option; - initStyleOption(&option); int index = d->firstIndex; if (d->orientation == Qt::Vertical) { qreal y = -d->offset; while (y <= position.y() && index < count) { - initStyleOption(&option, index); - const QSizeF size = d->itemSizeHint(&option, index, constraint); + const QSizeF size = d->itemSize(index); y += size.height(); if (y >= position.y()) return index; @@ -723,8 +871,7 @@ int QtGraphicsListView::itemAt(const QPointF &position) const } else { qreal x = -d->offset; while (x <= position.x() && index < count) { - initStyleOption(&option, index); - const QSizeF size = d->itemSizeHint(&option, index, constraint); + const QSizeF size = d->itemSize(index); x += size.width(); if (x >= position.x()) return index; @@ -754,11 +901,10 @@ void QtGraphicsListView::doLayout() Q_D(QtGraphicsListView); d->layoutTimer.stop(); - QStyleOptionViewItemV4 option; - initStyleOption(&option); - const QRectF area = boundingRect(); - const QSizeF constraint = area.size(); + const QSizeF constraint = (d->orientation == Qt::Horizontal + ? QSizeF(-1, size().height()) + : QSizeF(size().width(), -1)); const int count = d->model ? d->model->count() : 0; const bool vertical = (d->orientation == Qt::Vertical); const qreal areaStart = (vertical ? area.y() : area.x()); @@ -779,8 +925,7 @@ void QtGraphicsListView::doLayout() // the visible area starts at coordinate == 0 if (coordinate < 0) { // the cached offset was above or to the left of the visible area while (index < count) { - initStyleOption(&option, index); - const QSizeF hint = d->itemSizeHint(&option, index, constraint); + const QSizeF hint = d->itemSize(index); const qreal size = vertical ? hint.height() : hint.width(); if (coordinate + size > areaStart) break; @@ -789,8 +934,7 @@ void QtGraphicsListView::doLayout() } } else if (coordinate > 0) { // the cached offset was below or to the right while (index >= 0 && coordinate > 0) { - initStyleOption(&option, index); - const QSizeF hint = d->itemSizeHint(&option, index, constraint); + const QSizeF hint = d->itemSize(index); const qreal size = vertical ? hint.height() : hint.width(); coordinate -= size; --index; @@ -808,8 +952,8 @@ void QtGraphicsListView::doLayout() // set existing item positions for (int i = 0; i < d->items.count() && index < count && coordinate < areaEnd; ++i) { - QtGraphicsListViewItem *item = d->items.at(i); - const QSizeF size = item->size(); + QGraphicsObject *item = d->items.at(i).second; + const QSizeF size = item->boundingRect().size(); if (vertical) { item->setPos(0, coordinate); coordinate += size.height(); @@ -822,16 +966,23 @@ void QtGraphicsListView::doLayout() // add more items and set geometry while (index < count && coordinate < areaEnd) { - QtGraphicsListViewItem *item = d->creator->create(index, this); - d->items.append(item); - initStyleOption(&option, index); - const QSizeF size = item->sizeHint(index, &option, Qt::PreferredSize, constraint); - if (vertical) { - item->setGeometry(0, coordinate, area.width(), size.height()); - coordinate += size.height(); - } else { - item->setGeometry(coordinate, 0, size.width(), area.height()); - coordinate += size.width(); + if (QGraphicsObject *item = d->creator->create(index, this)) { + d->items.append(QPair<int,QGraphicsObject*>(index, item)); + const bool isWidget = item->isWidget(); + const QSizeF size = (isWidget + ? static_cast<QGraphicsWidget*>(item)->effectiveSizeHint(Qt::PreferredSize, constraint) + : item->boundingRect().size()); // ### don't use bounding rect + if (vertical) { + item->setPos(0, coordinate); + if (isWidget) + static_cast<QGraphicsWidget*>(item)->resize(area.width(), size.height()); + coordinate += size.height(); + } else { + item->setPos(coordinate, 0); + if (isWidget) + static_cast<QGraphicsWidget*>(item)->resize(size.width(), area.height()); + coordinate += size.width(); + } } ++index; } @@ -839,8 +990,7 @@ void QtGraphicsListView::doLayout() // remove unused items const int visibleCount = index - firstVisibleIndex; while (visibleCount < d->items.count()) - d->creator->recycle(d->items.takeLast()); - + d->creator->recycle(d->items.takeLast().second); } /*! @@ -853,24 +1003,22 @@ int QtGraphicsListView::maximumFirstIndex() const { // ### cache this value Q_D(const QtGraphicsListView); - const QSizeF constraint = size(); - QStyleOptionViewItemV4 option; - initStyleOption(&option); + const QSizeF constraint = (d->orientation == Qt::Horizontal + ? QSizeF(-1, size().height()) + : QSizeF(size().width(), -1)); int last = (d->model ? d->model->count() : 0) - 1; int index = last; if (orientation() == Qt::Vertical) { qreal height = size().height() + d->offset; for (; index >= 0; --index) { - initStyleOption(&option, index); - height -= d->itemSizeHint(&option, index, constraint).height(); + height -= d->itemSize(index).height(); if (height < 0) break; } } else { qreal width = size().width() + d->offset; for (; index >= 0; --index) { - initStyleOption(&option, index); - width -= d->itemSizeHint(&option, index, constraint).width(); + width -= d->itemSize(index).width(); if (width < 0) break; } @@ -892,24 +1040,22 @@ qreal QtGraphicsListView::maximumOffset() const { // ### cache this value Q_D(const QtGraphicsListView); - const QSizeF constraint = size(); - QStyleOptionViewItemV4 option; - initStyleOption(&option); + const QSizeF constraint = (d->orientation == Qt::Horizontal + ? QSizeF(-1, size().height()) + : QSizeF(size().width(), -1)); qreal max = 0; qreal content = 0; int count = d->model ? d->model->count() : 0; if (orientation() == Qt::Vertical) { for (int index = 0; index < count; ++index) { - initStyleOption(&option, index); - const QSizeF size = d->itemSizeHint(&option, index, constraint); + const QSizeF size = d->itemSize(index); content += size.height(); max = qMax(max, size.height()); } return qMax<qreal>(content - size().height(), 0); } else { // Horizontal for (int index = 0; index < count; ++index) { - initStyleOption(&option, index); - const QSizeF size = d->itemSizeHint(&option, index, constraint); + const QSizeF size = d->itemSize(index); content += size.width(); max = qMax(max, size.width()); } @@ -1006,7 +1152,9 @@ void QtGraphicsListView::setFirstIndexToEnsureIndexIsVisible(int index) Q_D(QtGraphicsListView); // ### cache if (index > d->firstIndex) { - const QSizeF constraint = size(); + const QSizeF constraint = (d->orientation == Qt::Horizontal + ? QSizeF(-1, size().height()) + : QSizeF(size().width(), -1)); QStyleOptionViewItemV4 option; initStyleOption(&option); if (orientation() == Qt::Vertical) { @@ -1063,124 +1211,6 @@ void QtGraphicsListView::initStyleOption(QStyleOptionViewItemV4 *option) const } /*! - Initialize the given \a option with the settings and data - specific for the item at the given \a index. - */ -void QtGraphicsListView::initStyleOption(QStyleOptionViewItemV4 *option, int index) const -{ - Q_D(const QtGraphicsListView); - Q_ASSERT(option); - - // Current Item - if (d->selectionManager && d->selectionManager->currentItem() == index) - option->state |= QStyle::State_HasFocus; - else - option->state &= ~QStyle::State_HasFocus; - - // selectionManager - if (d->selectionManager && d->selectionManager->isSelected(index)) - option->state |= QStyle::State_Selected; - else - option->state &= ~QStyle::State_Selected; - - // Data - QVariant value; - - // FontRole - value = d->cachedData(index, Qt::FontRole); - if (value.isValid()) { - option->font = qvariant_cast<QFont>(value).resolve(option->font); - option->fontMetrics = QFontMetrics(option->font); - } - - // TextAlignmentRole - value = d->cachedData(index, Qt::TextAlignmentRole); - if (value.isValid()) - option->displayAlignment = (Qt::Alignment)value.toInt(); - - // ForegroundRole - value = d->cachedData(index, Qt::ForegroundRole); - if (qVariantCanConvert<QBrush>(value)) - option->palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value)); - - // CheckStateRole - value = d->cachedData(index, Qt::CheckStateRole); - if (value.isValid()) { - option->features |= QStyleOptionViewItemV2::HasCheckIndicator; - option->checkState = static_cast<Qt::CheckState>(value.toInt()); - } - - // DecorationRole - value = d->cachedData(index, Qt::DecorationRole); - if (value.isValid()) { - option->features |= QStyleOptionViewItemV2::HasDecoration; - switch (value.type()) { - case QVariant::Icon: - option->icon = qvariant_cast<QIcon>(value); - break; - case QVariant::Color: { - QPixmap pixmap(option->decorationSize); - pixmap.fill(qvariant_cast<QColor>(value)); - option->icon = QIcon(pixmap); } - default: - break; - } - } - - // DisplayRole - value = d->cachedData(index, Qt::DisplayRole); - if (value.isValid()) { - option->features |= QStyleOptionViewItemV2::HasDisplay; - switch (value.type()) { - case QVariant::Double: - option->text = option->locale.toString(value.toDouble()); - break; - case QVariant::Int: - case QVariant::LongLong: - option->text = option->locale.toString(value.toLongLong()); - break; - case QVariant::UInt: - case QVariant::ULongLong: - option->text = option->locale.toString(value.toULongLong()); - break; - case QVariant::Date: - option->text = option->locale.toString(value.toDate(), QLocale::ShortFormat); - break; - case QVariant::Time: - option->text = option->locale.toString(value.toTime(), QLocale::ShortFormat); - break; - case QVariant::DateTime: - option->text = option->locale.toString(value.toDateTime().date(), QLocale::ShortFormat); - option->text += QLatin1Char(' '); - option->text += option->locale.toString(value.toDateTime().time(), QLocale::ShortFormat); - break; - default: { - QString text = value.toString(); - for (int i = 0; i < text.count(); ++i) - if (text.at(i).unicode() == '\n') - text[i] = QChar::LineSeparator; - option->text = text; - break; } - } - } -} - -/*! - Copies style option state information from the - given \a source to the given \a destination - */ -void QtGraphicsListView::copyStyleOptionState(const QStyleOptionGraphicsItem *source, QStyleOptionViewItemV4 *destination) -{ - if (source && destination) { - destination->state = source->state; - destination->direction = source->direction; - destination->rect = source->rect; - destination->fontMetrics = source->fontMetrics; - destination->palette = source->palette; - } -} - -/*! */ /* bool QtGraphicsListView::layoutsBlocked() const @@ -1221,11 +1251,14 @@ bool QtGraphicsListView::event(QEvent *event) QVariant QtGraphicsListView::itemChange(GraphicsItemChange change, const QVariant &value) { Q_D(QtGraphicsListView); - if (change == QGraphicsItem::ItemChildRemovedChange) { - QGraphicsItem *item = qvariant_cast<QGraphicsItem*>(value); - int index = d->items.indexOf(static_cast<QtGraphicsListViewItem*>(item)); - if (index != -1) - d->items.removeAt(index); + if (change == QGraphicsObject::ItemChildRemovedChange) { + void *ptr = qvariant_cast<void*>(value); + for (int i = 0; i < d->items.count(); ++i) { + if (d->items.at(i).second == ptr) { + d->items.removeAt(i); + break; + } + } } return QGraphicsWidget::itemChange(change, value); } @@ -1255,16 +1288,15 @@ void QtGraphicsListView::setItemCreator(QtGraphicsListViewItemCreatorBase *creat Returns a view item for the given \a index if such an item exists, otherwise returns null. */ -QtGraphicsListViewItem* QtGraphicsListView::itemForIndex(int index) const +QGraphicsObject* QtGraphicsListView::itemForIndex(int index) const { Q_D(const QtGraphicsListView); if (!d->items.isEmpty()) { - const int firstIndex = d->items.first()->index(); - const int lastIndex = d->items.last()->index(); + const int firstIndex = d->items.first().first; + const int lastIndex = d->items.last().first; if (firstIndex <= index && index <= lastIndex) { - QtGraphicsListViewItem *item = d->items.at(index - firstIndex); + QGraphicsObject *item = d->items.at(index - firstIndex).second; Q_ASSERT(item); - Q_ASSERT(item->index() == index); return item; } } @@ -1282,6 +1314,14 @@ void QtGraphicsListView::itemGeometryChanged(QtGraphicsListViewItem *item) } } +/*! + */ +QVariant QtGraphicsListView::cachedData(int index, int role) const +{ + Q_D(const QtGraphicsListView); + return d->cachedData(index, role); +} + QT_END_NAMESPACE #include "moc_qgraphicslistview.cpp" diff --git a/src/qgraphicslistview.h b/src/qgraphicslistview.h index 0c14fb7..5e2d3a1 100644 --- a/src/qgraphicslistview.h +++ b/src/qgraphicslistview.h @@ -53,15 +53,18 @@ public: int index() const; void setIndex(int index); - virtual QSizeF sizeHint(Qt::SizeHint which = Qt::PreferredSize, const QSizeF &constraint = QSizeF()) const; - virtual QSizeF sizeHint(int index, const QStyleOptionViewItemV4 *option, Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; + QRectF boundingRect() const; + virtual QSizeF sizeHint(Qt::SizeHint which = Qt::PreferredSize, const QSizeF &constraint = QSizeF()) const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); virtual void itemChanged(const QList<int> &roles = QList<int>()); + virtual void initStyleOption(QStyleOptionViewItemV4 *option) const; QHash<int, QVariant> data(const QList<int> &roles = QList<int>()) const; QtGraphicsListView *view() const; + void copyStyleOptionState(const QStyleOptionGraphicsItem *source, QStyleOptionViewItemV4 *dest); + protected: QtGraphicsListViewItemPrivate *d_ptr; @@ -74,16 +77,16 @@ class Q_ITEMVIEWSNG_EXPORT QtGraphicsListViewItemCreatorBase { public: virtual ~QtGraphicsListViewItemCreatorBase(); - virtual QtGraphicsListViewItem *create(int index, QtGraphicsListView *view) = 0; - virtual QtGraphicsListViewItem *reassign(int index, QtGraphicsListViewItem *item); - virtual void recycle(QtGraphicsListViewItem *item); + virtual QGraphicsObject *create(int index, QtGraphicsListView *view) = 0; + virtual QGraphicsObject *reassign(int index, QGraphicsObject *item, QtGraphicsListView *view); + virtual void recycle(QGraphicsObject *item); }; template <class T> class Q_ITEMVIEWSNG_EXPORT QtGraphicsListViewItemCreator : public QtGraphicsListViewItemCreatorBase { public: - inline QtGraphicsListViewItem *create(int index, QtGraphicsListView *view) { return new T(index, view); } + inline QGraphicsObject *create(int index, QtGraphicsListView *view) { return new T(index, view); } }; class Q_ITEMVIEWSNG_EXPORT QtGraphicsListView : public QGraphicsWidget @@ -119,13 +122,11 @@ public: virtual qreal maximumOffset() const; virtual void initStyleOption(QStyleOptionViewItemV4 *option) const; - virtual void initStyleOption(QStyleOptionViewItemV4 *option, int index) const; - void copyStyleOptionState(const QStyleOptionGraphicsItem *source, QStyleOptionViewItemV4 *dest); QtGraphicsListViewItemCreatorBase *itemCreator() const; void setItemCreator(QtGraphicsListViewItemCreatorBase *creator); - QtGraphicsListViewItem *itemForIndex(int index) const; + QGraphicsObject *itemForIndex(int index) const; //bool layoutsBlocked() const; // ### FIXME: should not be needed //void setLayoutsBlocked(bool block); @@ -153,6 +154,8 @@ protected: virtual bool event(QEvent *event); virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + QVariant cachedData(int index, int role) const; + QtGraphicsListViewPrivate *d_ptr; private: diff --git a/src/qgraphicslistview_p.h b/src/qgraphicslistview_p.h index 0fe0129..3da1b02 100644 --- a/src/qgraphicslistview_p.h +++ b/src/qgraphicslistview_p.h @@ -83,7 +83,7 @@ public: // used by updateLayout void scrollItems(int firstVisibleIndex); - QSizeF itemSizeHint(const QStyleOptionViewItemV4 *option, int index, const QSizeF &constraints = QSizeF()) const; + QSizeF itemSize(int index) const; QtGraphicsListView *q_ptr; QtListController *controller; @@ -106,7 +106,7 @@ public: bool layoutsBlocked; - QList<QtGraphicsListViewItem*> items; + QList<QPair<int, QGraphicsObject*> > items; QtGraphicsListViewItemCreatorBase *creator; QBasicTimer layoutTimer; }; diff --git a/src/qlistmodelinterface.cpp b/src/qlistmodelinterface.cpp index ff1abcd..768d87e 100644 --- a/src/qlistmodelinterface.cpp +++ b/src/qlistmodelinterface.cpp @@ -84,9 +84,10 @@ bool QtListModelInterface::setData(int index, const QHash<int,QVariant> &values) /*! Returns the supported roles for this model. */ -QHash<int,QString> QtListModelInterface::roles() const +QHash<int,QByteArray> QtListModelInterface::roles() const { return QtDataRoles::roles(); + } /*! diff --git a/src/qlistmodelinterface.h b/src/qlistmodelinterface.h index d90d37b..5d3592d 100644 --- a/src/qlistmodelinterface.h +++ b/src/qlistmodelinterface.h @@ -43,7 +43,7 @@ public: virtual int count() const = 0; virtual QHash<int,QVariant> data(int index, const QList<int> &roles = (QList<int>())) const = 0; virtual bool setData(int index, const QHash<int,QVariant> &values); - virtual QHash<int,QString> roles() const; + virtual QHash<int,QByteArray> roles() const; Q_SIGNALS: void itemsInserted(int index, int count); diff --git a/src/qtablemodelinterface.cpp b/src/qtablemodelinterface.cpp index bce124b..ccdcfbc 100644 --- a/src/qtablemodelinterface.cpp +++ b/src/qtablemodelinterface.cpp @@ -63,7 +63,7 @@ bool QtTableModelInterface::setData(int row, int column, const QHash<int,QVarian /*! Returns the supported roles for this model. */ -QHash<int,QString> QtTableModelInterface::roles() const +QHash<int,QByteArray> QtTableModelInterface::roles() const { return QtDataRoles::roles(); } diff --git a/src/qtablemodelinterface.h b/src/qtablemodelinterface.h index 78f6dad..780c1ae 100644 --- a/src/qtablemodelinterface.h +++ b/src/qtablemodelinterface.h @@ -44,7 +44,7 @@ public: virtual int columnCount() const = 0; virtual QHash<int,QVariant> data(int row, int column, const QList<int> &roles = QList<int>()) const = 0; virtual bool setData(int row, int column, const QHash<int,QVariant> &values); - virtual QHash<int,QString> roles() const; + virtual QHash<int,QByteArray> roles() const; // ### we may need something along the lines of cacheHint() that gives the model an idea // ### of what can be kept, what can be thrown away and what needs to be fetched diff --git a/src/src.pro b/src/src.pro index f371479..f089a44 100644 --- a/src/src.pro +++ b/src/src.pro @@ -19,10 +19,6 @@ HEADERS += qgraphicsscrollbar.h \ qlistselectionmanager_p.h \ qlistwidgetng.h \ qlistwidgetng_p.h \ - qprinterlistview.h \ - qprinterlistview_p.h \ - qprintertableview.h \ - qprintertableview_p.h \ qsectionspans_p.h \ qtablecontroller.h \ qtablecontroller_p.h \ @@ -51,13 +47,17 @@ HEADERS += qgraphicsscrollbar.h \ qtreewidgetng_p.h \ qdataroles_p.h \ # experimental/qlistiteminterface.h \ - experimental/qgraphicsflowview.h \ + # experimental/qgraphicsflowview.h \ experimental/qgraphicspathview.h \ experimental/qgraphicsgridview.h \ experimental/qkineticlistcontroller.h \ experimental/qkineticlistcontroller_p.h \ experimental/qgraphicsscrollarea.h \ experimental/qgraphicsscrollarea_p.h \ + # experimental/qprinterlistview.h \ + # experimental/qprinterlistview_p.h \ + # experimental/qprintertableview.h \ + # experimental/qprintertableview_p.h \ SOURCES += qgraphicsscrollbar.cpp \ qgraphicsheader.cpp \ @@ -69,8 +69,6 @@ SOURCES += qgraphicsscrollbar.cpp \ qlistfromtreeadaptor.cpp \ qlistselectionmanager.cpp \ qlistwidgetng.cpp \ - qprinterlistview.cpp \ - qprintertableview.cpp \ qtablecontroller.cpp \ qgraphicstableview.cpp \ qtabledefaultmodel.cpp \ @@ -85,11 +83,13 @@ SOURCES += qgraphicsscrollbar.cpp \ qtreeselectionmanager.cpp \ qtreewidgetng.cpp \ # experimental/qlistiteminterface.cpp \ - experimental/qgraphicsflowview.cpp \ + # experimental/qgraphicsflowview.cpp \ experimental/qgraphicspathview.cpp \ experimental/qgraphicsgridview.cpp \ experimental/qkineticlistcontroller.cpp \ experimental/qgraphicsscrollarea.cpp \ + # experimental/qprinterlistview.cpp \ + # experimental/qprintertableview.cpp \ win32 { DEFINES += Q_ITEMVIEWSNG_EXPORT=__declspec(dllexport) |