summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Bugge Monsen <mmonsen@trolltech.com>2009-08-31 16:00:12 +0200
committerMarius Bugge Monsen <mmonsen@trolltech.com>2009-08-31 16:00:12 +0200
commit0f0c04d35b5496032f4e4feae876427a8d095f1e (patch)
tree938d0b1d0660c66c7c498416bf8572f2947f3e80
parentf755b4fec12ad63d0de3e275c0ac9db778ad421a (diff)
Implement selection behavior in QtListController. Still needs tests and docs.
-rw-r--r--src/qgraphicslistview.cpp51
-rw-r--r--src/qgraphicslistview.h2
-rw-r--r--src/qlistcontroller.cpp138
-rw-r--r--src/qlistcontroller.h14
-rw-r--r--src/qlistcontroller_p.h3
-rw-r--r--src/qlistselectionmanager.cpp70
-rw-r--r--src/qlistselectionmanager.h8
-rw-r--r--src/qlistwidgetng.cpp2
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);
}