summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/dialogs/qfileinfogatherer_p.h2
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp44
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h8
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp17
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h2
-rw-r--r--src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp4
-rw-r--r--src/gui/image/qbmphandler.cpp8
-rw-r--r--src/gui/image/qiconloader_p.h1
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp10
-rw-r--r--src/gui/itemviews/qabstractitemview_p.h9
-rw-r--r--src/gui/itemviews/qlistview.cpp988
-rw-r--r--src/gui/itemviews/qlistview_p.h209
-rw-r--r--src/gui/kernel/qapplication.cpp13
-rw-r--r--src/gui/kernel/qapplication_x11.cpp2
-rw-r--r--src/gui/kernel/qcocoaapplicationdelegate_mac.mm18
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm10
-rw-r--r--src/gui/kernel/qdnd_x11.cpp6
-rw-r--r--src/gui/kernel/qevent.cpp158
-rw-r--r--src/gui/kernel/qshortcutmap.cpp4
-rw-r--r--src/gui/kernel/qstandardgestures.cpp18
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm8
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac_p.h1
-rw-r--r--src/gui/kernel/qt_mac.cpp19
-rw-r--r--src/gui/kernel/qwidget_mac.mm2
-rw-r--r--src/gui/kernel/qwidget_win.cpp2
-rw-r--r--src/gui/styles/gtksymbols.cpp2
-rw-r--r--src/gui/widgets/qdatetimeedit.cpp2
-rw-r--r--src/gui/widgets/qmainwindow.cpp15
28 files changed, 853 insertions, 729 deletions
diff --git a/src/gui/dialogs/qfileinfogatherer_p.h b/src/gui/dialogs/qfileinfogatherer_p.h
index cb980d2..bab4a29 100644
--- a/src/gui/dialogs/qfileinfogatherer_p.h
+++ b/src/gui/dialogs/qfileinfogatherer_p.h
@@ -184,7 +184,7 @@ private:
QMutex mutex;
QWaitCondition condition;
- bool abort;
+ volatile bool abort;
QStack<QString> path;
QStack<QStringList> files;
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 4f64c2a..88fac14 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1023,7 +1023,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
}
// Resolve depth.
- resolveDepth(parent ? parent->d_ptr->depth : -1);
+ invalidateDepthRecursively();
dirtySceneTransform = 1;
// Restore the sub focus chain.
@@ -4413,14 +4413,42 @@ bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, bool ignore
/*!
\internal
+*/
+int QGraphicsItemPrivate::depth() const
+{
+ if (itemDepth == -1)
+ const_cast<QGraphicsItemPrivate *>(this)->resolveDepth();
+
+ return itemDepth;
+}
- Resolves the stacking depth of this object and all its children.
+/*!
+ \internal
*/
-void QGraphicsItemPrivate::resolveDepth(int parentDepth)
+void QGraphicsItemPrivate::invalidateDepthRecursively()
{
- depth = parentDepth + 1;
+ if (itemDepth == -1)
+ return;
+
+ itemDepth = -1;
for (int i = 0; i < children.size(); ++i)
- children.at(i)->d_ptr->resolveDepth(depth);
+ children.at(i)->d_ptr->invalidateDepthRecursively();
+}
+
+/*!
+ \internal
+
+ Resolves the stacking depth of this object and all its ancestors.
+*/
+void QGraphicsItemPrivate::resolveDepth()
+{
+ if (!parent)
+ itemDepth = 0;
+ else {
+ if (parent->d_ptr->itemDepth == -1)
+ parent->d_ptr->resolveDepth();
+ itemDepth = parent->d_ptr->itemDepth + 1;
+ }
}
/*!
@@ -5590,8 +5618,8 @@ QGraphicsItem *QGraphicsItem::commonAncestorItem(const QGraphicsItem *other) con
return const_cast<QGraphicsItem *>(this);
const QGraphicsItem *thisw = this;
const QGraphicsItem *otherw = other;
- int thisDepth = d_ptr->depth;
- int otherDepth = other->d_ptr->depth;
+ int thisDepth = d_ptr->depth();
+ int otherDepth = other->d_ptr->depth();
while (thisDepth > otherDepth) {
thisw = thisw->d_ptr->parent;
--thisDepth;
@@ -6601,7 +6629,7 @@ void QGraphicsItem::prepareGeometryChange()
// if someone is connected to the changed signal or the scene has no views.
// Note that this has to be done *after* markDirty to ensure that
// _q_processDirtyItems is called before _q_emitUpdated.
- if ((scenePrivate->connectedSignals[0] & scenePrivate->changedSignalMask)
+ if (scenePrivate->isSignalConnected(scenePrivate->changedSignalIndex)
|| scenePrivate->views.isEmpty()) {
if (d_ptr->hasTranslateOnlySceneTransform()) {
d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(),
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 24326f6..6456ae7 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -123,7 +123,7 @@ public:
transformData(0),
index(-1),
siblingIndex(-1),
- depth(0),
+ itemDepth(-1),
focusProxy(0),
subFocusItem(0),
imHints(Qt::ImhNone),
@@ -209,7 +209,9 @@ public:
void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
bool discardUpdateRequest(bool ignoreClipping = false, bool ignoreVisibleBit = false,
bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
- void resolveDepth(int parentDepth);
+ int depth() const;
+ void invalidateDepthRecursively();
+ void resolveDepth();
void addChild(QGraphicsItem *child);
void removeChild(QGraphicsItem *child);
void setParentItemHelper(QGraphicsItem *parent);
@@ -419,7 +421,7 @@ public:
QTransform sceneTransform;
int index;
int siblingIndex;
- int depth;
+ int itemDepth; // Lazily calculated when calling depth().
QGraphicsItem *focusProxy;
QList<QGraphicsItem **> focusProxyRefs;
QGraphicsItem *subFocusItem;
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index a2a92b8..a8db74d 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -265,12 +265,13 @@ static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraph
hover->setAccepted(mouseEvent->isAccepted());
}
+int QGraphicsScenePrivate::changedSignalIndex;
+
/*!
\internal
*/
QGraphicsScenePrivate::QGraphicsScenePrivate()
- : changedSignalMask(0),
- indexMethod(QGraphicsScene::BspTreeIndex),
+ : indexMethod(QGraphicsScene::BspTreeIndex),
index(0),
lastItemCount(0),
hasSceneRect(false),
@@ -311,7 +312,9 @@ void QGraphicsScenePrivate::init()
index = new QGraphicsSceneBspTreeIndex(q);
// Keep this index so we can check for connected slots later on.
- changedSignalMask = (1 << q->metaObject()->indexOfSignal("changed(QList<QRectF>)"));
+ if (!changedSignalIndex) {
+ changedSignalIndex = signalIndex("changed(QList<QRectF>)");
+ }
qApp->d_func()->scene_list.append(q);
q->update();
}
@@ -343,7 +346,7 @@ void QGraphicsScenePrivate::_q_emitUpdated()
// the optimization that items send updates directly to the views, but it
// needs to happen in order to keep compatibility with the behavior from
// Qt 4.4 and backward.
- if (connectedSignals[0] & changedSignalMask) {
+ if (isSignalConnected(changedSignalIndex)) {
for (int i = 0; i < views.size(); ++i) {
QGraphicsView *view = views.at(i);
if (!view->d_func()->connectedToScene) {
@@ -2894,7 +2897,7 @@ void QGraphicsScene::update(const QRectF &rect)
// Check if anyone's connected; if not, we can send updates directly to
// the views. Otherwise or if there are no views, use old behavior.
- bool directUpdates = !(d->connectedSignals[0] & d->changedSignalMask) && !d->views.isEmpty();
+ bool directUpdates = !(d->isSignalConnected(d->changedSignalIndex)) && !d->views.isEmpty();
if (rect.isNull()) {
d->updateAll = true;
d->updatedRects.clear();
@@ -4473,7 +4476,7 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b
if (removingItemFromScene) {
// Note that this function can be called from the item's destructor, so
// do NOT call any virtual functions on it within this block.
- if ((connectedSignals[0] & changedSignalMask) || views.isEmpty()) {
+ if (isSignalConnected(changedSignalIndex) || views.isEmpty()) {
// This block of code is kept for compatibility. Since 4.5, by default
// QGraphicsView does not connect the signal and we use the below
// method of delivering updates.
@@ -4619,7 +4622,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
// Process item.
if (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
- const bool useCompatUpdate = views.isEmpty() || (connectedSignals[0] & changedSignalMask);
+ const bool useCompatUpdate = views.isEmpty() || isSignalConnected(changedSignalIndex);
const QRectF itemBoundingRect = adjustedItemBoundingRect(item);
if (useCompatUpdate && !itemIsUntransformable && qFuzzyIsNull(item->boundingRegionGranularity())) {
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 685f534..f1ddb5a 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -87,7 +87,7 @@ public:
static QGraphicsScenePrivate *get(QGraphicsScene *q);
- quint32 changedSignalMask;
+ static int changedSignalIndex;
QGraphicsScene::ItemIndexMethod indexMethod;
QGraphicsSceneIndex *index;
diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
index 433d0a8..7483bc1 100644
--- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
+++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
@@ -419,8 +419,8 @@ bool QGraphicsSceneBspTreeIndexPrivate::closestItemFirst_withoutCache(const QGra
// Find common ancestor, and each item's ancestor closest to the common
// ancestor.
- int item1Depth = d1->depth;
- int item2Depth = d2->depth;
+ int item1Depth = d1->depth();
+ int item2Depth = d2->depth();
const QGraphicsItem *p = item1;
const QGraphicsItem *t1 = item1;
while (item1Depth > item2Depth && (p = p->d_ptr->parent)) {
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index ccf8457..19701b4 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -81,14 +81,14 @@ static void swapPixel01(QImage *image) // 1-bpp: swap 0 and 1 pixels
const int BMP_FILEHDR_SIZE = 14; // size of BMP_FILEHDR data
-QDataStream &operator>>(QDataStream &s, BMP_FILEHDR &bf)
+static QDataStream &operator>>(QDataStream &s, BMP_FILEHDR &bf)
{ // read file header
s.readRawData(bf.bfType, 2);
s >> bf.bfSize >> bf.bfReserved1 >> bf.bfReserved2 >> bf.bfOffBits;
return s;
}
-QDataStream &operator<<(QDataStream &s, const BMP_FILEHDR &bf)
+static QDataStream &operator<<(QDataStream &s, const BMP_FILEHDR &bf)
{ // write file header
s.writeRawData(bf.bfType, 2);
s << bf.bfSize << bf.bfReserved1 << bf.bfReserved2 << bf.bfOffBits;
@@ -106,7 +106,7 @@ const int BMP_RLE4 = 2; // run-length encoded, 4
const int BMP_BITFIELDS = 3; // RGB values encoded in data as bit-fields
-QDataStream &operator>>(QDataStream &s, BMP_INFOHDR &bi)
+static QDataStream &operator>>(QDataStream &s, BMP_INFOHDR &bi)
{
s >> bi.biSize;
if (bi.biSize == BMP_WIN || bi.biSize == BMP_OS2) {
@@ -128,7 +128,7 @@ QDataStream &operator>>(QDataStream &s, BMP_INFOHDR &bi)
return s;
}
-QDataStream &operator<<(QDataStream &s, const BMP_INFOHDR &bi)
+static QDataStream &operator<<(QDataStream &s, const BMP_INFOHDR &bi)
{
s << bi.biSize;
s << bi.biWidth << bi.biHeight;
diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h
index b2944ef..5d5c211 100644
--- a/src/gui/image/qiconloader_p.h
+++ b/src/gui/image/qiconloader_p.h
@@ -85,6 +85,7 @@ struct QIconDirInfo
class QIconLoaderEngineEntry
{
public:
+ virtual ~QIconLoaderEngineEntry() {}
virtual QPixmap pixmap(const QSize &size,
QIcon::Mode mode,
QIcon::State state) = 0;
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index 8f8eae5..0671304 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -3382,11 +3382,7 @@ QPoint QAbstractItemView::dirtyRegionOffset() const
*/
void QAbstractItemView::startAutoScroll()
{
- Q_D(QAbstractItemView);
- // ### it would be nice to make this into a style hint one day
- int scrollInterval = (verticalScrollMode() == QAbstractItemView::ScrollPerItem) ? 150 : 50;
- d->autoScrollTimer.start(scrollInterval, this);
- d->autoScrollCount = 0;
+ d_func()->startAutoScroll();
}
/*!
@@ -3394,9 +3390,7 @@ void QAbstractItemView::startAutoScroll()
*/
void QAbstractItemView::stopAutoScroll()
{
- Q_D(QAbstractItemView);
- d->autoScrollTimer.stop();
- d->autoScrollCount = 0;
+ d_func()->stopAutoScroll();
}
/*!
diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h
index 0d55a2e..07edd4a 100644
--- a/src/gui/itemviews/qabstractitemview_p.h
+++ b/src/gui/itemviews/qabstractitemview_p.h
@@ -126,6 +126,15 @@ public:
void doDelayedItemsLayout(int delay = 0);
void interruptDelayedItemsLayout() const;
+ void startAutoScroll()
+ { // ### it would be nice to make this into a style hint one day
+ int scrollInterval = (verticalScrollMode == QAbstractItemView::ScrollPerItem) ? 150 : 50;
+ autoScrollTimer.start(scrollInterval, q_func());
+ autoScrollCount = 0;
+ }
+ void stopAutoScroll() { autoScrollTimer.stop(); autoScrollCount = 0;}
+
+
bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index);
bool droppingOnItself(QDropEvent *event, const QModelIndex &index);
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
index e9e365f..3e9db3b 100644
--- a/src/gui/itemviews/qlistview.cpp
+++ b/src/gui/itemviews/qlistview.cpp
@@ -1,4 +1,4 @@
-/***************************************************************************
+/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
@@ -458,15 +458,13 @@ QSize QListView::gridSize() const
void QListView::setViewMode(ViewMode mode)
{
Q_D(QListView);
- if (d->viewMode == mode)
+ if (d->commonListView && d->viewMode == mode)
return;
d->viewMode = mode;
+ delete d->commonListView;
if (mode == ListMode) {
- delete d->dynamicListView;
- d->dynamicListView = 0;
- if (!d->staticListView)
- d->staticListView = new QStaticListViewBase(this, d);
+ d->commonListView = new QListModeViewBase(this, d);
if (!(d->modeProperties & QListViewPrivate::Wrap))
d->setWrapping(false);
if (!(d->modeProperties & QListViewPrivate::Spacing))
@@ -482,10 +480,7 @@ void QListView::setViewMode(ViewMode mode)
if (!(d->modeProperties & QListViewPrivate::SelectionRectVisible))
d->showElasticBand = false;
} else {
- delete d->staticListView;
- d->staticListView = 0;
- if (!d->dynamicListView)
- d->dynamicListView = new QDynamicListViewBase(this, d);
+ d->commonListView = new QIconModeViewBase(this, d);
if (!(d->modeProperties & QListViewPrivate::Wrap))
d->setWrapping(true);
if (!(d->modeProperties & QListViewPrivate::Spacing))
@@ -549,24 +544,12 @@ void QListView::setRowHidden(int row, bool hide)
{
Q_D(QListView);
const bool hidden = d->isHidden(row);
- if (d->viewMode == ListMode) {
- if (hide && !hidden)
- d->hiddenRows.append(d->model->index(row, 0));
- else if (!hide && hidden)
- d->hiddenRows.remove(d->hiddenRows.indexOf(d->model->index(row, 0)));
- d->doDelayedItemsLayout();
- } else {
- if (hide && !hidden) {
- d->dynamicListView->removeItem(row);
- d->hiddenRows.append(d->model->index(row, 0));
- } else if (!hide && hidden) {
- d->hiddenRows.remove(d->hiddenRows.indexOf(d->model->index(row, 0)));
- d->dynamicListView->insertItem(row);
- }
- if (d->resizeMode == Adjust)
- d->doDelayedItemsLayout();
- d->viewport->update();
- }
+ if (hide && !hidden)
+ d->commonListView->appendHiddenRow(row);
+ else if (!hide && hidden)
+ d->commonListView->removeHiddenRow(row);
+ d->doDelayedItemsLayout();
+ d->viewport->update();
}
/*!
@@ -575,7 +558,7 @@ void QListView::setRowHidden(int row, bool hide)
QRect QListView::visualRect(const QModelIndex &index) const
{
Q_D(const QListView);
- return d->mapToViewport(rectForIndex(index), d->viewMode == QListView::ListMode);
+ return d->mapToViewport(rectForIndex(index));
}
/*!
@@ -612,69 +595,17 @@ int QListViewPrivate::horizontalScrollToValue(const QModelIndex &index, const QR
const bool rightOf = q->isRightToLeft()
? rect.right() > area.right()
: (rect.right() > area.right()) && (rect.left() > area.left());
- int horizontalValue = hbar->value();
-
- // ScrollPerItem
- if (q->horizontalScrollMode() == QAbstractItemView::ScrollPerItem && viewMode == QListView::ListMode) {
- const QListViewItem item = indexToListViewItem(index);
- const QRect rect = q->visualRect(index);
- horizontalValue = staticListView->horizontalPerItemValue(itemIndex(item),
- horizontalValue, area.width(),
- leftOf, rightOf, isWrapping(), hint, rect.width());
- } else { // ScrollPerPixel
- if (q->isRightToLeft()) {
- if (hint == QListView::PositionAtCenter) {
- horizontalValue += ((area.width() - rect.width()) / 2) - rect.left();
- } else {
- if (leftOf)
- horizontalValue -= rect.left();
- else if (rightOf)
- horizontalValue += qMin(rect.left(), area.width() - rect.right());
- }
- } else {
- if (hint == QListView::PositionAtCenter) {
- horizontalValue += rect.left() - ((area.width()- rect.width()) / 2);
- } else {
- if (leftOf)
- horizontalValue += rect.left();
- else if (rightOf)
- horizontalValue += qMin(rect.left(), rect.right() - area.width());
- }
- }
- }
- return horizontalValue;
+ return commonListView->horizontalScrollToValue(q->visualIndex(index), hint, leftOf, rightOf, area, rect);
}
int QListViewPrivate::verticalScrollToValue(const QModelIndex &index, const QRect &rect,
QListView::ScrollHint hint) const
{
Q_Q(const QListView);
-
const QRect area = viewport->rect();
const bool above = (hint == QListView::EnsureVisible && rect.top() < area.top());
const bool below = (hint == QListView::EnsureVisible && rect.bottom() > area.bottom());
-
- int verticalValue = vbar->value();
-
- // ScrollPerItem
- if (verticalScrollMode == QAbstractItemView::ScrollPerItem && viewMode == QListView::ListMode) {
- const QListViewItem item = indexToListViewItem(index);
- const QRect rect = q->visualRect(index);
- verticalValue = staticListView->verticalPerItemValue(itemIndex(item),
- verticalValue, area.height(),
- above, below, isWrapping(), hint, rect.height());
-
- } else { // ScrollPerPixel
- QRect adjusted = rect.adjusted(-spacing(), -spacing(), spacing(), spacing());
- if (hint == QListView::PositionAtTop || above)
- verticalValue += adjusted.top();
- else if (hint == QListView::PositionAtBottom || below)
- verticalValue += qMin(adjusted.top(), adjusted.bottom() - area.height() + 1);
- else if (hint == QListView::PositionAtCenter)
- verticalValue += adjusted.top() - ((area.height() - adjusted.height()) / 2);
- }
-
- return verticalValue;
+ return commonListView->verticalScrollToValue(q->visualIndex(index), hint, above, below, area, rect);
}
void QListViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command)
@@ -766,23 +697,12 @@ void QListView::setRootIndex(const QModelIndex &index)
Scroll the view contents by \a dx and \a dy.
*/
+
void QListView::scrollContentsBy(int dx, int dy)
{
Q_D(QListView);
-
d->delayedAutoScroll.stop(); // auto scroll was canceled by the user scrolling
-
- if (d->viewMode == ListMode)
- d->staticListView->scrollContentsBy(dx, dy);
- else if (state() == DragSelectingState)
- d->scrollElasticBandBy(isRightToLeft() ? -dx : dx, dy);
-
- d->scrollContentsBy(isRightToLeft() ? -dx : dx, dy);
-
- // update the dragged items
- if (d->viewMode == IconMode) // ### move to dynamic class
- if (!d->dynamicListView->draggedItems.isEmpty())
- d->viewport->update(d->dynamicListView->draggedItemsRect().translated(dx, dy));
+ d->commonListView->scrollContentsBy(dx, dy, d->state == QListView::DragSelectingState);
}
/*!
@@ -811,9 +731,7 @@ QSize QListView::contentsSize() const
*/
void QListView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
- Q_D(QListView);
- if (d->viewMode == IconMode)
- d->dynamicListView->dataChanged(topLeft, bottomRight);
+ d_func()->commonListView->dataChanged(topLeft, bottomRight);
QAbstractItemView::dataChanged(topLeft, bottomRight);
}
@@ -864,7 +782,7 @@ void QListView::mouseMoveEvent(QMouseEvent *e)
&& d->selectionMode != NoSelection) {
QRect rect(d->pressedPosition, e->pos() + QPoint(horizontalOffset(), verticalOffset()));
rect = rect.normalized();
- d->viewport->update(d->mapToViewport(rect.united(d->elasticBand), d->viewMode == QListView::ListMode));
+ d->viewport->update(d->mapToViewport(rect.united(d->elasticBand)));
d->elasticBand = rect;
}
}
@@ -878,7 +796,7 @@ void QListView::mouseReleaseEvent(QMouseEvent *e)
QAbstractItemView::mouseReleaseEvent(e);
// #### move this implementation into a dynamic class
if (d->showElasticBand && d->elasticBand.isValid()) {
- d->viewport->update(d->mapToViewport(d->elasticBand, d->viewMode == QListView::ListMode));
+ d->viewport->update(d->mapToViewport(d->elasticBand));
d->elasticBand = QRect();
}
}
@@ -935,69 +853,27 @@ void QListView::resizeEvent(QResizeEvent *e)
*/
void QListView::dragMoveEvent(QDragMoveEvent *e)
{
- // ### move implementation to dynamic
- Q_D(QListView);
- if (e->source() == this && d->viewMode == IconMode) {
- // the ignore by default
- e->ignore();
- if (d->canDecode(e)) {
- // get old dragged items rect
- QRect itemsRect = d->dynamicListView->itemsRect(d->dynamicListView->draggedItems);
- d->viewport->update(itemsRect.translated(d->dynamicListView->draggedItemsDelta()));
- // update position
- d->dynamicListView->draggedItemsPos = e->pos();
- // get new items rect
- d->viewport->update(itemsRect.translated(d->dynamicListView->draggedItemsDelta()));
- // set the item under the cursor to current
- QModelIndex index;
- if (d->movement == Snap) {
- QRect rect(d->dynamicListView->snapToGrid(e->pos() + d->offset()), d->gridSize());
- const QVector<QModelIndex> intersectVector = d->intersectingSet(rect);
- index = intersectVector.count() > 0
- ? intersectVector.last() : QModelIndex();
- } else {
- index = indexAt(e->pos());
- }
- // check if we allow drops here
- if (e->source() == this && d->dynamicListView->draggedItems.contains(index))
- e->accept(); // allow changing item position
- else if (d->model->flags(index) & Qt::ItemIsDropEnabled)
- e->accept(); // allow dropping on dropenabled items
- else if (!index.isValid())
- e->accept(); // allow dropping in empty areas
- }
- // do autoscrolling
- if (d->shouldAutoScroll(e->pos()))
- startAutoScroll();
- } else { // not internal
+ if (!d_func()->commonListView->filterDragMoveEvent(e))
QAbstractItemView::dragMoveEvent(e);
- }
}
+
/*!
\reimp
*/
void QListView::dragLeaveEvent(QDragLeaveEvent *e)
{
- // ### move implementation to dynamic
- Q_D(QListView);
- if (d->viewMode == IconMode) {
- d->viewport->update(d->dynamicListView->draggedItemsRect()); // erase the area
- d->dynamicListView->draggedItemsPos = QPoint(-1, -1); // don't draw the dragged items
- }
- QAbstractItemView::dragLeaveEvent(e);
+ if (!d_func()->commonListView->filterDragLeaveEvent(e))
+ QAbstractItemView::dragLeaveEvent(e);
}
/*!
\reimp
*/
-void QListView::dropEvent(QDropEvent *event)
+void QListView::dropEvent(QDropEvent *e)
{
- Q_D(QListView);
- if (event->source() == this && d->viewMode == IconMode)
- internalDrop(event); // ### move to dynamic
- else
- QAbstractItemView::dropEvent(event);
+ if (!d_func()->commonListView->filterDropEvent(e))
+ QAbstractItemView::dropEvent(e);
}
/*!
@@ -1005,10 +881,7 @@ void QListView::dropEvent(QDropEvent *event)
*/
void QListView::startDrag(Qt::DropActions supportedActions)
{
- Q_D(QListView);
- if (d->viewMode == IconMode) // ### move to dynamic
- internalDrag(supportedActions);
- else
+ if (!d_func()->commonListView->filterStartDrag(supportedActions))
QAbstractItemView::startDrag(supportedActions);
}
@@ -1020,41 +893,8 @@ void QListView::startDrag(Qt::DropActions supportedActions)
*/
void QListView::internalDrop(QDropEvent *event)
{
- Q_D(QListView);
- if (d->viewMode == QListView::ListMode)
- return;
-
- // ### move to dynamic class
- QPoint offset(horizontalOffset(), verticalOffset());
- QPoint end = event->pos() + offset;
- QPoint start = d->pressedPosition;
- QPoint delta = (d->movement == Snap ?
- d->dynamicListView->snapToGrid(end)
- - d->dynamicListView->snapToGrid(start) : end - start);
- QSize contents = d->contentsSize();
- QList<QModelIndex> indexes = d->selectionModel->selectedIndexes();
- for (int i = 0; i < indexes.count(); ++i) {
- QModelIndex index = indexes.at(i);
- QRect rect = rectForIndex(index);
- d->viewport->update(d->mapToViewport(rect, d->viewMode == QListView::ListMode));
- QPoint dest = rect.topLeft() + delta;
- if (isRightToLeft())
- dest.setX(d->flipX(dest.x()) - rect.width());
- d->dynamicListView->moveItem(index.row(), dest);
- update(index);
- }
- stopAutoScroll();
- d->dynamicListView->draggedItems.clear();
- emit indexesMoved(indexes);
- event->accept(); // we have handled the event
- // if the size has not grown, we need to check if it has shrinked
- if (d->dynamicListView
- && (d->contentsSize().width() <= contents.width()
- || d->contentsSize().height() <= contents.height())) {
- d->dynamicListView->updateContentsSize();
- }
- if (d->contentsSize() != contents)
- updateGeometries();
+ // ### Qt5: remove that function
+ Q_UNUSED(event);
}
/*!
@@ -1065,31 +905,8 @@ void QListView::internalDrop(QDropEvent *event)
*/
void QListView::internalDrag(Qt::DropActions supportedActions)
{
- Q_D(QListView);
- if (d->viewMode == QListView::ListMode)
- return;
-
- // #### move to dynamic class
-
- // This function does the same thing as in QAbstractItemView::startDrag(),
- // plus adding viewitems to the draggedItems list.
- // We need these items to draw the drag items
- QModelIndexList indexes = d->selectionModel->selectedIndexes();
- if (indexes.count() > 0 ) {
- if (d->viewport->acceptDrops()) {
- QModelIndexList::ConstIterator it = indexes.constBegin();
- for (; it != indexes.constEnd(); ++it)
- if (d->model->flags(*it) & Qt::ItemIsDragEnabled
- && (*it).column() == d->column)
- d->dynamicListView->draggedItems.push_back(*it);
- }
- QDrag *drag = new QDrag(this);
- drag->setMimeData(d->model->mimeData(indexes));
- Qt::DropAction action = drag->exec(supportedActions, Qt::CopyAction);
- d->dynamicListView->draggedItems.clear();
- if (action == Qt::MoveAction)
- d->clearOrRemove();
- }
+ // ### Qt5: remove that function
+ Q_UNUSED(supportedActions);
}
#endif // QT_NO_DRAGANDDROP
@@ -1117,6 +934,7 @@ QStyleOptionViewItem QListView::viewOptions() const
return option;
}
+
/*!
\reimp
*/
@@ -1213,18 +1031,7 @@ void QListView::paintEvent(QPaintEvent *e)
}
#ifndef QT_NO_DRAGANDDROP
- // #### move this implementation into a dynamic class
- if (d->viewMode == IconMode)
- if (!d->dynamicListView->draggedItems.isEmpty()
- && d->viewport->rect().contains(d->dynamicListView->draggedItemsPos)) {
- QPoint delta = d->dynamicListView->draggedItemsDelta();
- painter.translate(delta.x(), delta.y());
- d->dynamicListView->drawItems(&painter, d->dynamicListView->draggedItems);
- }
- // FIXME: Until the we can provide a proper drop indicator
- // in IconMode, it makes no sense to show it
- if (d->viewMode == ListMode)
- d->paintDropIndicator(&painter);
+ d->commonListView->paintDragDrop(&painter);
#endif
#ifndef QT_NO_RUBBERBAND
@@ -1263,31 +1070,7 @@ QModelIndex QListView::indexAt(const QPoint &p) const
*/
int QListView::horizontalOffset() const
{
- Q_D(const QListView);
- // ### split into static and dynamic
- if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem && d->viewMode == ListMode) {
- if (d->isWrapping()) {
- if (d->flow == TopToBottom && !d->staticListView->segmentPositions.isEmpty()) {
- const int max = d->staticListView->segmentPositions.count() - 1;
- int currentValue = qBound(0, horizontalScrollBar()->value(), max);
- int position = d->staticListView->segmentPositions.at(currentValue);
- int maximumValue = qBound(0, horizontalScrollBar()->maximum(), max);
- int maximum = d->staticListView->segmentPositions.at(maximumValue);
- return (isRightToLeft() ? maximum - position : position);
- }
- //return 0;
- } else {
- if (d->flow == LeftToRight && !d->staticListView->flowPositions.isEmpty()) {
- int position = d->staticListView->flowPositions.at(horizontalScrollBar()->value());
- int maximum = d->staticListView->flowPositions.at(horizontalScrollBar()->maximum());
- return (isRightToLeft() ? maximum - position : position);
- }
- //return 0;
- }
- }
- return (isRightToLeft()
- ? horizontalScrollBar()->maximum() - horizontalScrollBar()->value()
- : horizontalScrollBar()->value());
+ return d_func()->commonListView->horizontalOffset();
}
/*!
@@ -1295,30 +1078,7 @@ int QListView::horizontalOffset() const
*/
int QListView::verticalOffset() const
{
- // ## split into static and dynamic
- Q_D(const QListView);
- if (verticalScrollMode() == QAbstractItemView::ScrollPerItem && d->viewMode == ListMode) {
- if (d->isWrapping()) {
- if (d->flow == LeftToRight && !d->staticListView->segmentPositions.isEmpty()) {
- int value = verticalScrollBar()->value();
- if (value >= d->staticListView->segmentPositions.count()) {
- //qWarning("QListView: Vertical scroll bar is out of bounds");
- return 0;
- }
- return d->staticListView->segmentPositions.at(value);
- }
- } else {
- if (d->flow == TopToBottom && !d->staticListView->flowPositions.isEmpty()) {
- int value = verticalScrollBar()->value();
- if (value > d->staticListView->flowPositions.count()) {
- //qWarning("QListView: Vertical scroll bar is out of bounds");
- return 0;
- }
- return d->staticListView->flowPositions.at(value) - d->spacing();
- }
- }
- }
- return verticalScrollBar()->value();
+ return d_func()->commonListView->verticalOffset();
}
/*!
@@ -1444,15 +1204,7 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
*/
QRect QListView::rectForIndex(const QModelIndex &index) const
{
- Q_D(const QListView);
- if (!d->isIndexValid(index)
- || index.parent() != d->root
- || index.column() != d->column
- || isIndexHidden(index))
- return QRect();
- d->executePostedLayout();
- QListViewItem item = d->indexToListViewItem(index);
- return d->viewItemRect(item);
+ return d_func()->rectForIndex(index);
}
/*!
@@ -1460,8 +1212,8 @@ QRect QListView::rectForIndex(const QModelIndex &index) const
Sets the contents position of the item at \a index in the model to the given
\a position.
- If the list view's movement mode is Static, this function will have no
- effect.
+ If the list view's movement mode is Static or its view mode is ListView,
+ this function will have no effect.
*/
void QListView::setPositionForIndex(const QPoint &position, const QModelIndex &index)
{
@@ -1473,15 +1225,7 @@ void QListView::setPositionForIndex(const QPoint &position, const QModelIndex &i
return;
d->executePostedLayout();
- if (index.row() >= d->dynamicListView->items.count())
- return;
- const QSize oldContents = d->contentsSize();
- update(index); // update old position
- d->dynamicListView->moveItem(index.row(), position);
- update(index); // update new position
-
- if (d->contentsSize() != oldContents)
- updateGeometries(); // update the scroll bars
+ d->commonListView->setPositionForIndex(position, index);
}
/*!
@@ -1717,99 +1461,8 @@ void QListView::updateGeometries()
QModelIndex index = d->model->index(0, d->column, d->root);
QStyleOptionViewItemV4 option = d->viewOptionsV4();
QSize step = d->itemSize(option, index);
-
- QSize csize = d->contentsSize();
- QSize vsize = d->viewport->size();
- QSize max = maximumViewportSize();
- if (max.width() >= d->contentsSize().width() && max.height() >= d->contentsSize().height())
- vsize = max;
-
- // ### reorder the logic
-
- // ### split into static and dynamic
-
- const bool vertical = verticalScrollMode() == QAbstractItemView::ScrollPerItem;
- const bool horizontal = horizontalScrollMode() == QAbstractItemView::ScrollPerItem;
-
- if (d->flow == TopToBottom) {
- if (horizontal && d->isWrapping() && d->viewMode == ListMode) {
- const QVector<int> segmentPositions = d->staticListView->segmentPositions;
- const int steps = segmentPositions.count() - 1;
- if (steps > 0) {
- int pageSteps = d->staticListView->perItemScrollingPageSteps(vsize.width(),
- csize.width(),
- isWrapping());
- horizontalScrollBar()->setSingleStep(1);
- horizontalScrollBar()->setPageStep(pageSteps);
- horizontalScrollBar()->setRange(0, steps - pageSteps);
- } else {
- horizontalScrollBar()->setRange(0, 0);
- }
- } else {
- horizontalScrollBar()->setSingleStep(step.width() + d->spacing());
- horizontalScrollBar()->setPageStep(vsize.width());
- horizontalScrollBar()->setRange(0, d->contentsSize().width() - vsize.width());
- }
- if (vertical && !d->isWrapping() && d->viewMode == ListMode) {
- const QVector<int> flowPositions = d->staticListView->flowPositions;
- const int steps = flowPositions.count() - 1;
- if (steps > 0) {
- int pageSteps = d->staticListView->perItemScrollingPageSteps(vsize.height(),
- csize.height(),
- isWrapping());
- verticalScrollBar()->setSingleStep(1);
- verticalScrollBar()->setPageStep(pageSteps);
- verticalScrollBar()->setRange(0, steps - pageSteps);
- } else {
- verticalScrollBar()->setRange(0, 0);
- }
- // } else if (vertical && d->isWrapping() && d->movement == Static) {
- // ### wrapped scrolling in flow direction
- } else {
- verticalScrollBar()->setSingleStep(step.height() + d->spacing());
- verticalScrollBar()->setPageStep(vsize.height());
- verticalScrollBar()->setRange(0, d->contentsSize().height() - vsize.height());
- }
- } else { // LeftToRight
- if (horizontal && !d->isWrapping() && d->viewMode == ListMode) {
- const QVector<int> flowPositions = d->staticListView->flowPositions;
- int steps = flowPositions.count() - 1;
- if (steps > 0) {
- int pageSteps = d->staticListView->perItemScrollingPageSteps(vsize.width(),
- csize.width(),
- isWrapping());
- horizontalScrollBar()->setSingleStep(1);
- horizontalScrollBar()->setPageStep(pageSteps);
- horizontalScrollBar()->setRange(0, steps - pageSteps);
- } else {
- horizontalScrollBar()->setRange(0, 0);
- }
- // } else if (horizontal && d->isWrapping() && d->movement == Static) {
- // ### wrapped scrolling in flow direction
- } else {
- horizontalScrollBar()->setSingleStep(step.width() + d->spacing());
- horizontalScrollBar()->setPageStep(vsize.width());
- horizontalScrollBar()->setRange(0, d->contentsSize().width() - vsize.width());
- }
- if (vertical && d->isWrapping() && d->viewMode == ListMode) {
- const QVector<int> segmentPositions = d->staticListView->segmentPositions;
- int steps = segmentPositions.count() - 1;
- if (steps > 0) {
- int pageSteps = d->staticListView->perItemScrollingPageSteps(vsize.height(),
- csize.height(),
- isWrapping());
- verticalScrollBar()->setSingleStep(1);
- verticalScrollBar()->setPageStep(pageSteps);
- verticalScrollBar()->setRange(0, steps - pageSteps);
- } else {
- verticalScrollBar()->setRange(0, 0);
- }
- } else {
- verticalScrollBar()->setSingleStep(step.height() + d->spacing());
- verticalScrollBar()->setPageStep(vsize.height());
- verticalScrollBar()->setRange(0, d->contentsSize().height() - vsize.height());
- }
- }
+ d->commonListView->updateHorizontalScrollBar(step);
+ d->commonListView->updateVerticalScrollBar(step);
}
QAbstractItemView::updateGeometries();
@@ -1958,14 +1611,14 @@ bool QListView::event(QEvent *e)
QListViewPrivate::QListViewPrivate()
: QAbstractItemViewPrivate(),
- dynamicListView(0),
+ commonListView(0),
wrap(false),
space(0),
flow(QListView::TopToBottom),
movement(QListView::Static),
resizeMode(QListView::Fixed),
layoutMode(QListView::SinglePass),
- viewMode(QListView::IconMode), //this will ensure the first initialization to ListView
+ viewMode(QListView::ListMode),
modeProperties(0),
column(0),
uniformItemSizes(false),
@@ -1976,21 +1629,14 @@ QListViewPrivate::QListViewPrivate()
QListViewPrivate::~QListViewPrivate()
{
- if (viewMode == QListView::ListMode)
- delete staticListView;
- else
- delete dynamicListView;
+ delete commonListView;
}
void QListViewPrivate::clear()
{
- // ### split into dynamic and static
// initialization of data structs
cachedItemSize = QSize();
- if (viewMode == QListView::ListMode)
- staticListView->clear();
- else
- dynamicListView->clear();
+ commonListView->clear();
}
void QListViewPrivate::prepareItemsLayout()
@@ -1999,7 +1645,7 @@ void QListViewPrivate::prepareItemsLayout()
clear();
//take the size as if there were scrollbar in order to prevent scrollbar to blink
- layoutBounds = QRect(QPoint(0,0), q->maximumViewportSize());
+ layoutBounds = QRect(QPoint(), q->maximumViewportSize());
int frameAroundContents = 0;
if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents))
@@ -2017,15 +1663,8 @@ void QListViewPrivate::prepareItemsLayout()
layoutBounds.adjust(0, 0, -verticalMargin, -horizontalMargin);
- int rowCount = model->rowCount(root);
- int colCount = model->columnCount(root);
- if (colCount <= 0)
- rowCount = 0; // no contents
- if (viewMode == QListView::ListMode) {
- staticListView->flowPositions.resize(rowCount);
- } else {
- dynamicListView->tree.create(qMax(rowCount - hiddenRows.count(), 0));
- }
+ int rowCount = model->columnCount(root) <= 0 ? 0 : model->rowCount(root);
+ commonListView->setRowCount(rowCount);
}
/*!
@@ -2033,7 +1672,6 @@ void QListViewPrivate::prepareItemsLayout()
*/
bool QListViewPrivate::doItemsLayout(int delta)
{
- // ### split into static and dynamic
int max = model->rowCount(root) - 1;
int first = batchStartRow();
int last = qMin(first + delta - 1, max);
@@ -2057,9 +1695,7 @@ bool QListViewPrivate::doItemsLayout(int delta)
info.flow = flow;
info.max = max;
- if (viewMode == QListView::ListMode)
- return staticListView->doBatchedItemLayout(info, max);
- return dynamicListView->doBatchedItemLayout(info, max);
+ return commonListView->doBatchedItemLayout(info, max);
}
QListViewItem QListViewPrivate::indexToListViewItem(const QModelIndex &index) const
@@ -2067,29 +1703,16 @@ QListViewItem QListViewPrivate::indexToListViewItem(const QModelIndex &index) co
if (!index.isValid() || isHidden(index.row()))
return QListViewItem();
- if (viewMode == QListView::ListMode)
- return staticListView->indexToListViewItem(index);
- return dynamicListView->indexToListViewItem(index);
+ return commonListView->indexToListViewItem(index);
}
-
-int QListViewPrivate::itemIndex(const QListViewItem &item) const
-{
- if (viewMode == QListView::ListMode)
- return staticListView->itemIndex(item);
- return dynamicListView->itemIndex(item);
-}
-
-QRect QListViewPrivate::mapToViewport(const QRect &rect, bool greedy) const
+QRect QListViewPrivate::mapToViewport(const QRect &rect, bool extend) const
{
Q_Q(const QListView);
if (!rect.isValid())
return rect;
- QRect result = rect;
- if (greedy)
- result = staticListView->mapToViewport(rect);
-
+ QRect result = extend ? commonListView->mapToViewport(rect) : rect;
int dx = -q->horizontalOffset();
int dy = -q->verticalOffset();
result.adjust(dx, dy, dx, dy);
@@ -2177,46 +1800,217 @@ QItemSelection QListViewPrivate::selection(const QRect &rect) const
}
/*
- * Static ListView Implementation
+ * Common ListView Implementation
*/
-int QStaticListViewBase::verticalPerItemValue(int itemIndex, int verticalValue, int areaHeight,
- bool above, bool below, bool wrap,
- QListView::ScrollHint hint, int itemHeight) const
+void QCommonListViewBase::appendHiddenRow(int row)
+{
+ dd->hiddenRows.append(dd->model->index(row, 0));
+}
+
+void QCommonListViewBase::removeHiddenRow(int row)
{
- int value = qBound(0, verticalValue, flowPositions.count() - 1);
- if (above)
- return perItemScrollToValue(itemIndex, value, areaHeight, QListView::PositionAtTop,
- Qt::Vertical,wrap, itemHeight);
- else if (below)
- return perItemScrollToValue(itemIndex, value, areaHeight, QListView::PositionAtBottom,
- Qt::Vertical, wrap, itemHeight);
- else if (hint != QListView::EnsureVisible)
- return perItemScrollToValue(itemIndex, value, areaHeight, hint, Qt::Vertical, wrap, itemHeight);
- return value;
+ dd->hiddenRows.remove(dd->hiddenRows.indexOf(dd->model->index(row, 0)));
}
-int QStaticListViewBase::horizontalPerItemValue(int itemIndex, int horizontalValue, int areaWidth,
- bool leftOf, bool rightOf, bool wrap,
- QListView::ScrollHint hint, int itemWidth) const
+void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
{
- int value = qBound(0, horizontalValue, flowPositions.count() - 1);
+ horizontalScrollBar()->setSingleStep(step.width() + spacing());
+ horizontalScrollBar()->setPageStep(viewport()->width());
+ horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width());
+}
+
+void QCommonListViewBase::updateVerticalScrollBar(const QSize &step)
+{
+ verticalScrollBar()->setSingleStep(step.height() + spacing());
+ verticalScrollBar()->setPageStep(viewport()->height());
+ verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height());
+}
+
+void QCommonListViewBase::scrollContentsBy(int dx, int dy, bool /*scrollElasticBand*/)
+{
+ dd->scrollContentsBy(isRightToLeft() ? -dx : dx, dy);
+}
+
+int QCommonListViewBase::verticalScrollToValue(int /*index*/, QListView::ScrollHint hint,
+ bool above, bool below, const QRect &area, const QRect &rect) const
+{
+ int verticalValue = verticalScrollBar()->value();
+ QRect adjusted = rect.adjusted(-spacing(), -spacing(), spacing(), spacing());
+ if (hint == QListView::PositionAtTop || above)
+ verticalValue += adjusted.top();
+ else if (hint == QListView::PositionAtBottom || below)
+ verticalValue += qMin(adjusted.top(), adjusted.bottom() - area.height() + 1);
+ else if (hint == QListView::PositionAtCenter)
+ verticalValue += adjusted.top() - ((area.height() - adjusted.height()) / 2);
+ return verticalValue;
+}
+
+int QCommonListViewBase::horizontalOffset() const
+{
+ return (isRightToLeft() ? horizontalScrollBar()->maximum() - horizontalScrollBar()->value() : horizontalScrollBar()->value());
+}
+
+int QCommonListViewBase::horizontalScrollToValue(const int /*index*/, QListView::ScrollHint hint,
+ bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const
+{
+ int horizontalValue = horizontalScrollBar()->value();
+ if (isRightToLeft()) {
+ if (hint == QListView::PositionAtCenter) {
+ horizontalValue += ((area.width() - rect.width()) / 2) - rect.left();
+ } else {
+ if (leftOf)
+ horizontalValue -= rect.left();
+ else if (rightOf)
+ horizontalValue += qMin(rect.left(), area.width() - rect.right());
+ }
+ } else {
+ if (hint == QListView::PositionAtCenter) {
+ horizontalValue += rect.left() - ((area.width()- rect.width()) / 2);
+ } else {
+ if (leftOf)
+ horizontalValue += rect.left();
+ else if (rightOf)
+ horizontalValue += qMin(rect.left(), rect.right() - area.width());
+ }
+ }
+ return horizontalValue;
+}
+
+/*
+ * ListMode ListView Implementation
+*/
+
+#ifndef QT_NO_DRAGANDDROP
+void QListModeViewBase::paintDragDrop(QPainter *painter)
+{
+ // FIXME: Until the we can provide a proper drop indicator
+ // in IconMode, it makes no sense to show it
+ dd->paintDropIndicator(painter);
+}
+#endif //QT_NO_DRAGANDDROP
+
+void QListModeViewBase::updateVerticalScrollBar(const QSize &step)
+{
+ if (verticalScrollMode() == QAbstractItemView::ScrollPerItem
+ && ((flow() == QListView::TopToBottom && !isWrapping())
+ || (flow() == QListView::LeftToRight && isWrapping()))) {
+ const int steps = (flow() == QListView::TopToBottom ? flowPositions : segmentPositions).count() - 1;
+ if (steps > 0) {
+ const int pageSteps = perItemScrollingPageSteps(viewport()->height(), contentsSize.height(), isWrapping());
+ verticalScrollBar()->setSingleStep(1);
+ verticalScrollBar()->setPageStep(pageSteps);
+ verticalScrollBar()->setRange(0, steps - pageSteps);
+ } else {
+ verticalScrollBar()->setRange(0, 0);
+ }
+ // } else if (vertical && d->isWrapping() && d->movement == Static) {
+ // ### wrapped scrolling in flow direction
+ } else {
+ QCommonListViewBase::updateVerticalScrollBar(step);
+ }
+}
+
+void QListModeViewBase::updateHorizontalScrollBar(const QSize &step)
+{
+ if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem
+ && ((flow() == QListView::TopToBottom && isWrapping())
+ || (flow() == QListView::LeftToRight && !isWrapping()))) {
+ int steps = (flow() == QListView::TopToBottom ? segmentPositions : flowPositions).count() - 1;
+ if (steps > 0) {
+ const int pageSteps = perItemScrollingPageSteps(viewport()->width(), contentsSize.width(), isWrapping());
+ horizontalScrollBar()->setSingleStep(1);
+ horizontalScrollBar()->setPageStep(pageSteps);
+ horizontalScrollBar()->setRange(0, steps - pageSteps);
+ } else {
+ horizontalScrollBar()->setRange(0, 0);
+ }
+ } else {
+ QCommonListViewBase::updateHorizontalScrollBar(step);
+ }
+}
+
+int QListModeViewBase::verticalScrollToValue(int index, QListView::ScrollHint hint,
+ bool above, bool below, const QRect &area, const QRect &rect) const
+{
+ if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
+ int value = qBound(0, verticalScrollBar()->value(), flowPositions.count() - 1);
+ if (above)
+ hint = QListView::PositionAtTop;
+ else if (below)
+ hint = QListView::PositionAtBottom;
+ if (hint == QListView::EnsureVisible)
+ return value;
+
+ return perItemScrollToValue(index, value, area.height(), hint, Qt::Vertical, isWrapping(), rect.height());
+ }
+
+ return QCommonListViewBase::verticalScrollToValue(index, hint, above, below, area, rect);
+}
+
+int QListModeViewBase::horizontalOffset() const
+{
+ if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
+ if (isWrapping()) {
+ if (flow() == QListView::TopToBottom && !segmentPositions.isEmpty()) {
+ const int max = segmentPositions.count() - 1;
+ int currentValue = qBound(0, horizontalScrollBar()->value(), max);
+ int position = segmentPositions.at(currentValue);
+ int maximumValue = qBound(0, horizontalScrollBar()->maximum(), max);
+ int maximum = segmentPositions.at(maximumValue);
+ return (isRightToLeft() ? maximum - position : position);
+ }
+ } else if (flow() == QListView::LeftToRight && !flowPositions.isEmpty()) {
+ int position = flowPositions.at(horizontalScrollBar()->value());
+ int maximum = flowPositions.at(horizontalScrollBar()->maximum());
+ return (isRightToLeft() ? maximum - position : position);
+ }
+ }
+ return QCommonListViewBase::horizontalOffset();
+}
+
+int QListModeViewBase::verticalOffset() const
+{
+ if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
+ if (isWrapping()) {
+ if (flow() == QListView::LeftToRight && !segmentPositions.isEmpty()) {
+ int value = verticalScrollBar()->value();
+ if (value >= segmentPositions.count())
+ return 0;
+ return segmentPositions.at(value);
+ }
+ } else if (flow() == QListView::TopToBottom && !flowPositions.isEmpty()) {
+ int value = verticalScrollBar()->value();
+ if (value > flowPositions.count())
+ return 0;
+ return flowPositions.at(value) - spacing();
+ }
+ }
+ return QCommonListViewBase::verticalOffset();
+}
+
+int QListModeViewBase::horizontalScrollToValue(int index, QListView::ScrollHint hint,
+ bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const
+{
+ if (horizontalScrollMode() != QAbstractItemView::ScrollPerItem)
+ return QCommonListViewBase::horizontalScrollToValue(index, hint, leftOf, rightOf, area, rect);
+
+ int value = qBound(0, horizontalScrollBar()->value(), flowPositions.count() - 1);
if (leftOf)
- return perItemScrollToValue(itemIndex, value, areaWidth, QListView::PositionAtTop,
- Qt::Horizontal, wrap, itemWidth);
+ hint = QListView::PositionAtTop;
else if (rightOf)
- return perItemScrollToValue(itemIndex, value, areaWidth, QListView::PositionAtBottom,
- Qt::Horizontal, wrap, itemWidth);
- else if (hint != QListView::EnsureVisible)
- return perItemScrollToValue(itemIndex, value, areaWidth, hint, Qt::Horizontal, wrap, itemWidth);
- return value;
+ hint = QListView::PositionAtBottom;
+ if (hint == QListView::EnsureVisible)
+ return value;
+
+ return perItemScrollToValue(index, value, area.width(), hint, Qt::Horizontal, isWrapping(), rect.width());
}
-void QStaticListViewBase::scrollContentsBy(int &dx, int &dy)
+void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
{
// ### reorder this logic
- const int verticalValue = verticalScrollBarValue();
- const int horizontalValue = horizontalScrollBarValue();
+ const int verticalValue = verticalScrollBar()->value();
+ const int horizontalValue = horizontalScrollBar()->value();
const bool vertical = (verticalScrollMode() == QAbstractItemView::ScrollPerItem);
const bool horizontal = (horizontalScrollMode() == QAbstractItemView::ScrollPerItem);
@@ -2255,9 +2049,10 @@ void QStaticListViewBase::scrollContentsBy(int &dx, int &dy)
dx = previousCoordinate - currentCoordinate;
}
}
+ QCommonListViewBase::scrollContentsBy(dx, dy, scrollElasticBand);
}
-bool QStaticListViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)
+bool QListModeViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)
{
doStaticLayout(info);
if (batchStartRow > max) { // stop items layout
@@ -2269,7 +2064,7 @@ bool QStaticListViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, i
return false; // not done
}
-QListViewItem QStaticListViewBase::indexToListViewItem(const QModelIndex &index) const
+QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) const
{
if (flowPositions.isEmpty()
|| segmentPositions.isEmpty()
@@ -2305,7 +2100,7 @@ QListViewItem QStaticListViewBase::indexToListViewItem(const QModelIndex &index)
return QListViewItem(QRect(pos, size), index.row());
}
-QPoint QStaticListViewBase::initStaticLayout(const QListViewLayoutInfo &info)
+QPoint QListModeViewBase::initStaticLayout(const QListViewLayoutInfo &info)
{
int x, y;
if (info.first == 0) {
@@ -2340,7 +2135,7 @@ QPoint QStaticListViewBase::initStaticLayout(const QListViewLayoutInfo &info)
/*!
\internal
*/
-void QStaticListViewBase::doStaticLayout(const QListViewLayoutInfo &info)
+void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
{
const bool useItemSize = !info.grid.isValid();
const QPoint topLeft = initStaticLayout(info);
@@ -2443,7 +2238,7 @@ void QStaticListViewBase::doStaticLayout(const QListViewLayoutInfo &info)
Finds the set of items intersecting with \a area.
In this function, itemsize is counted from topleft to the start of the next item.
*/
-QVector<QModelIndex> QStaticListViewBase::intersectingStaticSet(const QRect &area) const
+QVector<QModelIndex> QListModeViewBase::intersectingSet(const QRect &area) const
{
QVector<QModelIndex> ret;
int segStartPosition;
@@ -2480,19 +2275,14 @@ QVector<QModelIndex> QStaticListViewBase::intersectingStaticSet(const QRect &are
ret += index;
#if 0 // for debugging
else
- qWarning("intersectingStaticSet: row %d was invalid", row);
+ qWarning("intersectingSet: row %d was invalid", row);
#endif
}
}
return ret;
}
-int QStaticListViewBase::itemIndex(const QListViewItem &item) const
-{
- return item.indexHint;
-}
-
-QRect QStaticListViewBase::mapToViewport(const QRect &rect) const
+QRect QListModeViewBase::mapToViewport(const QRect &rect) const
{
if (isWrapping())
return rect;
@@ -2510,7 +2300,7 @@ QRect QStaticListViewBase::mapToViewport(const QRect &rect) const
return result;
}
-int QStaticListViewBase::perItemScrollingPageSteps(int length, int bounds, bool wrap) const
+int QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wrap) const
{
const QVector<int> positions = (wrap ? segmentPositions : flowPositions);
if (positions.isEmpty() || bounds <= length)
@@ -2538,7 +2328,7 @@ int QStaticListViewBase::perItemScrollingPageSteps(int length, int bounds, bool
return qMax(pageSteps, 1);
}
-int QStaticListViewBase::perItemScrollToValue(int index, int scrollValue, int viewportSize,
+int QListModeViewBase::perItemScrollToValue(int index, int scrollValue, int viewportSize,
QAbstractItemView::ScrollHint hint,
Qt::Orientation orientation, bool wrap, int itemExtent) const
{
@@ -2598,7 +2388,7 @@ int QStaticListViewBase::perItemScrollToValue(int index, int scrollValue, int vi
return scrollValue;
}
-void QStaticListViewBase::clear()
+void QListModeViewBase::clear()
{
flowPositions.clear();
segmentPositions.clear();
@@ -2610,10 +2400,175 @@ void QStaticListViewBase::clear()
}
/*
- * Dynamic ListView Implementation
+ * IconMode ListView Implementation
*/
-void QDynamicListViewBase::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+void QIconModeViewBase::setPositionForIndex(const QPoint &position, const QModelIndex &index)
+{
+ if (index.row() >= items.count())
+ return;
+ const QSize oldContents = contentsSize;
+ qq->update(index); // update old position
+ moveItem(index.row(), position);
+ qq->update(index); // update new position
+
+ if (contentsSize != oldContents)
+ dd->viewUpdateGeometries(); // update the scroll bars
+}
+
+void QIconModeViewBase::appendHiddenRow(int row)
+{
+ if (row >= 0 && row < items.count()) //remove item
+ tree.removeLeaf(items.at(row).rect(), row);
+ QCommonListViewBase::appendHiddenRow(row);
+}
+
+void QIconModeViewBase::removeHiddenRow(int row)
+{
+ QCommonListViewBase::appendHiddenRow(row);
+ if (row >= 0 && row < items.count()) //insert item
+ tree.insertLeaf(items.at(row).rect(), row);
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QIconModeViewBase::paintDragDrop(QPainter *painter)
+{
+ if (!draggedItems.isEmpty() && viewport()->rect().contains(draggedItemsPos)) {
+ //we need to draw the items that arre dragged
+ painter->translate(draggedItemsDelta());
+ QStyleOptionViewItemV4 option = viewOptions();
+ option.state &= ~QStyle::State_MouseOver;
+ QVector<QModelIndex>::const_iterator it = draggedItems.begin();
+ QListViewItem item = indexToListViewItem(*it);
+ for (; it != draggedItems.end(); ++it) {
+ item = indexToListViewItem(*it);
+ option.rect = viewItemRect(item);
+ delegate(*it)->paint(painter, option, *it);
+ }
+ }
+}
+
+bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions)
+{
+ // This function does the same thing as in QAbstractItemView::startDrag(),
+ // plus adding viewitems to the draggedItems list.
+ // We need these items to draw the drag items
+ QModelIndexList indexes = dd->selectionModel->selectedIndexes();
+ if (indexes.count() > 0 ) {
+ if (viewport()->acceptDrops()) {
+ QModelIndexList::ConstIterator it = indexes.constBegin();
+ for (; it != indexes.constEnd(); ++it)
+ if (dd->model->flags(*it) & Qt::ItemIsDragEnabled
+ && (*it).column() == dd->column)
+ draggedItems.push_back(*it);
+ }
+ QDrag *drag = new QDrag(qq);
+ drag->setMimeData(dd->model->mimeData(indexes));
+ Qt::DropAction action = drag->exec(supportedActions, Qt::CopyAction);
+ draggedItems.clear();
+ if (action == Qt::MoveAction)
+ dd->clearOrRemove();
+ }
+ return true;
+}
+
+bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
+{
+ if (e->source() != qq)
+ return false;
+
+ const QSize contents = contentsSize;
+ QPoint offset(horizontalOffset(), verticalOffset());
+ QPoint end = e->pos() + offset;
+ QPoint start = dd->pressedPosition;
+ QPoint delta = (dd->movement == QListView::Snap ? snapToGrid(end) - snapToGrid(start) : end - start);
+ QList<QModelIndex> indexes = dd->selectionModel->selectedIndexes();
+ for (int i = 0; i < indexes.count(); ++i) {
+ QModelIndex index = indexes.at(i);
+ QRect rect = dd->rectForIndex(index);
+ viewport()->update(mapToViewport(rect));
+ QPoint dest = rect.topLeft() + delta;
+ if (qq->isRightToLeft())
+ dest.setX(dd->flipX(dest.x()) - rect.width());
+ moveItem(index.row(), dest);
+ qq->update(index);
+ }
+ dd->stopAutoScroll();
+ draggedItems.clear();
+ dd->emitIndexesMoved(indexes);
+ e->accept(); // we have handled the event
+ // if the size has not grown, we need to check if it has shrinked
+ if (contentsSize != contents) {
+ if ((contentsSize.width() <= contents.width()
+ || contentsSize.height() <= contents.height())) {
+ updateContentsSize();
+ }
+ dd->viewUpdateGeometries();
+ }
+ return true;
+}
+
+bool QIconModeViewBase::filterDragLeaveEvent(QDragLeaveEvent *e)
+{
+ viewport()->update(draggedItemsRect()); // erase the area
+ draggedItemsPos = QPoint(-1, -1); // don't draw the dragged items
+ return QCommonListViewBase::filterDragLeaveEvent(e);
+}
+
+bool QIconModeViewBase::filterDragMoveEvent(QDragMoveEvent *e)
+{
+ if (e->source() != qq || !dd->canDecode(e))
+ return false;
+
+ // ignore by default
+ e->ignore();
+ // get old dragged items rect
+ QRect itemsRect = this->itemsRect(draggedItems);
+ viewport()->update(itemsRect.translated(draggedItemsDelta()));
+ // update position
+ draggedItemsPos = e->pos();
+ // get new items rect
+ viewport()->update(itemsRect.translated(draggedItemsDelta()));
+ // set the item under the cursor to current
+ QModelIndex index;
+ if (movement() == QListView::Snap) {
+ QRect rect(snapToGrid(e->pos() + offset()), gridSize());
+ const QVector<QModelIndex> intersectVector = intersectingSet(rect);
+ index = intersectVector.count() > 0 ? intersectVector.last() : QModelIndex();
+ } else {
+ index = qq->indexAt(e->pos());
+ }
+ // check if we allow drops here
+ if (draggedItems.contains(index))
+ e->accept(); // allow changing item position
+ else if (dd->model->flags(index) & Qt::ItemIsDropEnabled)
+ e->accept(); // allow dropping on dropenabled items
+ else if (!index.isValid())
+ e->accept(); // allow dropping in empty areas
+
+ // the event was treated. do autoscrolling
+ if (dd->shouldAutoScroll(e->pos()))
+ dd->startAutoScroll();
+ return true;
+}
+#endif // QT_NO_DRAGANDDROP
+
+void QIconModeViewBase::setRowCount(int rowCount)
+{
+ tree.create(qMax(rowCount - hiddenCount(), 0));
+}
+
+void QIconModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
+{
+ if (scrollElasticBand)
+ dd->scrollElasticBandBy(isRightToLeft() ? -dx : dx, dy);
+
+ QCommonListViewBase::scrollContentsBy(dx, dy, scrollElasticBand);
+ if (!draggedItems.isEmpty())
+ viewport()->update(draggedItemsRect().translated(dx, dy));
+}
+
+void QIconModeViewBase::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
if (column() >= topLeft.column() && column() <= bottomRight.column()) {
QStyleOptionViewItemV4 option = viewOptions();
@@ -2623,23 +2578,29 @@ void QDynamicListViewBase::dataChanged(const QModelIndex &topLeft, const QModelI
}
}
-bool QDynamicListViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)
+bool QIconModeViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)
{
if (info.last >= items.count()) {
- createItems(info.last + 1);
+ //first we create the items
+ QStyleOptionViewItemV4 option = viewOptions();
+ for (int row = items.count(); row <= info.last; ++row) {
+ QSize size = itemSize(option, modelIndex(row));
+ QListViewItem item(QRect(0, 0, size.width(), size.height()), row); // default pos
+ items.append(item);
+ }
doDynamicLayout(info);
}
return (batchStartRow > max); // done
}
-QListViewItem QDynamicListViewBase::indexToListViewItem(const QModelIndex &index) const
+QListViewItem QIconModeViewBase::indexToListViewItem(const QModelIndex &index) const
{
if (index.isValid() && index.row() < items.count())
return items.at(index.row());
return QListViewItem();
}
-void QDynamicListViewBase::initBspTree(const QSize &contents)
+void QIconModeViewBase::initBspTree(const QSize &contents)
{
// remove all items from the tree
int leafCount = tree.leafCount();
@@ -2656,7 +2617,7 @@ void QDynamicListViewBase::initBspTree(const QSize &contents)
tree.init(QRect(0, 0, contents.width(), contents.height()), type);
}
-QPoint QDynamicListViewBase::initDynamicLayout(const QListViewLayoutInfo &info)
+QPoint QIconModeViewBase::initDynamicLayout(const QListViewLayoutInfo &info)
{
int x, y;
if (info.first == 0) {
@@ -2678,7 +2639,7 @@ QPoint QDynamicListViewBase::initDynamicLayout(const QListViewLayoutInfo &info)
/*!
\internal
*/
-void QDynamicListViewBase::doDynamicLayout(const QListViewLayoutInfo &info)
+void QIconModeViewBase::doDynamicLayout(const QListViewLayoutInfo &info)
{
const bool useItemSize = !info.grid.isValid();
const QPoint topLeft = initDynamicLayout(info);
@@ -2712,7 +2673,7 @@ void QDynamicListViewBase::doDynamicLayout(const QListViewLayoutInfo &info)
if (moved.count() != items.count())
moved.resize(items.count());
- QRect rect(QPoint(0, 0), topLeft);
+ QRect rect(QPoint(), topLeft);
QListViewItem *item = 0;
for (int row = info.first; row <= info.last; ++row) {
item = &items[row];
@@ -2805,43 +2766,18 @@ void QDynamicListViewBase::doDynamicLayout(const QListViewLayoutInfo &info)
viewport()->update();
}
-QVector<QModelIndex> QDynamicListViewBase::intersectingDynamicSet(const QRect &area) const
+QVector<QModelIndex> QIconModeViewBase::intersectingSet(const QRect &area) const
{
- QDynamicListViewBase *that = const_cast<QDynamicListViewBase*>(this);
+ QIconModeViewBase *that = const_cast<QIconModeViewBase*>(this);
QBspTree::Data data(static_cast<void*>(that));
QVector<QModelIndex> res;
that->interSectingVector = &res;
- that->tree.climbTree(area, &QDynamicListViewBase::addLeaf, data);
+ that->tree.climbTree(area, &QIconModeViewBase::addLeaf, data);
that->interSectingVector = 0;
return res;
}
-void QDynamicListViewBase::createItems(int to)
-{
- int count = items.count();
- QSize size;
- QStyleOptionViewItemV4 option = viewOptions();
- for (int row = count; row < to; ++row) {
- size = itemSize(option, modelIndex(row));
- QListViewItem item(QRect(0, 0, size.width(), size.height()), row); // default pos
- items.append(item);
- }
-}
-
-void QDynamicListViewBase::drawItems(QPainter *painter, const QVector<QModelIndex> &indexes) const
-{
- QStyleOptionViewItemV4 option = viewOptions();
- option.state &= ~QStyle::State_MouseOver;
- QVector<QModelIndex>::const_iterator it = indexes.begin();
- QListViewItem item = indexToListViewItem(*it);
- for (; it != indexes.end(); ++it) {
- item = indexToListViewItem(*it);
- option.rect = viewItemRect(item);
- delegate(*it)->paint(painter, option, *it);
- }
-}
-
-QRect QDynamicListViewBase::itemsRect(const QVector<QModelIndex> &indexes) const
+QRect QIconModeViewBase::itemsRect(const QVector<QModelIndex> &indexes) const
{
QVector<QModelIndex>::const_iterator it = indexes.begin();
QListViewItem item = indexToListViewItem(*it);
@@ -2853,7 +2789,7 @@ QRect QDynamicListViewBase::itemsRect(const QVector<QModelIndex> &indexes) const
return rect;
}
-int QDynamicListViewBase::itemIndex(const QListViewItem &item) const
+int QIconModeViewBase::itemIndex(const QListViewItem &item) const
{
if (!item.isValid())
return -1;
@@ -2889,11 +2825,11 @@ int QDynamicListViewBase::itemIndex(const QListViewItem &item) const
return -1;
}
-void QDynamicListViewBase::addLeaf(QVector<int> &leaf, const QRect &area,
+void QIconModeViewBase::addLeaf(QVector<int> &leaf, const QRect &area,
uint visited, QBspTree::Data data)
{
QListViewItem *vi;
- QDynamicListViewBase *_this = static_cast<QDynamicListViewBase *>(data.ptr);
+ QIconModeViewBase *_this = static_cast<QIconModeViewBase *>(data.ptr);
for (int i = 0; i < leaf.count(); ++i) {
int idx = leaf.at(i);
if (idx < 0 || idx >= _this->items.count())
@@ -2909,19 +2845,7 @@ void QDynamicListViewBase::addLeaf(QVector<int> &leaf, const QRect &area,
}
}
-void QDynamicListViewBase::insertItem(int index)
-{
- if (index >= 0 && index < items.count())
- tree.insertLeaf(items.at(index).rect(), index);
-}
-
-void QDynamicListViewBase::removeItem(int index)
-{
- if (index >= 0 && index < items.count())
- tree.removeLeaf(items.at(index).rect(), index);
-}
-
-void QDynamicListViewBase::moveItem(int index, const QPoint &dest)
+void QIconModeViewBase::moveItem(int index, const QPoint &dest)
{
// does not impact on the bintree itself or the contents rect
QListViewItem *item = &items[index];
@@ -2941,14 +2865,14 @@ void QDynamicListViewBase::moveItem(int index, const QPoint &dest)
moved.setBit(index, true);
}
-QPoint QDynamicListViewBase::snapToGrid(const QPoint &pos) const
+QPoint QIconModeViewBase::snapToGrid(const QPoint &pos) const
{
int x = pos.x() - (pos.x() % gridSize().width());
int y = pos.y() - (pos.y() % gridSize().height());
return QPoint(x, y);
}
-QPoint QDynamicListViewBase::draggedItemsDelta() const
+QPoint QIconModeViewBase::draggedItemsDelta() const
{
if (movement() == QListView::Snap) {
QPoint snapdelta = QPoint((offset().x() % gridSize().width()),
@@ -2958,7 +2882,7 @@ QPoint QDynamicListViewBase::draggedItemsDelta() const
return draggedItemsPos - pressedPosition();
}
-QRect QDynamicListViewBase::draggedItemsRect() const
+QRect QIconModeViewBase::draggedItemsRect() const
{
QRect rect = itemsRect(draggedItems);
rect.translate(draggedItemsDelta());
@@ -2977,7 +2901,7 @@ void QListViewPrivate::scrollElasticBandBy(int dx, int dy)
elasticBand.moveTop(elasticBand.top() - dy);
}
-void QDynamicListViewBase::clear()
+void QIconModeViewBase::clear()
{
tree.destroy();
items.clear();
@@ -2986,7 +2910,7 @@ void QDynamicListViewBase::clear()
batchSavedDeltaSeg = 0;
}
-void QDynamicListViewBase::updateContentsSize()
+void QIconModeViewBase::updateContentsSize()
{
QRect bounding;
for (int i = 0; i < items.count(); ++i)
@@ -3039,7 +2963,7 @@ int QListView::visualIndex(const QModelIndex &index) const
Q_D(const QListView);
d->executePostedLayout();
QListViewItem itm = d->indexToListViewItem(index);
- return d->itemIndex(itm);
+ return d->commonListView->itemIndex(itm);
}
QT_END_NAMESPACE
diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h
index 6c8d324..db9eb59 100644
--- a/src/gui/itemviews/qlistview_p.h
+++ b/src/gui/itemviews/qlistview_p.h
@@ -67,8 +67,8 @@ QT_BEGIN_NAMESPACE
class QListViewItem
{
friend class QListViewPrivate;
- friend class QStaticListViewBase;
- friend class QDynamicListViewBase;
+ friend class QListModeViewBase;
+ friend class QIconModeViewBase;
public:
inline QListViewItem()
: x(-1), y(-1), w(0), h(0), indexHint(-1), visited(0xffff) {}
@@ -120,8 +120,42 @@ class QListViewPrivate;
class QCommonListViewBase
{
public:
- inline QCommonListViewBase(QListView *q, QListViewPrivate *d) : dd(d), qq(q) {}
-
+ inline QCommonListViewBase(QListView *q, QListViewPrivate *d) : dd(d), qq(q), batchStartRow(0), batchSavedDeltaSeg(0) {}
+ virtual ~QCommonListViewBase() {}
+
+ //common interface
+ virtual int itemIndex(const QListViewItem &item) const = 0;
+ virtual QListViewItem indexToListViewItem(const QModelIndex &index) const = 0;
+ virtual bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max) = 0;
+ virtual void clear() = 0;
+ virtual void setRowCount(int) = 0;
+ virtual QVector<QModelIndex> intersectingSet(const QRect &area) const = 0;
+
+ virtual int horizontalScrollToValue(int index, QListView::ScrollHint hint,
+ bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const;
+ virtual int verticalScrollToValue(int index, QListView::ScrollHint hint,
+ bool above, bool below, const QRect &area, const QRect &rect) const;
+ virtual void scrollContentsBy(int dx, int dy, bool scrollElasticBand);
+ virtual QRect mapToViewport(const QRect &rect) const {return rect;}
+ virtual int horizontalOffset() const;
+ virtual int verticalOffset() const { return verticalScrollBar()->value(); }
+ virtual void updateHorizontalScrollBar(const QSize &step);
+ virtual void updateVerticalScrollBar(const QSize &step);
+ virtual void dataChanged(const QModelIndex &, const QModelIndex &) { }
+ virtual void appendHiddenRow(int row);
+ virtual void removeHiddenRow(int row);
+ virtual void setPositionForIndex(const QPoint &, const QModelIndex &) { }
+
+#ifndef QT_NO_DRAGANDDROP
+ virtual void paintDragDrop(QPainter *painter) = 0;
+ virtual bool filterDragMoveEvent(QDragMoveEvent *) { return false; }
+ virtual bool filterDragLeaveEvent(QDragLeaveEvent *) { return false; }
+ virtual bool filterDropEvent(QDropEvent *) { return false; }
+ virtual bool filterStartDrag(Qt::DropActions) { return false; }
+#endif
+
+
+ //other inline members
inline int spacing() const;
inline bool isWrapping() const;
inline QSize gridSize() const;
@@ -133,8 +167,8 @@ public:
inline bool uniformItemSizes() const;
inline int column() const;
- inline int verticalScrollBarValue() const;
- inline int horizontalScrollBarValue() const;
+ inline QScrollBar *verticalScrollBar() const;
+ inline QScrollBar *horizontalScrollBar() const;
inline QListView::ScrollMode verticalScrollMode() const;
inline QListView::ScrollMode horizontalScrollMode() const;
@@ -157,110 +191,107 @@ public:
QListViewPrivate *dd;
QListView *qq;
+ QSize contentsSize;
+ int batchStartRow;
+ int batchSavedDeltaSeg;
};
-// ### rename to QListModeViewBase
-class QStaticListViewBase : public QCommonListViewBase
+class QListModeViewBase : public QCommonListViewBase
{
- friend class QListViewPrivate;
public:
- QStaticListViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d),
- batchStartRow(0), batchSavedDeltaSeg(0), batchSavedPosition(0) {}
+ QListModeViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d) {}
QVector<int> flowPositions;
QVector<int> segmentPositions;
QVector<int> segmentStartRows;
QVector<int> segmentExtents;
- QSize contentsSize;
-
// used when laying out in batches
- int batchStartRow;
- int batchSavedDeltaSeg;
int batchSavedPosition;
+ //reimplementations
+ int itemIndex(const QListViewItem &item) const { return item.indexHint; }
+ QListViewItem indexToListViewItem(const QModelIndex &index) const;
bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max);
+ void clear();
+ void setRowCount(int rowCount) { flowPositions.resize(rowCount); }
+ QVector<QModelIndex> intersectingSet(const QRect &area) const;
+
+ int horizontalScrollToValue(int index, QListView::ScrollHint hint,
+ bool leftOf, bool rightOf,const QRect &area, const QRect &rect) const;
+ int verticalScrollToValue(int index, QListView::ScrollHint hint,
+ bool above, bool below, const QRect &area, const QRect &rect) const;
+ void scrollContentsBy(int dx, int dy, bool scrollElasticBand);
+ QRect mapToViewport(const QRect &rect) const;
+ int horizontalOffset() const;
+ int verticalOffset() const;
+ void updateHorizontalScrollBar(const QSize &step);
+ void updateVerticalScrollBar(const QSize &step);
+
+#ifndef QT_NO_DRAGANDDROP
+ void paintDragDrop(QPainter *painter);
+#endif
+private:
QPoint initStaticLayout(const QListViewLayoutInfo &info);
void doStaticLayout(const QListViewLayoutInfo &info);
- QVector<QModelIndex> intersectingStaticSet(const QRect &area) const;
-
- int itemIndex(const QListViewItem &item) const;
-
- int perItemScrollingPageSteps(int length, int bounds, bool wrap) const;
-
int perItemScrollToValue(int index, int value, int height,
QAbstractItemView::ScrollHint hint,
Qt::Orientation orientation, bool wrap, int extent) const;
-
- QRect mapToViewport(const QRect &rect) const;
-
- QListViewItem indexToListViewItem(const QModelIndex &index) const;
-
- void scrollContentsBy(int &dx, int &dy);
-
- int verticalPerItemValue(int itemIndex, int verticalValue, int areaHeight,
- bool above, bool below, bool wrap, QListView::ScrollHint hint, int itemHeight) const;
- int horizontalPerItemValue(int itemIndex, int horizontalValue, int areaWidth,
- bool leftOf, bool rightOf, bool wrap, QListView::ScrollHint hint, int itemWidth) const;
-
- void clear();
+ int perItemScrollingPageSteps(int length, int bounds, bool wrap) const;
};
-// ### rename to QIconModeViewBase
-class QDynamicListViewBase : public QCommonListViewBase
+class QIconModeViewBase : public QCommonListViewBase
{
- friend class QListViewPrivate;
public:
- QDynamicListViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d),
- batchStartRow(0), batchSavedDeltaSeg(0), interSectingVector(0) {}
+ QIconModeViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d), interSectingVector(0) {}
QBspTree tree;
QVector<QListViewItem> items;
QBitArray moved;
- QSize contentsSize;
-
QVector<QModelIndex> draggedItems; // indices to the tree.itemVector
mutable QPoint draggedItemsPos;
// used when laying out in batches
- int batchStartRow;
- int batchSavedDeltaSeg;
- QVector<QModelIndex> *interSectingVector; //used from within intersectingDynamicSet
+ QVector<QModelIndex> *interSectingVector; //used from within intersectingSet
- void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ //reimplementations
+ int itemIndex(const QListViewItem &item) const;
+ QListViewItem indexToListViewItem(const QModelIndex &index) const;
bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max);
+ void clear();
+ void setRowCount(int rowCount);
+ QVector<QModelIndex> intersectingSet(const QRect &area) const;
+
+ void scrollContentsBy(int dx, int dy, bool scrollElasticBand);
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void appendHiddenRow(int row);
+ void removeHiddenRow(int row);
+ void setPositionForIndex(const QPoint &position, const QModelIndex &index);
+
+#ifndef QT_NO_DRAGANDDROP
+ void paintDragDrop(QPainter *painter);
+ bool filterDragMoveEvent(QDragMoveEvent *);
+ bool filterDragLeaveEvent(QDragLeaveEvent *);
+ bool filterDropEvent(QDropEvent *e);
+ bool filterStartDrag(Qt::DropActions);
+#endif
+private:
void initBspTree(const QSize &contents);
QPoint initDynamicLayout(const QListViewLayoutInfo &info);
void doDynamicLayout(const QListViewLayoutInfo &info);
- QVector<QModelIndex> intersectingDynamicSet(const QRect &area) const;
-
static void addLeaf(QVector<int> &leaf, const QRect &area,
uint visited, QBspTree::Data data);
-
- void insertItem(int index);
- void removeItem(int index);
- void moveItem(int index, const QPoint &dest);
-
- int itemIndex(const QListViewItem &item) const;
-
- void createItems(int to);
- void drawItems(QPainter *painter, const QVector<QModelIndex> &indexes) const;
QRect itemsRect(const QVector<QModelIndex> &indexes) const;
-
- QPoint draggedItemsDelta() const;
QRect draggedItemsRect() const;
-
QPoint snapToGrid(const QPoint &pos) const;
-
- void scrollElasticBandBy(int dx, int dy);
-
- QListViewItem indexToListViewItem(const QModelIndex &index) const;
-
- void clear();
void updateContentsSize();
+ QPoint draggedItemsDelta() const;
+ void drawItems(QPainter *painter, const QVector<QModelIndex> &indexes) const;
+ void moveItem(int index, const QPoint &dest);
+
};
class QListViewPrivate: public QAbstractItemViewPrivate
@@ -278,23 +309,13 @@ public:
inline QVector<QModelIndex> intersectingSet(const QRect &area, bool doLayout = true) const {
if (doLayout) executePostedLayout();
QRect a = (q_func()->isRightToLeft() ? flipX(area.normalized()) : area.normalized());
- return (viewMode == QListView::ListMode) ? staticListView->intersectingStaticSet(a)
- : dynamicListView->intersectingDynamicSet(a);
+ return commonListView->intersectingSet(a);
}
- // ### FIXME:
- inline void resetBatchStartRow()
- { if (viewMode == QListView::ListMode) staticListView->batchStartRow = 0;
- else dynamicListView->batchStartRow = 0; }
- inline int batchStartRow() const
- { return (viewMode == QListView::ListMode
- ? staticListView->batchStartRow : dynamicListView->batchStartRow); }
- inline QSize contentsSize() const
- { return (viewMode == QListView::ListMode
- ? staticListView->contentsSize : dynamicListView->contentsSize); }
- inline void setContentsSize(int w, int h)
- { if (viewMode == QListView::ListMode) staticListView->contentsSize = QSize(w, h);
- else dynamicListView->contentsSize = QSize(w, h); }
+ inline void resetBatchStartRow() { commonListView->batchStartRow = 0; }
+ inline int batchStartRow() const { return commonListView->batchStartRow; }
+ inline QSize contentsSize() const { return commonListView->contentsSize; }
+ inline void setContentsSize(int w, int h) { commonListView->contentsSize = QSize(w, h); }
inline int flipX(int x) const
{ return qMax(viewport->width(), contentsSize().width()) - x; }
@@ -305,12 +326,22 @@ public:
inline QRect viewItemRect(const QListViewItem &item) const
{ if (q_func()->isRightToLeft()) return flipX(item.rect()); return item.rect(); }
- int itemIndex(const QListViewItem &item) const;
QListViewItem indexToListViewItem(const QModelIndex &index) const;
inline QModelIndex listViewItemToIndex(const QListViewItem &item) const
- { return model->index(itemIndex(item), column, root); }
+ { return model->index(commonListView->itemIndex(item), column, root); }
+
+ QRect rectForIndex(const QModelIndex &index) const
+ {
+ if (!isIndexValid(index) || index.parent() != root || index.column() != column || isHidden(index.row()))
+ return QRect();
+ executePostedLayout();
+ return viewItemRect(indexToListViewItem(index));
+ }
+
+ void viewUpdateGeometries() { q_func()->updateGeometries(); }
- QRect mapToViewport(const QRect &rect, bool greedy = false) const;
+
+ QRect mapToViewport(const QRect &rect, bool extend = true) const;
QModelIndex closestIndex(const QRect &target, const QVector<QModelIndex> &candidates) const;
QSize itemSize(const QStyleOptionViewItem &option, const QModelIndex &index) const;
@@ -351,10 +382,10 @@ public:
QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
- union {
- QDynamicListViewBase *dynamicListView;
- QStaticListViewBase *staticListView;
- };
+ void emitIndexesMoved(const QModelIndexList &indexes) { emit q_func()->indexesMoved(indexes); }
+
+
+ QCommonListViewBase *commonListView;
// ### FIXME: see if we can move the members into the dynamic/static classes
@@ -412,8 +443,8 @@ inline QPoint QCommonListViewBase::pressedPosition() const { return dd->pressedP
inline bool QCommonListViewBase::uniformItemSizes() const { return dd->uniformItemSizes; }
inline int QCommonListViewBase::column() const { return dd->column; }
-inline int QCommonListViewBase::verticalScrollBarValue() const { return qq->verticalScrollBar()->value(); }
-inline int QCommonListViewBase::horizontalScrollBarValue() const { return qq->horizontalScrollBar()->value(); }
+inline QScrollBar *QCommonListViewBase::verticalScrollBar() const { return qq->verticalScrollBar(); }
+inline QScrollBar *QCommonListViewBase::horizontalScrollBar() const { return qq->horizontalScrollBar(); }
inline QListView::ScrollMode QCommonListViewBase::verticalScrollMode() const { return qq->verticalScrollMode(); }
inline QListView::ScrollMode QCommonListViewBase::horizontalScrollMode() const { return qq->horizontalScrollMode(); }
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 38592e0..8e9c3a1 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -104,6 +104,10 @@ extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp
#include "qdatetime.h"
+#ifdef QT_MAC_USE_COCOA
+#include <private/qt_cocoa_helpers_mac_p.h>
+#endif
+
//#define ALIEN_DEBUG
static void initResources()
@@ -3497,6 +3501,15 @@ void QApplication::changeOverrideCursor(const QCursor &cursor)
if (qApp->d_func()->cursor_list.isEmpty())
return;
qApp->d_func()->cursor_list.removeFirst();
+#ifdef QT_MAC_USE_COCOA
+ // We use native NSCursor stacks in Cocoa. The currentCursor is the
+ // top of this stack. So to avoid flickering of cursor, we have to
+ // change the cusor instead of pop-ing the existing OverrideCursor
+ // and pushing the new one.
+ qApp->d_func()->cursor_list.prepend(cursor);
+ qt_cocoaChangeOverrideCursor(cursor);
+ return;
+#endif
setOverrideCursor(cursor);
}
#endif
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index d942519..0d07a02 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -4572,6 +4572,7 @@ bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet
int deviceType = QTabletEvent::NoDevice;
int pointerType = QTabletEvent::UnknownPointer;
XEvent mouseMotionEvent;
+ XEvent dummy;
const XDeviceMotionEvent *motion = 0;
XDeviceButtonEvent *button = 0;
const XProximityNotifyEvent *proximity = 0;
@@ -4589,7 +4590,6 @@ bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet
// Do event compression. Skip over tablet+mouse move events if there are newer ones.
qt_tablet_motion_data tabletMotionData;
tabletMotionData.tabletMotionType = tablet->xinput_motion;
- XEvent dummy;
while (true) {
// Find first mouse event since we expect them in pairs inside Qt
tabletMotionData.error =false;
diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
index 572df70..172d07b 100644
--- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
+++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
@@ -197,11 +197,19 @@ static void cleanupCocoaApplicationDelegate()
}
}
- // Prevent Cocoa from terminating the application, since this simply
- // exits the program whithout allowing QApplication::exec() to return.
- // The call to QApplication::quit() above will instead quit the
- // application from the Qt side.
- return NSTerminateCancel;
+ if (qtPrivate->threadData->eventLoops.size() == 0) {
+ // INVARIANT: No event loop is executing. This probably
+ // means that Qt is used as a plugin, or as a part of a native
+ // Cocoa application. In any case it should be fine to
+ // terminate now:
+ return NSTerminateNow;
+ } else {
+ // Prevent Cocoa from terminating the application, since this simply
+ // exits the program whithout allowing QApplication::exec() to return.
+ // The call to QApplication::quit() above will instead quit the
+ // application from the Qt side.
+ return NSTerminateCancel;
+ }
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 7ac0d89..5a0209d 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -667,7 +667,15 @@ extern "C" {
- (void)mouseMoved:(NSEvent *)theEvent
{
- qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton);
+ // We always enable mouse tracking for all QCocoaView-s. In cases where we have
+ // child views, we will receive mouseMoved for both parent & the child (if
+ // mouse is over the child). We need to ignore the parent mouseMoved in such
+ // cases.
+ NSPoint windowPoint = [theEvent locationInWindow];
+ NSView *candidateView = [[[self window] contentView] hitTest:windowPoint];
+ if (candidateView && candidateView == self) {
+ qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton);
+ }
}
- (void)mouseDown:(NSEvent *)theEvent
diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp
index a4042c1..8f92fea 100644
--- a/src/gui/kernel/qdnd_x11.cpp
+++ b/src/gui/kernel/qdnd_x11.cpp
@@ -1073,12 +1073,14 @@ void qt_xdnd_send_leave()
if (!qt_xdnd_current_target)
return;
+ QDragManager *manager = QDragManager::self();
+
XClientMessageEvent leave;
leave.type = ClientMessage;
leave.window = qt_xdnd_current_target;
leave.format = 32;
leave.message_type = ATOM(XdndLeave);
- leave.data.l[0] = qt_xdnd_dragsource_xid;
+ leave.data.l[0] = manager->dragPrivate()->source->effectiveWinId();
leave.data.l[1] = 0; // flags
leave.data.l[2] = 0; // x, y
leave.data.l[3] = 0; // w, h
@@ -1094,8 +1096,8 @@ void qt_xdnd_send_leave()
else
XSendEvent(X11->display, qt_xdnd_current_proxy_target, False,
NoEventMask, (XEvent*)&leave);
+
// reset the drag manager state
- QDragManager *manager = QDragManager::self();
manager->willDrop = false;
if (global_accepted_action != Qt::IgnoreAction)
manager->emitActionChanged(Qt::IgnoreAction);
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 1cc168f..76d52c7 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -3549,38 +3549,108 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar)
\since 4.6
\ingroup events
- Touch events occur when pressing, releasing, or moving one or more
- touch points on a touch device (such as a touch-screen or
- track-pad). To receive touch events, widgets have to have the
- Qt::WA_AcceptTouchEvents attribute set and graphics items need to have
- the \l{QGraphicsItem::setAcceptTouchEvents()}{acceptTouchEvents}
- attribute set to true.
-
- All touch events are of type QEvent::TouchBegin,
- QEvent::TouchUpdate, or QEvent::TouchEnd. The touchPoints()
- function returns a list of all touch points contained in the event.
- Information about each touch point can be retrieved using the
- QTouchEvent::TouchPoint class. The Qt::TouchPointState enum
- describes the different states that a touch point may have.
-
- Similar to QMouseEvent, Qt automatically grabs each touch point on
- the first press inside a widget; the widget will receive all
- updates for the touch point until it is released. Note that it is
- possible for a widget to receive events for multiple touch points,
- and that multiple widgets may be receiving touch events at the same
- time.
-
- A touch event contains a special accept flag that indicates
- whether the receiver wants the event. By default, the event is
- accepted. You should call ignore() if the touch event is not handled by
- your widget. A QEvent::TouchBegin event is propagated up the parent widget
- chain until a widget accepts it with accept(), or an event filter
- consumes it. If the QEvent::TouchBegin event is neither accepted nor consumed,
- then mouse events are simulated from the state of the first touch
- point.
-
- Reimplement QWidget::event() for widgets and QGraphicsItem::sceneEvent()
- for items in a graphics view to receive touch events.
+ \section1 Enabling Touch Events
+
+ Touch events occur when pressing, releasing, or moving one or more touch points on a touch
+ device (such as a touch-screen or track-pad). To receive touch events, widgets have to have the
+ Qt::WA_AcceptTouchEvents attribute set and graphics items need to have the
+ \l{QGraphicsItem::setAcceptTouchEvents()}{acceptTouchEvents} attribute set to true.
+
+ Note: when using QAbstractScrollArea based widgets, you should enabled the
+ Qt::WA_AcceptTouchEvents attribute on the scroll area's
+ \l{QAbstractScrollArea::viewport()}{viewport}.
+
+ \section1 Event Delivery and Propagation
+
+ All touch events are of type QEvent::TouchBegin, QEvent::TouchUpdate, or QEvent::TouchEnd.
+ Reimplement QWidget::event() or QAbstractScrollArea::viewportEvent() for widgets and
+ QGraphicsItem::sceneEvent() for items in a graphics view to receive touch events. By default,
+ QWidget::event() translates the first non-primary touch point in a QTouchEvent into a
+ QMouseEvent. This makes it possible to enable touch events on existing widgets that do not
+ normally handle QTouchEvent. See below for information on some special considerations needed
+ when doing this.
+
+ QEvent::TouchBegin is the first touch event sent to a widget. The QEvent::TouchBegin event
+ contains a special accept flag that indicates whether the receiver wants the event. By default,
+ the event is accepted. You should call ignore() if the touch event is not handled by your
+ widget. The QEvent::TouchBegin event is propagated up the parent widget chain until a widget
+ accepts it with accept(), or an event filter consumes it. For QGraphicsItems, the
+ QEvent::TouchBegin event is propagated to items under the mouse (similar to mouse event
+ propagation for QGraphicsItems).
+
+ The QEvent::TouchUpdate and QEvent::TouchEnd events are sent to the widget or item that
+ accepted the QEvent::TouchBegin event. If the QEvent::TouchBegin event is not accepted and not
+ filtered by an event filter, then no further touch events are sent until the next
+ QEvent::TouchBegin.
+
+ The touchPoints() function returns a list of all touch points contained in the event.
+ Information about each touch point can be retrieved using the QTouchEvent::TouchPoint class.
+ The Qt::TouchPointState enum describes the different states that a touch point may have.
+
+ Similar to QMouseEvent, Qt automatically grabs each touch point on the first press inside a
+ widget; the widget will receive all updates for the touch point until it is released. Note that
+ it is possible for a widget to receive events for multiple touch points, and that multiple
+ widgets may be receiving touch events at the same time.
+
+ \section1 Touch Point Grouping
+
+ As mentioned above, it is possible that several widgets can be receiving QTouchEvents at the
+ same time. However, Qt makes sure to never send duplicate QEvent::TouchBegin events to the same
+ widget, which could theoretically happen during propagation if, for example, the user touched 2
+ separate widgets in a QGroupBox and both widgets ignored the QEvent::TouchBegin event.
+
+ To avoid this, Qt will group new touch points together using the following rules:
+
+ \list
+
+ \i When the first touch point is detected, the destination widget is determined firstly by the
+ location on screen first and secondly by the propagation rules.
+
+ \i When additional touch points are detected, Qt first looks to see if there are any active
+ touch points on any ancestor or descendent of the widget under the new touch point. If there
+ are, the new touch point is grouped with the first, and the new touch point will be sent in a
+ single QTouchEvent to the widget that handled the first touch point. (The widget under the new
+ touch point will not receive an event).
+
+ \endlist
+
+ This makes it possible for sibling widgets to handle touch events independently while making
+ sure that the sequence of QTouchEvents is always correct.
+
+ \section1 Mouse Events and the Primary Touch Point
+
+ QTouchEvent delivery is independent from that of QMouseEvent. On some windowing systems, mouse
+ events are also sent for the \l{QTouchEvent::TouchPoint::isPrimary()}{primary touch point}.
+ This means it is possible for your widget to receive both QTouchEvent and QMouseEvent for the
+ same user interaction point. You can use the QTouchEvent::TouchPoint::isPrimary() function to
+ identify the primary touch point.
+
+ Note that on some systems, it is possible to receive touch events without a primary touch
+ point. All this means is that there will be no mouse event generated for the touch points in
+ the QTouchEvent.
+
+ \section1 Caveats
+
+ \list
+
+ \i As mentioned above, enabling touch events means multiple widgets can be receiving touch
+ events simultaneously. Combined with the default QWidget::event() handling for QTouchEvents,
+ this gives you great flexibility in designing multi-touch user interfaces. Be aware of the
+ implications. For example, is is possible that the user is moving a QSlider with one finger and
+ pressing a QPushButton with another. The signals are emitted from these widgets will be
+ interleaved.
+
+ \i Recursion into the event loop using one of the exec() methods (e.g. QDialog::exec() or
+ QMenu::exec()) in a QTouchEvent event handler is not supported. Since there are multiple event
+ recipients, unexpected recursion may cause problems, including but not limited to lost events
+ and unexpected infinite recursion.
+
+ \i QTouchEvents are not affected by a \l{QWidget::grabMouse()}{mouse grab} or an
+ \l{QApplication::activePopupWidget()}{active popup widget}. The behavior of QTouchEvents is
+ undefined when opening a popup or grabbing the mouse while there are multiple active touch
+ points.
+
+ \endlist
\sa QTouchEvent::TouchPoint, Qt::TouchPointState, Qt::WA_AcceptTouchEvents,
QGraphicsItem::acceptTouchEvents()
@@ -3659,6 +3729,11 @@ QTouchEvent::~QTouchEvent()
Returns the list of touch points contained in the touch event.
*/
+/*! \fn QTouchEvent::DeviceType QTouchEvent::deviceType() const
+
+ Returns the touch device Type, which is of type \l {QTouchEvent::DeviceType} {DeviceType}.
+*/
+
/*! \fn void QTouchEvent::setWidget(QWidget *widget)
\internal
@@ -3680,6 +3755,14 @@ QTouchEvent::~QTouchEvent()
Sets the list of touch points for this event.
*/
+/*! \fn void QTouchEvent::setDeviceType(DeviceType deviceType)
+
+ \internal
+
+ Sets the device type to \a deviceType, which is of type \l {QTouchEvent::DeviceType}
+ {DeviceType}.
+*/
+
/*! \class QTouchEvent::TouchPoint
\brief The QTouchEvent::TouchPoint class provides information about a touch point in a QTouchEvent.
\since 4.6
@@ -4091,15 +4174,4 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T
return *this;
}
-/*! \fn QTouchEvent::DeviceType QTouchEvent::deviceType() const
- Returns the touch device Type, which is of type
- \l {QTouchEvent::DeviceType} {DeviceType}.
- */
-
-/*! \fn void QTouchEvent::setDeviceType(DeviceType deviceType)
- Sets the device type to \a deviceType, which is of type
- \l {QTouchEvent::DeviceType} {DeviceType}.
- */
-
-
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index 59b9a2d..585a7e1 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -99,11 +99,11 @@ struct QShortcutEntry
QObject *owner;
};
-#ifndef QT_NO_DEBUG_STREAM
+#if 0 //ndef QT_NO_DEBUG_STREAM
/*! \internal
QDebug operator<< for easy debug output of the shortcut entries.
*/
-QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se) {
+static QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se) {
if (!se)
return dbg << "QShortcutEntry(0x0)";
dbg.nospace()
diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp
index 47f3146..10689ba 100644
--- a/src/gui/kernel/qstandardgestures.cpp
+++ b/src/gui/kernel/qstandardgestures.cpp
@@ -172,8 +172,6 @@ bool QPanGesture::eventFilter(QObject *receiver, QEvent *event)
bool QPanGesture::filterEvent(QEvent *event)
{
Q_D(QPanGesture);
- if (!event->spontaneous())
- return false;
const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
if (event->type() == QEvent::TouchBegin) {
QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
@@ -329,10 +327,11 @@ bool QPinchGesture::event(QEvent *event)
bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event)
{
-#ifdef Q_WS_WIN
+#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
Q_D(QPinchGesture);
if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) {
QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
+#if defined(Q_WS_WIN)
QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
QApplicationPrivate::WidgetStandardGesturesMap::iterator it;
it = qAppPriv->widgetGestures.find(static_cast<QWidget*>(receiver));
@@ -340,7 +339,9 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event)
return false;
if (this != it.value().pinch)
return false;
+#endif
Qt::GestureState nextState = Qt::NoGesture;
+
switch(ev->gestureType) {
case QNativeGestureEvent::GestureBegin:
// next we might receive the first gesture update event, so we
@@ -349,15 +350,22 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event)
d->scaleFactor = d->lastScaleFactor = 1;
d->rotationAngle = d->lastRotationAngle = 0;
d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPoint();
+#if defined(Q_WS_WIN)
d->initialDistance = 0;
+#endif
return false;
case QNativeGestureEvent::Rotate:
d->lastRotationAngle = d->rotationAngle;
+#if defined(Q_WS_WIN)
d->rotationAngle = -1 * GID_ROTATE_ANGLE_FROM_ARGUMENT(ev->argument);
+#elif defined(Q_WS_MAC)
+ d->rotationAngle = ev->percentage;
+#endif
nextState = Qt::GestureUpdated;
event->accept();
break;
case QNativeGestureEvent::Zoom:
+#if defined(Q_WS_WIN)
if (d->initialDistance != 0) {
d->lastScaleFactor = d->scaleFactor;
int distance = int(qint64(ev->argument));
@@ -365,6 +373,10 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event)
} else {
d->initialDistance = int(qint64(ev->argument));
}
+#elif defined(Q_WS_MAC)
+ d->lastScaleFactor = d->scaleFactor;
+ d->scaleFactor = ev->percentage;
+#endif
nextState = Qt::GestureUpdated;
event->accept();
break;
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 7596802..a9b8970 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -1238,4 +1238,12 @@ void qt_mac_menu_collapseSeparators(void */*NSMenu **/ theMenu, bool collapse)
}
}
+#ifdef QT_MAC_USE_COCOA
+void qt_cocoaChangeOverrideCursor(const QCursor &cursor)
+{
+ QMacCocoaAutoReleasePool pool;
+ [static_cast<NSCursor *>(qt_mac_nsCursorForQCursor(cursor)) set];
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
index 24d7096..932abef 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h
+++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
@@ -133,6 +133,7 @@ bool qt_mac_checkForNativeSizeGrip(const QWidget *widget);
void qt_dispatchTabletProximityEvent(void * /*NSEvent * */ tabletEvent);
#ifdef QT_MAC_USE_COCOA
bool qt_dispatchKeyEventWithCocoa(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent);
+void qt_cocoaChangeOverrideCursor(const QCursor &cursor);
#endif
void qt_mac_menu_collapseSeparators(void * /*NSMenu */ menu, bool collapse);
bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent);
diff --git a/src/gui/kernel/qt_mac.cpp b/src/gui/kernel/qt_mac.cpp
index 642aa5c..bef3449 100644
--- a/src/gui/kernel/qt_mac.cpp
+++ b/src/gui/kernel/qt_mac.cpp
@@ -1,11 +1,11 @@
/****************************************************************************
- **
- ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
- **
- ** This file is part of the QtGui module of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:LGPL$
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
@@ -36,11 +36,8 @@
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
** $QT_END_LICENSE$
- **
- ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- **
- ****************************************************************************/
+**
+****************************************************************************/
#include <private/qt_mac_p.h>
#include <private/qpixmap_mac_p.h>
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 3dd2e65..4bd7222 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -1055,7 +1055,7 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event,
handled_event = false;
break;
}
- qNGEvent.gestureType = QNativeGestureEvent::Zoom;
+ qNGEvent.gestureType = QNativeGestureEvent::Rotate;
qNGEvent.percentage = float(amount);
break; }
case kEventGestureSwipe: {
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index c74368c..3d618fe 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -2064,8 +2064,6 @@ void QWidgetPrivate::winSetupGestures()
Q_Q(QWidget);
if (!q)
return;
- q->setAttribute(Qt::WA_DontCreateNativeAncestors);
- q->setAttribute(Qt::WA_NativeWindow);
if (!q->isVisible())
return;
QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp
index 51f40e3..6a5ea49 100644
--- a/src/gui/styles/gtksymbols.cpp
+++ b/src/gui/styles/gtksymbols.cpp
@@ -642,7 +642,7 @@ GtkStyle* QGtk::gtkStyle(const QString &path)
return 0;
}
-static void update_toolbar_style(GtkWidget *gtkToolBar, GParamSpec *pspec, gpointer user_data)
+static void update_toolbar_style(GtkWidget *gtkToolBar, GParamSpec *, gpointer)
{
GtkToolbarStyle toolbar_style = GTK_TOOLBAR_ICONS;
g_object_get(gtkToolBar, "toolbar-style", &toolbar_style, NULL);
diff --git a/src/gui/widgets/qdatetimeedit.cpp b/src/gui/widgets/qdatetimeedit.cpp
index 133d73c..5a9c7e1 100644
--- a/src/gui/widgets/qdatetimeedit.cpp
+++ b/src/gui/widgets/qdatetimeedit.cpp
@@ -1,4 +1,4 @@
-/****************************************************************************)
+/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
index 7db800b..15e6791 100644
--- a/src/gui/widgets/qmainwindow.cpp
+++ b/src/gui/widgets/qmainwindow.cpp
@@ -1032,6 +1032,8 @@ void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget
Restores the state of \a dockwidget if it is created after the call
to restoreState(). Returns true if the state was restored; otherwise
returns false.
+
+ \sa restoreState(), saveState()
*/
bool QMainWindow::restoreDockWidget(QDockWidget *dockwidget)
@@ -1163,6 +1165,11 @@ Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const
To restore the saved state, pass the return value and \a version
number to restoreState().
+ To save the geometry when the window closes, you can
+ implement a close event like this:
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp 0
+
\sa restoreState(), QWidget::saveGeometry(), QWidget::restoreGeometry()
*/
QByteArray QMainWindow::saveState(int version) const
@@ -1182,7 +1189,13 @@ QByteArray QMainWindow::saveState(int version) const
unchanged, and this function returns \c false; otherwise, the state
is restored, and this function returns \c true.
- \sa saveState(), QWidget::saveGeometry(), QWidget::restoreGeometry()
+ To restore geometry saved using QSettings, you can use code like
+ this:
+
+ \snippet doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp 1
+
+ \sa saveState(), QWidget::saveGeometry(),
+ QWidget::restoreGeometry(), restoreDockWidget()
*/
bool QMainWindow::restoreState(const QByteArray &state, int version)
{