diff options
author | Marius Bugge Monsen <mmonsen@trolltech.com> | 2009-08-31 16:00:12 +0200 |
---|---|---|
committer | Marius Bugge Monsen <mmonsen@trolltech.com> | 2009-08-31 16:00:12 +0200 |
commit | 0f0c04d35b5496032f4e4feae876427a8d095f1e (patch) | |
tree | 938d0b1d0660c66c7c498416bf8572f2947f3e80 | |
parent | f755b4fec12ad63d0de3e275c0ac9db778ad421a (diff) |
Implement selection behavior in QtListController. Still needs tests and docs.
-rw-r--r-- | src/qgraphicslistview.cpp | 51 | ||||
-rw-r--r-- | src/qgraphicslistview.h | 2 | ||||
-rw-r--r-- | src/qlistcontroller.cpp | 138 | ||||
-rw-r--r-- | src/qlistcontroller.h | 14 | ||||
-rw-r--r-- | src/qlistcontroller_p.h | 3 | ||||
-rw-r--r-- | src/qlistselectionmanager.cpp | 70 | ||||
-rw-r--r-- | src/qlistselectionmanager.h | 8 | ||||
-rw-r--r-- | src/qlistwidgetng.cpp | 2 |
8 files changed, 223 insertions, 65 deletions
diff --git a/src/qgraphicslistview.cpp b/src/qgraphicslistview.cpp index ce61895..169db3e 100644 --- a/src/qgraphicslistview.cpp +++ b/src/qgraphicslistview.cpp @@ -149,19 +149,18 @@ QSizeF QtGraphicsListViewItem::sizeHint(Qt::SizeHint which, const QSizeF &constr /*! \reimp */ +#include <qlistview.h> void QtGraphicsListViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { + Q_UNUSED(option); 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 - if (d->view) { - copyStyleOptionState(option, &d->option); + if (d->view) d->view->initStyleOption(&d->option); - initStyleOption(&d->option); - d->option.rect = rect().toRect(); - //qDebug() << "rect" << boundingRect() << "view rect" << parentItem()->boundingRect(); - d->view->style()->drawControl(QStyle::CE_ItemViewItem, &d->option, painter, widget); - } + initStyleOption(&d->option); + d->option.rect = rect().toRect(); + style()->drawControl(QStyle::CE_ItemViewItem, &d->option, painter, widget); } /*! @@ -220,14 +219,14 @@ void QtGraphicsListViewItem::initStyleOption(QStyleOptionViewItemV4 *option) con // FontRole value = d->view->d_func()->cachedData(d->index, Qt::FontRole); - if (value.isValid()) { + if (value.isValid() && !value.isNull()) { option->font = qvariant_cast<QFont>(value).resolve(option->font); option->fontMetrics = QFontMetrics(option->font); } // TextAlignmentRole value = d->view->d_func()->cachedData(d->index, Qt::TextAlignmentRole); - if (value.isValid()) + if (value.isValid() && !value.isNull()) option->displayAlignment = (Qt::Alignment)value.toInt(); // ForegroundRole @@ -235,6 +234,11 @@ void QtGraphicsListViewItem::initStyleOption(QStyleOptionViewItemV4 *option) con if (qVariantCanConvert<QBrush>(value)) option->palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value)); + // BackgroundRole + value = d->view->d_func()->cachedData(d->index, Qt::BackgroundRole); + if (qVariantCanConvert<QBrush>(value)) + option->palette.setBrush(QPalette::Background, qvariant_cast<QBrush>(value)); + // CheckStateRole value = d->view->d_func()->cachedData(d->index, Qt::CheckStateRole); if (value.isValid()) { @@ -298,21 +302,6 @@ void QtGraphicsListViewItem::initStyleOption(QStyleOptionViewItemV4 *option) con } /*! - 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 @@ -509,7 +498,7 @@ void QtGraphicsListViewPrivate::_q_currentChanged(int current, int previous) if (from <= current && current <= to) items.at(current - from).second->update(); if (from <= previous && previous <= to) - items.at(current - from).second->update(); + items.at(previous - from).second->update(); } } @@ -721,12 +710,14 @@ void QtGraphicsListView::setSelectionManager(QtListSelectionManager *selectionMa disconnect(d->selectionManager, SIGNAL(destroyed()), this, SLOT(_q_selectionsDestroyed())); disconnect(d->selectionManager, SIGNAL(selectionsChanged(const QtListSelectionChange&)), this, SLOT(_q_selectionsChanged(const QtListSelectionChange&))); + disconnect(d->selectionManager, SIGNAL(currentChanged(int,int)), this, SLOT(_q_currentChanged(int,int))); } d->selectionManager = selectionManager; if (d->selectionManager) { connect(d->selectionManager, SIGNAL(destroyed()), this, SLOT(_q_selectionsDestroyed())); connect(d->selectionManager, SIGNAL(selectionsChanged(const QtListSelectionChange&)), this, SLOT(_q_selectionsChanged(const QtListSelectionChange&))); + connect(d->selectionManager, SIGNAL(currentChanged(int,int)), this, SLOT(_q_currentChanged(int,int))); } } @@ -1236,7 +1227,8 @@ void QtGraphicsListView::initStyleOption(QStyleOptionViewItemV4 *option) const { Q_ASSERT(option); option->widget = 0; - option->font = QApplication::font(); + option->palette = palette(); + option->font = font(); option->fontMetrics = QFontMetrics(option->font); option->textElideMode = textElideMode(); option->showDecorationSelected = style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected); @@ -1247,12 +1239,15 @@ void QtGraphicsListView::initStyleOption(QStyleOptionViewItemV4 *option) const option->decorationPosition = vertical ? QStyleOptionViewItem::Left : QStyleOptionViewItem::Top; option->decorationAlignment = Qt::AlignCenter; option->displayAlignment = vertical ? Qt::AlignLeft|Qt::AlignVCenter : Qt::AlignCenter; - option->locale = QLocale(); // ### FIXME + option->direction = layoutDirection(); + //option->locale = QLocale(); // ### FIXME option->locale.setNumberOptions(QLocale::OmitGroupSeparator); //if (d->wrapText) option->features |= QStyleOptionViewItemV2::WrapText; //if (d->alternate) option->features |= QStyleOptionViewItemV2::Alternate; - if (isActiveWindow()) // ### FIXME + if (isActiveWindow()) option->state |= QStyle::State_Active; + if (isEnabled()) + option->state |= QStyle::State_Enabled; } /*! diff --git a/src/qgraphicslistview.h b/src/qgraphicslistview.h index 4e57fe4..bbca758 100644 --- a/src/qgraphicslistview.h +++ b/src/qgraphicslistview.h @@ -64,8 +64,6 @@ public: 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; diff --git a/src/qlistcontroller.cpp b/src/qlistcontroller.cpp index ee86436..f1dbd9e 100644 --- a/src/qlistcontroller.cpp +++ b/src/qlistcontroller.cpp @@ -45,9 +45,11 @@ QtListControllerPrivate::QtListControllerPrivate() model(0), selectionManager(0), view(0), + behavior(QtListController::SingleSelection), animation(0), firstIndex(0), - scrollPerItem(true) + scrollPerItem(true), + wheelEnabled(true) { } @@ -319,6 +321,39 @@ void QtListController::setView(QtGraphicsListView *view) } /*! + */ +QtListController::SelectionBehavior QtListController::selectionBehavior() const +{ + Q_D(const QtListController); + return d->behavior; +} + +/*! + */ +void QtListController::setSelectionBehavior(QtListController::SelectionBehavior behavior) +{ + Q_D(QtListController); + d->behavior = behavior; +} + +/*! + */ +bool QtListController::isWheelEnabled() const +{ + Q_D(const QtListController); + return d->wheelEnabled; +} + +/*! + */ +void QtListController::setWheelEnabled(bool enable) +{ + Q_D(QtListController); + d->wheelEnabled = enable; +} + + +/*! Returns the scroll value of the view. This value depends on the controller scroll mode and the view orientation. @@ -450,15 +485,49 @@ bool QtListController::keyPressEvent(QKeyEvent *event) break; } if (d->selectionManager->currentItem() != index) { - if (event->modifiers() & Qt::ShiftModifier) { - d->selectionManager->beginAnchoredSelection(d->selectionManager->anchorItem()); + if (event->modifiers() & Qt::ControlModifier) { + d->selectionManager->setCurrentItem(index); + switch (d->behavior) { + case NoSelection: + return true; + case SingleSelection: + if (d->selectionManager->isAnchoredSelectionActive()) + d->selectionManager->setAnchorItem(index); + else + d->selectionManager->beginAnchoredSelection(index, QtListSelectionManager::Toggle); + return true; + case MultiSelection: + d->selectionManager->beginAnchoredSelection(d->selectionManager->anchorItem(), QtListSelectionManager::Toggle); + return true; + } + } else if (event->modifiers() & Qt::ShiftModifier) { d->selectionManager->setCurrentItem(index); - } else { - d->selectionManager->endAnchoredSelection(); + switch (d->behavior) { + case NoSelection: + return true; + case SingleSelection: + if (d->selectionManager->isAnchoredSelectionActive()) + d->selectionManager->setAnchorItem(index); + else + d->selectionManager->beginAnchoredSelection(index, QtListSelectionManager::Select); + return true; + case MultiSelection: + d->selectionManager->beginAnchoredSelection(d->selectionManager->anchorItem(), QtListSelectionManager::Select); + return true; + } + } else { // no modifier + //d->selectionManager->endAnchoredSelection(); d->selectionManager->clearSelections(); d->selectionManager->setCurrentItem(index); + switch (d->behavior) { + case NoSelection: + return true; + case SingleSelection: + case MultiSelection: + d->selectionManager->beginAnchoredSelection(index, QtListSelectionManager::Select); + return true; + } } - return true; } } return false; @@ -479,19 +548,39 @@ bool QtListController::mousePressEvent(QGraphicsSceneMouseEvent *event, const QT Q_D(QtListController); if (d->selectionManager && d->view && event->buttons() & Qt::LeftButton) { const int index = d->view->itemAt(transform.map(event->pos())); + d->selectionManager->setCurrentItem(index); if (event->modifiers() & Qt::ControlModifier) { - d->selectionManager->beginAnchoredSelection(index, QtListSelectionManager::Toggle); - d->selectionManager->setCurrentItem(index); + switch (d->behavior) { + case NoSelection: + return true; + case SingleSelection: + case MultiSelection: + d->selectionManager->beginAnchoredSelection(index, QtListSelectionManager::Toggle); + return true; + } } else if (event->modifiers() & Qt::ShiftModifier) { d->selectionManager->clearSelections(); - d->selectionManager->beginAnchoredSelection(d->selectionManager->anchorItem()); - d->selectionManager->setCurrentItem(index); + switch (d->behavior) { + case NoSelection: + return true; + case SingleSelection: + d->selectionManager->beginAnchoredSelection(index); + return true; + case MultiSelection: + d->selectionManager->beginAnchoredSelection(d->selectionManager->anchorItem()); + return true; + } } else { // no modifiers d->selectionManager->clearSelections(); - d->selectionManager->beginAnchoredSelection(index); - d->selectionManager->setCurrentItem(index); + switch (d->behavior) { + case NoSelection: + return true; + case SingleSelection: + case MultiSelection: + d->selectionManager->beginAnchoredSelection(index); + return true; + } } - return true; } return false; } @@ -505,7 +594,15 @@ bool QtListController::mouseMoveEvent(QGraphicsSceneMouseEvent *event, const QTr const int index = d->view->itemAt(transform.map(event->pos())); if (d->selectionManager->currentItem() != index) { d->selectionManager->setCurrentItem(index); - return true; + switch (d->behavior) { + case NoSelection: + return true; + case SingleSelection: + d->selectionManager->setAnchorItem(index); + return true; + case MultiSelection: + return true; + } } } return false; @@ -520,7 +617,15 @@ bool QtListController::mouseReleaseEvent(QGraphicsSceneMouseEvent *event, const const int index = d->view->itemAt(transform.map(event->pos())); if (d->selectionManager->currentItem() != index) d->selectionManager->setCurrentItem(index); - d->selectionManager->endAnchoredSelection(); + switch (d->behavior) { + case NoSelection: + break; + case SingleSelection: + d->selectionManager->setAnchorItem(index); + case MultiSelection: + d->selectionManager->endAnchoredSelection(); + break; + } emit itemClicked(index, Qt::LeftButton); emit itemActivated(index); // activates on single-click return true; @@ -606,7 +711,8 @@ bool QtListController::wheelEvent(QGraphicsSceneWheelEvent *event, const QTransf { Q_UNUSED(transform); Q_D(QtListController); - if (!d->view) + return false; + if (!d->view || !d->wheelEnabled) return false; if (d->scrollPerItem) { const int index = d->view->firstIndex() - event->delta() / 120; diff --git a/src/qlistcontroller.h b/src/qlistcontroller.h index 57cb33d..70d5f09 100644 --- a/src/qlistcontroller.h +++ b/src/qlistcontroller.h @@ -56,6 +56,14 @@ class Q_ITEMVIEWSNG_EXPORT QtListController : public QObject Q_PROPERTY(QtListModelInterface* model READ model WRITE setModel) Q_PROPERTY(QtListSelectionManager* selectionManager READ selectionManager WRITE setSelectionManager) Q_PROPERTY(QtGraphicsListView *view READ view WRITE setView) + Q_PROPERTY(SelectionBehavior selectionBehavior READ selectionBehavior WRITE setSelectionBehavior) + Q_PROPERTY(bool isWheelEnabled READ isWheelEnabled WRITE setWheelEnabled) + + enum SelectionBehavior { + NoSelection, + SingleSelection, + MultiSelection + }; public: QtListController(QObject *parent = 0); @@ -70,6 +78,12 @@ public: QtGraphicsListView *view() const; void setView(QtGraphicsListView *view); + SelectionBehavior selectionBehavior() const; + void setSelectionBehavior(SelectionBehavior behavior); + + bool isWheelEnabled() const; + void setWheelEnabled(bool enable); + virtual qreal scrollValue() const; virtual qreal pageStepValue(qreal *maximumScrollValue = 0) const; virtual qreal maximumScrollValue() const; diff --git a/src/qlistcontroller_p.h b/src/qlistcontroller_p.h index 13825e0..80c8990 100644 --- a/src/qlistcontroller_p.h +++ b/src/qlistcontroller_p.h @@ -70,10 +70,13 @@ public: QPointer<QtListSelectionManager> selectionManager; QtGraphicsListView *view; + QtListController::SelectionBehavior behavior; + QPropertyAnimation *animation; int firstIndex; bool scrollPerItem; + bool wheelEnabled; }; QT_END_NAMESPACE diff --git a/src/qlistselectionmanager.cpp b/src/qlistselectionmanager.cpp index d947c15..f0290ff 100644 --- a/src/qlistselectionmanager.cpp +++ b/src/qlistselectionmanager.cpp @@ -565,6 +565,19 @@ bool QtListSelectionManager::isAnchoredSelectionActive() const /*! */ +void QtListSelectionManager::setAnchoredSelectionActive(bool active) +{ + Q_D(QtListSelectionManager); + d->active = active; + if (d->active) { + d->change.d->setRanges(d->anchor, d->anchor, d->current, d->current, d->selections, d->mode); + emit selectionsChanged(d->change); + d->change.d->clear(); // avoid detach later + } +} + +/*! + */ QtListSelectionManager::SelectionMode QtListSelectionManager::anchoredSelectionMode() const { Q_D(const QtListSelectionManager); @@ -573,6 +586,21 @@ QtListSelectionManager::SelectionMode QtListSelectionManager::anchoredSelectionM /*! */ +void QtListSelectionManager::setAnchoredSelectionMode(QtListSelectionManager::SelectionMode mode) +{ + Q_D(QtListSelectionManager); + if (mode != d->mode) { + d->mode = mode; + if (d->active) { + d->change.d->setRanges(d->anchor, d->anchor, d->current, d->current, d->selections, d->mode); + emit selectionsChanged(d->change); + d->change.d->clear(); // avoid detach later + } + } +} + +/*! + */ void QtListSelectionManager::beginAnchoredSelection(int anchor, SelectionMode mode) { Q_D(QtListSelectionManager); @@ -589,27 +617,35 @@ void QtListSelectionManager::endAnchoredSelection() { Q_D(QtListSelectionManager); if (d->active) { - // commit anchored selection range - if (d->current >= 0 && d->anchor >= 0) { - const int from = qMin(d->anchor, d->current); - const int to = qMax(d->anchor, d->current) + 1; - switch (d->mode) { - case Select: - d->selections.fill(true, from, to); - break; - case Deselect: - d->selections.fill(false, from, to); - break; - case Toggle: - for (int i = from; i <= to; ++i) - d->selections.toggleBit(i); - break; - } - } + commitAnchoredSelection(); d->active = false; } } +/*! + */ +void QtListSelectionManager::commitAnchoredSelection() +{ + Q_D(QtListSelectionManager); + // commit anchored selection range + if (d->current >= 0 && d->anchor >= 0) { + const int from = qMin(d->anchor, d->current); + const int to = qMax(d->anchor, d->current) + 1; + switch (d->mode) { + case Select: + d->selections.fill(true, from, to); + break; + case Deselect: + d->selections.fill(false, from, to); + break; + case Toggle: + for (int i = from; i <= to; ++i) + d->selections.toggleBit(i); + break; + } + } +} + QT_END_NAMESPACE #include "moc_qlistselectionmanager.cpp" diff --git a/src/qlistselectionmanager.h b/src/qlistselectionmanager.h index 7763d4f..95765b2 100644 --- a/src/qlistselectionmanager.h +++ b/src/qlistselectionmanager.h @@ -61,8 +61,8 @@ class Q_ITEMVIEWSNG_EXPORT QtListSelectionManager : public QObject { Q_OBJECT Q_PROPERTY(int currentItem READ currentItem WRITE setCurrentItem) - Q_PROPERTY(bool anchoredSelectionActive READ isAnchoredSelectionActive) - Q_PROPERTY(SelectionMode anchoredSelectionMode READ anchoredSelectionMode) + Q_PROPERTY(bool anchoredSelectionActive READ isAnchoredSelectionActive WRITE setAnchoredSelectionActive) + Q_PROPERTY(SelectionMode anchoredSelectionMode READ anchoredSelectionMode WRITE setAnchoredSelectionMode) public: enum SelectionMode { Select, @@ -82,7 +82,10 @@ public: QList<int> selectedItems() const; bool isAnchoredSelectionActive() const; + void setAnchoredSelectionActive(bool active); + SelectionMode anchoredSelectionMode() const; + void setAnchoredSelectionMode(SelectionMode mode); void beginAnchoredSelection(int anchor, SelectionMode mode = Select); void endAnchoredSelection(); @@ -102,6 +105,7 @@ protected: QtListSelectionManager(QtListSelectionManagerPrivate&, QObject *parent = 0); QtListSelectionManagerPrivate *d_ptr; void setModel(QtListModelInterface *model); + void commitAnchoredSelection(); private: friend class QtListController; diff --git a/src/qlistwidgetng.cpp b/src/qlistwidgetng.cpp index 34fb103..1a70187 100644 --- a/src/qlistwidgetng.cpp +++ b/src/qlistwidgetng.cpp @@ -159,6 +159,7 @@ void QtListWidgetNGPrivate::_q_viewChanged(QtGraphicsListView *current, QtGraphi } if (current) { q->scene()->addItem(current); + q->scene()->setActiveWindow(current); current->grabKeyboard(); } //_q_updateGeometries(); @@ -197,6 +198,7 @@ void QtListWidgetNGPrivate::initialize() controller->setView(new QtGraphicsListView); controller->view()->setParent(controller); } + controller->setWheelEnabled(false); // the widget will handle it _q_controllerChanged(controller, 0); } |