diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2011-05-18 07:55:56 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2011-05-18 07:55:56 (GMT) |
commit | 06557b8d7c472c6298f7d8b310feda225864265f (patch) | |
tree | 571e5078ee66377cdadbc07fc7851b334c0d5272 /src | |
parent | 83a2be48a82394ae692d91587c64f8ccd385350f (diff) | |
parent | fa065de6eb49c706feb4a75db7bc0a4618a81a13 (diff) | |
download | Qt-06557b8d7c472c6298f7d8b310feda225864265f.zip Qt-06557b8d7c472c6298f7d8b310feda225864265f.tar.gz Qt-06557b8d7c472c6298f7d8b310feda225864265f.tar.bz2 |
Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qt-releng-team
* 'master' of git://scm.dev.nokia.troll.no/qt/qt-releng-team: (195 commits)
Re-apply licenseheader text in source files for qt4.8
Revert all QScroller and QFlickGesture related code.
Fix regression that caused waitForXXX(-1) to fail.
Fix thread safety regression of QNetworkConfigurationManager
Fix instability in QNetworkConfigurationManager autotest
Support word selection list with predictive text from splitview
Fix softkey icon positioning in S60 5.3
QDeclarativeMouseArea: block context menu events
ListViews loses items if all visible items are removed.
Make TextEdit word selection more natural.
Fixed license header.
Ensure that recursive QMAKE_EXTRA_TARGETS use the correct makefile
Clear confusion between QMainWindow and QMainWindowLayout.
Fix for rounded corners bug in QMenu
Compile
QWidgetPrivate::setParent_sys might be using null pointer
Ensure the TextEdit cursor delegate is repositioned on mouse events.
Don't crash on an invalid replacementStart from an input method.
Fix QGLWidget::renderPixmap for raster engine on Mac
Check if OES_texture_npot is present on OpenGL ES 2.
...
Diffstat (limited to 'src')
94 files changed, 724 insertions, 4516 deletions
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 9200a97..5333b71 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -450,10 +450,11 @@ QLibraryInfo::location(LibraryLocation loc) } if (QDir::isRelativePath(ret)) { + QString baseDir; if (loc == PrefixPath) { // we make the prefix path absolute to the executable's directory #ifdef BOOTSTRAPPING - return QFileInfo(qmake_libraryInfoFile()).absolutePath(); + baseDir = QFileInfo(qmake_libraryInfoFile()).absolutePath(); #else if (QCoreApplication::instance()) { #ifdef Q_OS_MAC @@ -466,15 +467,16 @@ QLibraryInfo::location(LibraryLocation loc) } } #endif - return QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(ret); + baseDir = QCoreApplication::applicationDirPath(); } else { - return QDir::current().absoluteFilePath(ret); + baseDir = QDir::currentPath(); } #endif } else { // we make any other path absolute to the prefix directory - return QDir(location(PrefixPath)).absoluteFilePath(ret); + baseDir = location(PrefixPath); } + ret = QDir::cleanPath(baseDir + QLatin1Char('/') + ret); } return ret; } diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index c870d4a..99479d0 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -94,6 +94,7 @@ Qt { Q_ENUMS(GestureState) Q_ENUMS(GestureType) #endif + Q_ENUMS(CursorMoveStyle) #endif // (defined(Q_MOC_RUN) || defined(QT_JAMBI_RUN)) #if defined(Q_MOC_RUN) @@ -1784,6 +1785,11 @@ public: NavigationModeCursorAuto, NavigationModeCursorForceVisible }; + + enum CursorMoveStyle { + LogicalMoveStyle, + VisualMoveStyle + }; } #ifdef Q_MOC_RUN ; diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index fbc935d..7b2491b 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -231,8 +231,6 @@ QT_BEGIN_NAMESPACE \value WinIdChange The window system identifer for this native widget has changed \value Gesture A gesture was triggered (QGestureEvent) \value GestureOverride A gesture override was triggered (QGestureEvent) - \value ScrollPrepare The object needs to fill in its geometry information (QScrollPrepareEvent) - \value Scroll The object needs to scroll to the supplied position (QScrollEvent) User events should have values between \c User and \c{MaxUser}: diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 98a08e9..281367b 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -288,9 +288,6 @@ public: Gesture = 198, GestureOverride = 202, #endif - ScrollPrepare = 204, - Scroll = 205, - // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 86cf6a7..34925f1 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1499,6 +1499,7 @@ void QDeclarativeGridView::setDelegate(QDeclarativeComponent *delegate) d->ownModel = true; } if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model)) { + int oldCount = dataModel->count(); dataModel->setDelegate(delegate); if (isComponentComplete()) { for (int i = 0; i < d->visibleItems.count(); ++i) @@ -1516,6 +1517,8 @@ void QDeclarativeGridView::setDelegate(QDeclarativeComponent *delegate) } d->moveReason = QDeclarativeGridViewPrivate::Other; } + if (oldCount != dataModel->count()) + emit countChanged(); emit delegateChanged(); } } diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 0757419..b52b6fc 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -733,6 +733,7 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) if (doBuffer && (bufferMode & BufferBefore)) fillFrom = bufferFrom; + bool haveValidItems = false; int modelIndex = visibleIndex; qreal itemEnd = visiblePos-1; if (!visibleItems.isEmpty()) { @@ -741,11 +742,13 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) int i = visibleItems.count() - 1; while (i > 0 && visibleItems.at(i)->index == -1) --i; - if (visibleItems.at(i)->index != -1) + if (visibleItems.at(i)->index != -1) { + haveValidItems = true; modelIndex = visibleItems.at(i)->index + 1; + } } - if (visibleItems.count() && (fillFrom > itemEnd+averageSize+spacing + if (haveValidItems && (fillFrom > itemEnd+averageSize+spacing || fillTo < visiblePos - averageSize - spacing)) { // We've jumped more than a page. Estimate which items are now // visible and fill from there. @@ -1813,6 +1816,7 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) d->ownModel = true; } if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model)) { + int oldCount = dataModel->count(); dataModel->setDelegate(delegate); if (isComponentComplete()) { for (int i = 0; i < d->visibleItems.count(); ++i) @@ -1831,6 +1835,8 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) } d->updateViewport(); } + if (oldCount != dataModel->count()) + emit countChanged(); } emit delegateChanged(); } @@ -3403,9 +3409,9 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) } } - if (removedVisible && !haveVisibleIndex) { + if (!haveVisibleIndex) { d->timeline.clear(); - if (d->itemCount == 0) { + if (removedVisible && d->itemCount == 0) { d->visibleIndex = 0; d->visiblePos = d->header ? d->header->size() : 0; d->setPosition(0); diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index 271a704..20ca0f6 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -660,6 +660,32 @@ void QDeclarativeMouseArea::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) setHovered(false); } +#ifndef QT_NO_CONTEXTMENU +void QDeclarativeMouseArea::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + bool acceptsContextMenuButton; +#if defined(Q_OS_SYMBIAN) + // In Symbian a Long Tap on the screen will trigger. See QSymbianControl::HandleLongTapEventL(). + acceptsContextMenuButton = acceptedButtons() & Qt::LeftButton; +#elif defined(Q_WS_WINCE) + // ### WinCE can trigger context menu event with a gesture in the left button or a + // click with the right button. Since we have no way here to differentiate them when + // event happens, accepting either of the them will block the event. + acceptsContextMenuButton = acceptedButtons() & (Qt::LeftButton | Qt::RightButton); +#else + acceptsContextMenuButton = acceptedButtons() & Qt::RightButton; +#endif + + if (isEnabled() && event->reason() == QGraphicsSceneContextMenuEvent::Mouse + && acceptsContextMenuButton) { + // Do not let the context menu event propagate to items behind. + return; + } + + QDeclarativeItem::contextMenuEvent(event); +} +#endif // QT_NO_CONTEXTMENU + bool QDeclarativeMouseArea::sceneEvent(QEvent *event) { bool rv = QDeclarativeItem::sceneEvent(event); diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p.h index c3e5d3d..8fd453f 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea_p.h +++ b/src/declarative/graphicsitems/qdeclarativemousearea_p.h @@ -190,6 +190,9 @@ protected: void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void hoverMoveEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); +#ifndef QT_NO_CONTEXTMENU + void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); +#endif // QT_NO_CONTEXTMENU bool sceneEvent(QEvent *); bool sendMouseEvent(QGraphicsSceneMouseEvent *event); bool sceneEventFilter(QGraphicsItem *i, QEvent *e); diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index 9a74b50..79e52cd 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -1021,9 +1021,12 @@ void QDeclarativePathView::setDelegate(QDeclarativeComponent *delegate) d->ownModel = true; } if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model)) { + int oldCount = dataModel->count(); dataModel->setDelegate(delegate); d->modelCount = dataModel->count(); d->regenerate(); + if (oldCount != dataModel->count()) + emit countChanged(); emit delegateChanged(); } } diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index 62c84c0..e806dbf 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -1451,6 +1451,7 @@ QByteArray QDeclarativePropertyPrivate::saveValueType(const QMetaObject *metaObj QMetaProperty subProp = subObject->property(subIndex); ValueTypeSerializedData sd; + memset(&sd, 0, sizeof(sd)); sd.isValueType = true; sd.core.load(metaObject->property(index)); sd.valueType.flags = QDeclarativePropertyCache::Data::flagsForProperty(subProp); @@ -1465,6 +1466,7 @@ QByteArray QDeclarativePropertyPrivate::saveValueType(const QMetaObject *metaObj QByteArray QDeclarativePropertyPrivate::saveProperty(const QMetaObject *metaObject, int index) { SerializedData sd; + memset(&sd, 0, sizeof(sd)); sd.isValueType = false; sd.core.load(metaObject->property(index)); diff --git a/src/declarative/qml/qmetaobjectbuilder.cpp b/src/declarative/qml/qmetaobjectbuilder.cpp index 8b178fc..f5e8369 100644 --- a/src/declarative/qml/qmetaobjectbuilder.cpp +++ b/src/declarative/qml/qmetaobjectbuilder.cpp @@ -1452,6 +1452,7 @@ QMetaObject *QMetaObjectBuilder::toMetaObject() const { int size = buildMetaObject(d, 0, false); char *buf = reinterpret_cast<char *>(qMalloc(size)); + memset(buf, 0, size); buildMetaObject(d, buf, false); return reinterpret_cast<QMetaObject *>(buf); } @@ -1481,6 +1482,7 @@ QByteArray QMetaObjectBuilder::toRelocatableData(bool *ok) const QByteArray data; data.resize(size); char *buf = data.data(); + memset(buf, 0, size); buildMetaObject(d, buf, true); if (ok) *ok = true; return data; diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 01be5e8..61a228d 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4449,6 +4449,8 @@ QImage QImage::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::Transf QSize newSize = size(); newSize.scale(s, aspectMode); + newSize.rwidth() = qMax(newSize.width(), 1); + newSize.rheight() = qMax(newSize.height(), 1); if (newSize == size()) return *this; diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 1dec071..7071579 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1514,6 +1514,8 @@ QPixmap QPixmap::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::Tran QSize newSize = size(); newSize.scale(s, aspectMode); + newSize.rwidth() = qMax(newSize.width(), 1); + newSize.rheight() = qMax(newSize.height(), 1); if (newSize == size()) return *this; diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp index 7e31f5b..cb30161 100644 --- a/src/gui/image/qpixmap_mac.cpp +++ b/src/gui/image/qpixmap_mac.cpp @@ -54,6 +54,7 @@ #include <private/qpaintengine_mac_p.h> #include <private/qt_mac_p.h> #include <private/qt_cocoa_helpers_mac_p.h> +#include <private/qapplication_p.h> #include <limits.h> #include <string.h> @@ -73,12 +74,18 @@ static int qt_pixmap_serial = 0; Q_GUI_EXPORT quint32 *qt_mac_pixmap_get_base(const QPixmap *pix) { - return static_cast<QMacPixmapData*>(pix->data.data())->pixels; + if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) + return reinterpret_cast<quint32 *>(static_cast<QRasterPixmapData*>(pix->data.data())->buffer()->bits()); + else + return static_cast<QMacPixmapData*>(pix->data.data())->pixels; } Q_GUI_EXPORT int qt_mac_pixmap_get_bytes_per_line(const QPixmap *pix) { - return static_cast<QMacPixmapData*>(pix->data.data())->bytesPerRow; + if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) + return static_cast<QRasterPixmapData*>(pix->data.data())->buffer()->bytesPerLine(); + else + return static_cast<QMacPixmapData*>(pix->data.data())->bytesPerRow; } void qt_mac_cgimage_data_free(void *info, const void *memoryToFree, size_t) diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index edcd9a7..daa448b 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -240,21 +240,6 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) return false; switch (event->type()) { - case QEvent::MouseButtonPress: - // Alphanumeric keypad doesn't like it when we click and text is still getting displayed - // It ignores the mouse event, so we need to commit and send a selection event (which will get triggered - // after the commit) - if (!m_preeditString.isEmpty()) { - commitCurrentString(true); - - int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt(); - - QList<QInputMethodEvent::Attribute> selectAttributes; - selectAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos, 0, QVariant()); - QInputMethodEvent selectEvent(QLatin1String(""), selectAttributes); - sendEvent(selectEvent); - } - break; case QEvent::KeyPress: commitTemporaryPreeditString(); // fall through intended @@ -333,7 +318,10 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) if (sControl) { sControl->setIgnoreFocusChanged(false); } - return true; + //If m_pointerHandler has already been set, it means that fep inline editing is in progress. + //When this is happening, do not filter out pointer events. + if (!m_pointerHandler) + return true; } return false; @@ -385,18 +373,31 @@ void QCoeFepInputContext::commitTemporaryPreeditString() commitCurrentString(false); } -void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event) +void QCoeFepInputContext::mouseHandler(int x, QMouseEvent *event) { Q_ASSERT(focusWidget()); if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::LeftButton) { - commitCurrentString(true); - int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt(); + QWidget *proxy = focusWidget()->focusProxy(); + Qt::InputMethodHints currentHints = proxy ? proxy->inputMethodHints() : focusWidget()->inputMethodHints(); + + //If splitview is open and T9 word is tapped, pass the pointer event to pointer handler. + //This will open the "suggested words" list. Pass pointer position always as zero, to make + //full word replacement in case user makes a selection. + if (S60->partial_keyboard && S60->partialKeyboardOpen + && m_pointerHandler + && !(currentHints & Qt::ImhNoPredictiveText) + && (x > 0 && x < m_preeditString.length())) { + m_pointerHandler->HandlePointerEventInInlineTextL(TPointerEvent::EButton1Up, 0, 0); + } else { + commitCurrentString(true); + int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt(); - QList<QInputMethodEvent::Attribute> attributes; - attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos + x, 0, QVariant()); - QInputMethodEvent event(QLatin1String(""), attributes); - sendEvent(event); + QList<QInputMethodEvent::Attribute> attributes; + attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos + x, 0, QVariant()); + QInputMethodEvent event(QLatin1String(""), attributes); + sendEvent(event); + } } } diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 6aed17c..f53705b 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -62,9 +62,6 @@ #include <qaccessible.h> #endif #include <private/qsoftkeymanager_p.h> -#ifndef QT_NO_GESTURE -# include <qscroller.h> -#endif QT_BEGIN_NAMESPACE @@ -194,40 +191,6 @@ void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index } } -#ifndef QT_NO_GESTURES - -// stores and restores the selection and current item when flicking -void QAbstractItemViewPrivate::_q_scrollerStateChanged() -{ - Q_Q(QAbstractItemView); - - if (QScroller *scroller = QScroller::scroller(viewport)) { - switch (scroller->state()) { - case QScroller::Pressed: - // store the current selection in case we start scrolling - if (q->selectionModel()) { - oldSelection = q->selectionModel()->selection(); - oldCurrent = q->selectionModel()->currentIndex(); - } - break; - - case QScroller::Dragging: - // restore the old selection if we really start scrolling - if (q->selectionModel()) { - q->selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect); - q->selectionModel()->setCurrentIndex(oldCurrent, QItemSelectionModel::NoUpdate); - } - // fall through - - default: - oldSelection = QItemSelection(); - oldCurrent = QModelIndex(); - break; - } - } -} - -#endif // QT_NO_GESTURES /*! \class QAbstractItemView @@ -1662,13 +1625,6 @@ bool QAbstractItemView::viewportEvent(QEvent *event) case QEvent::WindowDeactivate: d->viewport->update(); break; - case QEvent::ScrollPrepare: - executeDelayedItemsLayout(); -#ifndef QT_NO_GESTURES - connect(QScroller::scroller(d->viewport), SIGNAL(stateChanged(QScroller::State)), this, SLOT(_q_scrollerStateChanged()), Qt::UniqueConnection); -#endif - break; - default: break; } diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h index e4766af..cb7b78d 100644 --- a/src/gui/itemviews/qabstractitemview.h +++ b/src/gui/itemviews/qabstractitemview.h @@ -359,9 +359,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) Q_PRIVATE_SLOT(d_func(), void _q_headerDataChanged()) -#ifndef QT_NO_GESTURES - Q_PRIVATE_SLOT(d_func(), void _q_scrollerStateChanged()) -#endif friend class QTreeViewPrivate; // needed to compile with MSVC friend class QAccessibleItemRow; diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 5b4b179..3ba7227 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -114,7 +114,6 @@ public: virtual void _q_modelDestroyed(); virtual void _q_layoutChanged(); void _q_headerDataChanged() { doDelayedItemsLayout(); } - void _q_scrollerStateChanged(); void fetchMore(); @@ -415,12 +414,6 @@ public: QAbstractItemView::ScrollMode verticalScrollMode; QAbstractItemView::ScrollMode horizontalScrollMode; -#ifndef QT_NO_GESTURES - // the selection before the last mouse down. In case we have to restore it for scrolling - QItemSelection oldSelection; - QModelIndex oldCurrent; -#endif - bool currentIndexSet; bool wrapItemText; diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index dae0ff0..e9d58c7 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1490,8 +1490,10 @@ void QSymbianControl::HandleResourceChange(int resourceType) } if (ic && isSplitViewWidget(widget)) { if (resourceType == KSplitViewCloseEvent) { + S60->partialKeyboardOpen = false; ic->resetSplitViewWidget(); } else { + S60->partialKeyboardOpen = true; ic->ensureFocusWidgetVisible(widget); } } diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 6ce8fa2..666fe85 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -2018,15 +2018,12 @@ void qt_init(QApplicationPrivate *priv, int, (PtrXRRRootToScreen) xrandrLib.resolve("XRRRootToScreen"); X11->ptrXRRQueryExtension = (PtrXRRQueryExtension) xrandrLib.resolve("XRRQueryExtension"); - X11->ptrXRRSizes = - (PtrXRRSizes) xrandrLib.resolve("XRRSizes"); } # else X11->ptrXRRSelectInput = XRRSelectInput; X11->ptrXRRUpdateConfiguration = XRRUpdateConfiguration; X11->ptrXRRRootToScreen = XRRRootToScreen; X11->ptrXRRQueryExtension = XRRQueryExtension; - X11->ptrXRRSizes = XRRSizes; # endif if (X11->ptrXRRQueryExtension diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 436ee45..bdd2fe4 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -4629,223 +4629,4 @@ const QGestureEventPrivate *QGestureEvent::d_func() const #endif // QT_NO_GESTURES -/*! - \class QScrollPrepareEvent - \since 4.8 - \ingroup events - - \brief The QScrollPrepareEvent class is send in preparation of a scrolling. - - The scroll prepare event is send before scrolling (usually by QScroller) is started. - The object receiving this event should set viewportSize, maxContentPos and contentPos. - It also should accept this event to indicate that scrolling should be started. - - It is not guaranteed that a QScrollEvent will be send after an acceepted - QScrollPrepareEvent, e.g. in a case where the maximum content position is (0,0). - - \sa QScrollEvent, QScroller -*/ - -/*! - Creates new QScrollPrepareEvent - The \a startPos is the position of a touch or mouse event that started the scrolling. -*/ -QScrollPrepareEvent::QScrollPrepareEvent(const QPointF &startPos) - : QEvent(QEvent::ScrollPrepare) -{ - d = reinterpret_cast<QEventPrivate *>(new QScrollPrepareEventPrivate()); - d_func()->startPos = startPos; -} - -/*! - Destroys QScrollEvent. -*/ -QScrollPrepareEvent::~QScrollPrepareEvent() -{ - delete reinterpret_cast<QScrollPrepareEventPrivate *>(d); -} - -/*! - Returns the position of the touch or mouse event that started the scrolling. -*/ -QPointF QScrollPrepareEvent::startPos() const -{ - return d_func()->startPos; -} - -/*! - Returns size of the area that is to be scrolled as set by setViewportSize - - \sa setViewportSize() -*/ -QSizeF QScrollPrepareEvent::viewportSize() const -{ - return d_func()->viewportSize; -} - -/*! - Returns the range of coordinates for the content as set by setContentPosRange(). -*/ -QRectF QScrollPrepareEvent::contentPosRange() const -{ - return d_func()->contentPosRange; -} - -/*! - Returns the current position of the content as set by setContentPos. -*/ -QPointF QScrollPrepareEvent::contentPos() const -{ - return d_func()->contentPos; -} - - -/*! - Sets the size of the area that is to be scrolled to \a size. - - \sa viewportSize() -*/ -void QScrollPrepareEvent::setViewportSize(const QSizeF &size) -{ - d_func()->viewportSize = size; -} - -/*! - Sets the range of content coordinates to \a rect. - - \sa contentPosRange() -*/ -void QScrollPrepareEvent::setContentPosRange(const QRectF &rect) -{ - d_func()->contentPosRange = rect; -} - -/*! - Sets the current content position to \a pos. - - \sa contentPos() -*/ -void QScrollPrepareEvent::setContentPos(const QPointF &pos) -{ - d_func()->contentPos = pos; -} - - -/*! - \internal -*/ -QScrollPrepareEventPrivate *QScrollPrepareEvent::d_func() -{ - return reinterpret_cast<QScrollPrepareEventPrivate *>(d); -} - -/*! - \internal -*/ -const QScrollPrepareEventPrivate *QScrollPrepareEvent::d_func() const -{ - return reinterpret_cast<const QScrollPrepareEventPrivate *>(d); -} - -/*! - \class QScrollEvent - \since 4.8 - \ingroup events - - \brief The QScrollEvent class is send when scrolling. - - The scroll event is send to indicate that the receiver should be scrolled. - Usually the receiver should be something visual like QWidget or QGraphicsObject. - - Some care should be taken that no conflicting QScrollEvents are sent from two - sources. Using QScroller::scrollTo is save however. - - \sa QScrollPrepareEvent, QScroller -*/ - -/*! - \enum QScrollEvent::ScrollState - - This enum describes the states a scroll event can have. - - \value ScrollStarted Set for the first scroll event of a scroll activity. - - \value ScrollUpdated Set for all but the first and the last scroll event of a scroll activity. - - \value ScrollFinished Set for the last scroll event of a scroll activity. - - \sa QScrollEvent::scrollState() -*/ - -/*! - Creates a new QScrollEvent - \a contentPos is the new content position, \a overshootDistance is the - new overshoot distance while \a scrollState indicates if this scroll - event is the first one, the last one or some event in between. -*/ -QScrollEvent::QScrollEvent(const QPointF &contentPos, const QPointF &overshootDistance, ScrollState scrollState) - : QEvent(QEvent::Scroll) -{ - d = reinterpret_cast<QEventPrivate *>(new QScrollEventPrivate()); - d_func()->contentPos = contentPos; - d_func()->overshoot= overshootDistance; - d_func()->state = scrollState; -} - -/*! - Destroys QScrollEvent. -*/ -QScrollEvent::~QScrollEvent() -{ - delete reinterpret_cast<QScrollEventPrivate *>(d); -} - -/*! - Returns the new scroll position. -*/ -QPointF QScrollEvent::contentPos() const -{ - return d_func()->contentPos; -} - -/*! - Returns the new overshoot distance. - See QScroller for an explanation of the term overshoot. - - \sa QScroller -*/ -QPointF QScrollEvent::overshootDistance() const -{ - return d_func()->overshoot; -} - -/*! - Returns the current scroll state as a combination of ScrollStateFlag values. - ScrollStarted (or ScrollFinished) will be set, if this scroll event is the first (or last) event in a scrolling activity. - Please note that both values can be set at the same time, if the activity consists of a single QScrollEvent. - All other scroll events in between will have their state set to ScrollUpdated. - - A widget could for example revert selections when scrolling is started and stopped. -*/ -QScrollEvent::ScrollState QScrollEvent::scrollState() const -{ - return d_func()->state; -} - -/*! - \internal -*/ -QScrollEventPrivate *QScrollEvent::d_func() -{ - return reinterpret_cast<QScrollEventPrivate *>(d); -} - -/*! - \internal -*/ -const QScrollEventPrivate *QScrollEvent::d_func() const -{ - return reinterpret_cast<const QScrollEventPrivate *>(d); -} - QT_END_NAMESPACE diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 2267d73..4f2e61f 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -889,52 +889,6 @@ private: }; #endif // QT_NO_GESTURES -class QScrollPrepareEventPrivate; -class Q_GUI_EXPORT QScrollPrepareEvent : public QEvent -{ -public: - QScrollPrepareEvent(const QPointF &startPos); - ~QScrollPrepareEvent(); - - QPointF startPos() const; - - QSizeF viewportSize() const; - QRectF contentPosRange() const; - QPointF contentPos() const; - - void setViewportSize(const QSizeF &size); - void setContentPosRange(const QRectF &rect); - void setContentPos(const QPointF &pos); - -private: - QScrollPrepareEventPrivate *d_func(); - const QScrollPrepareEventPrivate *d_func() const; -}; - - -class QScrollEventPrivate; -class Q_GUI_EXPORT QScrollEvent : public QEvent -{ -public: - enum ScrollState - { - ScrollStarted, - ScrollUpdated, - ScrollFinished - }; - - QScrollEvent(const QPointF &contentPos, const QPointF &overshoot, ScrollState scrollState); - ~QScrollEvent(); - - QPointF contentPos() const; - QPointF overshootDistance() const; - ScrollState scrollState() const; - -private: - QScrollEventPrivate *d_func(); - const QScrollEventPrivate *d_func() const; -}; - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index f227f73..9aba654 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -186,34 +186,6 @@ public: #endif }; - -class QScrollPrepareEventPrivate -{ -public: - inline QScrollPrepareEventPrivate() - : target(0) - { - } - - QObject* target; - QPointF startPos; - QSizeF viewportSize; - QRectF contentPosRange; - QPointF contentPos; -}; - -class QScrollEventPrivate -{ -public: - inline QScrollEventPrivate() - { - } - - QPointF contentPos; - QPointF overshoot; - QScrollEvent::ScrollState state; -}; - QT_END_NAMESPACE #endif // QEVENT_P_H diff --git a/src/gui/kernel/qsoftkeymanager_s60.cpp b/src/gui/kernel/qsoftkeymanager_s60.cpp index cc2eafa..ab71064 100644 --- a/src/gui/kernel/qsoftkeymanager_s60.cpp +++ b/src/gui/kernel/qsoftkeymanager_s60.cpp @@ -176,22 +176,27 @@ void QSoftKeyManagerPrivateS60::setNativeSoftkey(CEikButtonGroupContainer &cba, QPoint QSoftKeyManagerPrivateS60::softkeyIconPosition(int position, QSize sourceSize, QSize targetSize) { QPoint iconPosition(0,0); - switch( AknLayoutUtils::CbaLocation() ) - { - case AknLayoutUtils::EAknCbaLocationBottom: - // RSK must be moved to right, LSK in on correct position by default - if (position == RSK_POSITION) - iconPosition.setX(targetSize.width() - sourceSize.width()); - break; - case AknLayoutUtils::EAknCbaLocationRight: - case AknLayoutUtils::EAknCbaLocationLeft: - // Already in correct position - default: - break; - } - // Align horizontally to center - iconPosition.setY((targetSize.height() - sourceSize.height()) >> 1); + // Prior to S60 5.3 icons need to be properly positioned to buttons, but starting with 5.3 + // positioning is done on Avkon side. + if (QSysInfo::s60Version() < QSysInfo::SV_S60_5_3) { + switch (AknLayoutUtils::CbaLocation()) + { + case AknLayoutUtils::EAknCbaLocationBottom: + // RSK must be moved to right, LSK in on correct position by default + if (position == RSK_POSITION) + iconPosition.setX(targetSize.width() - sourceSize.width()); + break; + case AknLayoutUtils::EAknCbaLocationRight: + case AknLayoutUtils::EAknCbaLocationLeft: + // Already in correct position + default: + break; + } + + // Align horizontally to center + iconPosition.setY((targetSize.height() - sourceSize.height()) >> 1); + } return iconPosition; } diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index a7010cd..67eb07b 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -160,6 +160,7 @@ public: int orientationSet : 1; int partial_keyboard : 1; int partial_keyboardAutoTranslation : 1; + int partialKeyboardOpen : 1; QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type QPointer<QWidget> splitViewLastWidget; @@ -351,6 +352,7 @@ inline QS60Data::QS60Data() orientationSet(0), partial_keyboard(0), partial_keyboardAutoTranslation(1), + partialKeyboardOpen(0), s60ApplicationFactory(0) #ifdef Q_OS_SYMBIAN ,s60InstalledTrapHandler(0) diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h index 1a9830d..72acaf3 100644 --- a/src/gui/kernel/qt_x11_p.h +++ b/src/gui/kernel/qt_x11_p.h @@ -226,7 +226,6 @@ typedef void (*PtrXRRSelectInput)(Display *, Window, int); typedef int (*PtrXRRUpdateConfiguration)(XEvent *); typedef int (*PtrXRRRootToScreen)(Display *, Window); typedef Bool (*PtrXRRQueryExtension)(Display *, int *, int *); -typedef XRRScreenSize *(*PtrXRRSizes)(Display *, int, int *); #endif // QT_NO_XRANDR #ifndef QT_NO_XINPUT @@ -711,7 +710,6 @@ struct QX11Data PtrXRRUpdateConfiguration ptrXRRUpdateConfiguration; PtrXRRRootToScreen ptrXRRRootToScreen; PtrXRRQueryExtension ptrXRRQueryExtension; - PtrXRRSizes ptrXRRSizes; #endif // QT_NO_XRANDR }; diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 6a0b39d..ea2412b 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -299,6 +299,7 @@ QWidgetPrivate::QWidgetPrivate(int version) #ifndef QT_NO_IM , inheritsInputMethodHints(0) #endif + , inSetParent(0) #if defined(Q_WS_X11) , picture(0) #elif defined(Q_WS_WIN) @@ -1389,16 +1390,6 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) QApplication::postEvent(q, new QEvent(QEvent::PolishRequest)); extraPaintEngine = 0; - -#ifdef QT_MAC_USE_COCOA - // If we add a child to the unified toolbar, we have to redirect the painting. - if (parentWidget && parentWidget->d_func() && parentWidget->d_func()->isInUnifiedToolbar) { - if (parentWidget->d_func()->unifiedSurface) { - QWidget *toolbar = parentWidget->d_func()->toolbar_ancestor; - parentWidget->d_func()->unifiedSurface->recursiveRedirect(toolbar, toolbar, toolbar->d_func()->toolbar_offset); - } - } -#endif // QT_MAC_USE_COCOA } @@ -2599,6 +2590,22 @@ WId QWidget::effectiveWinId() const if (id || !testAttribute(Qt::WA_WState_Created)) return id; QWidget *realParent = nativeParentWidget(); + if (!realParent && d_func()->inSetParent) { + // In transitional state. This is really just a workaround. The real problem + // is that QWidgetPrivate::setParent_sys (platform specific code) first sets + // the window id to 0 (setWinId(0)) before it sets the Qt::WA_WState_Created + // attribute to false. The correct way is to do it the other way around, and + // in that case the Qt::WA_WState_Created logic above will kick in and + // return 0 whenever the widget is in a transitional state. However, changing + // the original logic for all platforms is far more intrusive and might + // break existing applications. + // Note: The widget can only be in a transitional state when changing its + // parent -- everything else is an internal error -- hence explicitly checking + // against 'inSetParent' rather than doing an unconditional return whenever + // 'realParent' is 0 (which may cause strange artifacts and headache later). + return 0; + } + // This widget *must* have a native parent widget. Q_ASSERT(realParent); Q_ASSERT(realParent->internalWinId()); return realParent->internalWinId(); @@ -10111,6 +10118,7 @@ void QWidget::setParent(QWidget *parent) void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) { Q_D(QWidget); + d->inSetParent = true; bool resized = testAttribute(Qt::WA_Resized); bool wasCreated = testAttribute(Qt::WA_WState_Created); QWidget *oldtlw = window(); @@ -10271,6 +10279,8 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) ancestorProxy->d_func()->embedSubWindow(this); } #endif + + d->inSetParent = false; } /*! diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 387d00c..778f1f1 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2733,7 +2733,7 @@ QWidget::macCGHandle() const return handle(); } -void qt_mac_repaintParentUnderAlienWidget(QWidget *alienWidget) +void qt_mac_updateParentUnderAlienWidget(QWidget *alienWidget) { QWidget *nativeParent = alienWidget->nativeParentWidget(); if (!nativeParent) @@ -2741,7 +2741,7 @@ void qt_mac_repaintParentUnderAlienWidget(QWidget *alienWidget) QPoint globalPos = alienWidget->mapToGlobal(QPoint(0, 0)); QRect dirtyRect = QRect(nativeParent->mapFromGlobal(globalPos), alienWidget->size()); - nativeParent->repaint(dirtyRect); + nativeParent->update(dirtyRect); } void QWidget::destroy(bool destroyWindow, bool destroySubWindows) @@ -2752,7 +2752,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); if (!internalWinId()) - qt_mac_repaintParentUnderAlienWidget(this); + qt_mac_updateParentUnderAlienWidget(this); d->deactivateWidgetCleanup(); qt_mac_event_release(this); if(testAttribute(Qt::WA_WState_Created)) { @@ -3032,6 +3032,16 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f) q->setAttribute(Qt::WA_WState_Hidden); q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden); +#ifdef QT_MAC_USE_COCOA + // If we add a child to the unified toolbar, we have to redirect the painting. + if (parent && parent->d_func() && parent->d_func()->isInUnifiedToolbar) { + if (parent->d_func()->unifiedSurface) { + QWidget *toolbar = parent->d_func()->toolbar_ancestor; + parent->d_func()->unifiedSurface->recursiveRedirect(toolbar, toolbar, toolbar->d_func()->toolbar_offset); + } + } +#endif // QT_MAC_USE_COCOA + if (wasCreated) { transferChildren(); #ifndef QT_MAC_USE_COCOA @@ -3526,8 +3536,8 @@ void QWidgetPrivate::show_sys() // INVARIANT: q is native. Just show the view: [view setHidden:NO]; } else { - // INVARIANT: q is alien. Repaint q instead: - q->repaint(); + // INVARIANT: q is alien. Update q instead: + q->update(); } #endif } @@ -3683,7 +3693,7 @@ void QWidgetPrivate::hide_sys() [view setHidden:YES]; } else { // INVARIANT: q is alien. Repaint where q is placed instead: - qt_mac_repaintParentUnderAlienWidget(q); + qt_mac_updateParentUnderAlienWidget(q); } #endif } diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 3991d90..ad65274 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -232,6 +232,7 @@ struct QTLWExtra { #elif defined(Q_OS_SYMBIAN) uint inExpose : 1; // Prevents drawing recursion uint nativeWindowTransparencyEnabled : 1; // Tracks native window transparency + uint forcedToRaster : 1; #elif defined(Q_WS_QPA) QPlatformWindow *platformWindow; QPlatformWindowFormat platformWindowFormat; @@ -770,6 +771,7 @@ public: #ifndef QT_NO_IM uint inheritsInputMethodHints : 1; #endif + uint inSetParent : 1; // *************************** Platform specific ************************************ #if defined(Q_WS_X11) // <----------------------------------------------------------- X11 diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index db5552f..5672686 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -578,6 +578,11 @@ void QWidgetPrivate::show_sys() if (isFullscreen) { const bool cbaVisible = S60->buttonGroupContainer() && S60->buttonGroupContainer()->IsVisible(); S60->setStatusPaneAndButtonGroupVisibility(false, cbaVisible); + if (cbaVisible) { + // Fix window dimensions as without screen furniture they will have + // defaulted to full screen dimensions initially. + id->handleClientAreaChange(); + } } } } @@ -792,7 +797,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f) adjustFlags(data.window_flags, q); // keep compatibility with previous versions, we need to preserve the created state // (but we recreate the winId for the widget being reparented, again for compatibility) - if (wasCreated || (!q->isWindow() && parent->testAttribute(Qt::WA_WState_Created))) + if (wasCreated || (!q->isWindow() && parent && parent->testAttribute(Qt::WA_WState_Created))) createWinId(); if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden) q->setAttribute(Qt::WA_WState_Hidden); @@ -835,7 +840,8 @@ void QWidgetPrivate::s60UpdateIsOpaque() RWindow *const window = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow()); #ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE - if (QApplicationPrivate::instance()->useTranslucentEGLSurfaces) { + if (QApplicationPrivate::instance()->useTranslucentEGLSurfaces + && !extra->topextra->forcedToRaster) { window->SetSurfaceTransparency(!isOpaque); extra->topextra->nativeWindowTransparencyEnabled = !isOpaque; return; @@ -1019,6 +1025,7 @@ void QWidgetPrivate::createTLSysExtra() { extra->topextra->inExpose = 0; extra->topextra->nativeWindowTransparencyEnabled = 0; + extra->topextra->forcedToRaster = 0; } void QWidgetPrivate::deleteTLSysExtra() diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 65e7af4..f1496b1 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -9,6 +9,7 @@ HEADERS += \ painting/qdrawutil.h \ painting/qemulationpaintengine_p.h \ painting/qgraphicssystem_p.h \ + painting/qgraphicssystemex_p.h \ painting/qmatrix.h \ painting/qmemrotate_p.h \ painting/qoutlinemapper_p.h \ @@ -249,8 +250,10 @@ embedded { symbian { HEADERS += painting/qwindowsurface_s60_p.h \ - painting/qdrawhelper_arm_simd_p.h - SOURCES += painting/qwindowsurface_s60.cpp + painting/qdrawhelper_arm_simd_p.h \ + painting/qgraphicssystemex_symbian_p.h + SOURCES += painting/qwindowsurface_s60.cpp \ + painting/qgraphicssystemex_symbian.cpp armccIfdefBlock = \ "$${LITERAL_HASH}if defined(ARMV6)" \ "MACRO QT_HAVE_ARM_SIMD" \ diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 8633dc1..3d895b7 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -532,8 +532,7 @@ QString QColor::name() const void QColor::setNamedColor(const QString &name) { - if (!setColorFromString(name)) - qWarning("QColor::setNamedColor: Unknown color name '%s'", name.toLatin1().constData()); + setColorFromString(name); } /*! diff --git a/src/gui/painting/qgraphicssystem.cpp b/src/gui/painting/qgraphicssystem.cpp index de0b516..d4a8015 100644 --- a/src/gui/painting/qgraphicssystem.cpp +++ b/src/gui/painting/qgraphicssystem.cpp @@ -55,6 +55,9 @@ #endif #ifdef Q_OS_SYMBIAN # include <private/qpixmap_s60_p.h> +# include <private/qgraphicssystemex_symbian_p.h> +#else +# include <private/qgraphicssystemex_p.h> #endif QT_BEGIN_NAMESPACE @@ -89,9 +92,18 @@ QPixmapData *QGraphicsSystem::createPixmapData(QPixmapData *origin) return createPixmapData(origin->pixelType()); } -void QGraphicsSystem::releaseCachedResources() +#ifdef Q_OS_SYMBIAN +Q_GLOBAL_STATIC(QSymbianGraphicsSystemEx, symbianPlatformExtension) +#endif + +QGraphicsSystemEx* QGraphicsSystem::platformExtension() { - // Do nothing here +#ifdef Q_OS_SYMBIAN + // this is used on raster graphics systems. HW accelerated + // graphics systems will overwrite this function. + return symbianPlatformExtension(); +#endif + return 0; } QT_END_NAMESPACE diff --git a/src/gui/painting/qgraphicssystem_p.h b/src/gui/painting/qgraphicssystem_p.h index 53c0551..db42fa8 100644 --- a/src/gui/painting/qgraphicssystem_p.h +++ b/src/gui/painting/qgraphicssystem_p.h @@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE class QPixmapFilter; class QBlittable; +class QGraphicsSystemEx; class Q_GUI_EXPORT QGraphicsSystem { @@ -77,7 +78,7 @@ public: // to have a graphics system. static QPixmapData *createDefaultPixmapData(QPixmapData::PixelType type); - virtual void releaseCachedResources(); + virtual QGraphicsSystemEx* platformExtension(); }; QT_END_NAMESPACE diff --git a/src/gui/util/qscrollerproperties_p.h b/src/gui/painting/qgraphicssystemex_p.h index 2e57a3f..55828f0 100644 --- a/src/gui/util/qscrollerproperties_p.h +++ b/src/gui/painting/qgraphicssystemex_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QSCROLLERPROPERTIES_P_H -#define QSCROLLERPROPERTIES_P_H +#ifndef QGRAPHICSSYSTEMEX_P_H +#define QGRAPHICSSYSTEMEX_P_H // // W A R N I N G @@ -53,42 +53,14 @@ // We mean it. // -#include <QPointF> -#include <QEasingCurve> -#include <qscrollerproperties.h> +#include <qglobal.h> QT_BEGIN_NAMESPACE -class QScrollerPropertiesPrivate +class Q_GUI_EXPORT QGraphicsSystemEx { -public: - static QScrollerPropertiesPrivate *defaults(); - - bool operator==(const QScrollerPropertiesPrivate &) const; - - qreal mousePressEventDelay; - qreal dragStartDistance; - qreal dragVelocitySmoothingFactor; - qreal axisLockThreshold; - QEasingCurve scrollingCurve; - qreal decelerationFactor; - qreal minimumVelocity; - qreal maximumVelocity; - qreal maximumClickThroughVelocity; - qreal acceleratingFlickMaximumTime; - qreal acceleratingFlickSpeedupFactor; - qreal snapPositionRatio; - qreal snapTime; - qreal overshootDragResistanceFactor; - qreal overshootDragDistanceFactor; - qreal overshootScrollDistanceFactor; - qreal overshootScrollTime; - QScrollerProperties::OvershootPolicy hOvershootPolicy; - QScrollerProperties::OvershootPolicy vOvershootPolicy; - QScrollerProperties::FrameRates frameRate; }; QT_END_NAMESPACE -#endif // QSCROLLERPROPERTIES_P_H - +#endif diff --git a/src/gui/painting/qgraphicssystemex_symbian.cpp b/src/gui/painting/qgraphicssystemex_symbian.cpp new file mode 100644 index 0000000..b53353b --- /dev/null +++ b/src/gui/painting/qgraphicssystemex_symbian.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgraphicssystemex_symbian_p.h" +#include "private/qwidget_p.h" +#include "private/qbackingstore_p.h" +#include "private/qapplication_p.h" + +#include <QDebug> + +QT_BEGIN_NAMESPACE + +void QSymbianGraphicsSystemEx::releaseCachedGpuResources() +{ + // Do nothing here + // This is implemented in graphics system specific plugin +} + +void QSymbianGraphicsSystemEx::releaseAllGpuResources() +{ + releaseCachedGpuResources(); + + foreach (QWidget *widget, QApplication::topLevelWidgets()) { + if (QTLWExtra *topExtra = qt_widget_private(widget)->maybeTopData()) + topExtra->backingStore.destroy(); + } +} + +bool QSymbianGraphicsSystemEx::hasBCM2727() +{ + return !QApplicationPrivate::instance()->useTranslucentEGLSurfaces; +} + +void QSymbianGraphicsSystemEx::forceToRaster(QWidget *window) +{ + if (window && window->isWindow()) { + qt_widget_private(window)->createTLExtra(); + if (QTLWExtra *topExtra = qt_widget_private(window)->maybeTopData()) { + topExtra->forcedToRaster = 1; + if (topExtra->backingStore.data()) { + topExtra->backingStore.create(window); + topExtra->backingStore.registerWidget(window); + } + } + } +} + +QT_END_NAMESPACE diff --git a/src/gui/util/qscroller_mac.mm b/src/gui/painting/qgraphicssystemex_symbian_p.h index c0ef4a1..c1d1bdf 100644 --- a/src/gui/util/qscroller_mac.mm +++ b/src/gui/painting/qgraphicssystemex_symbian_p.h @@ -39,33 +39,35 @@ ** ****************************************************************************/ -#include <QtCore/qglobal.h> +#ifndef QSYMBIANGRAPHICSSYSTEMEX_P_H +#define QSYMBIANGRAPHICSSYSTEMEX_P_H -#ifdef Q_WS_MAC +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// -#import <Cocoa/Cocoa.h> +#include "private/qgraphicssystemex_p.h" -#include "qscroller_p.h" +QT_BEGIN_NAMESPACE -QPointF QScrollerPrivate::realDpi(int screen) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSArray *nsscreens = [NSScreen screens]; - - if (screen < 0 || screen >= int([nsscreens count])) - screen = 0; +class QWidget; - NSScreen *nsscreen = [nsscreens objectAtIndex:screen]; - CGDirectDisplayID display = [[[nsscreen deviceDescription] objectForKey:@"NSScreenNumber"] intValue]; +class Q_GUI_EXPORT QSymbianGraphicsSystemEx : public QGraphicsSystemEx +{ +public: + virtual void releaseCachedGpuResources(); + virtual void releaseAllGpuResources(); + virtual bool hasBCM2727(); + virtual void forceToRaster(QWidget *window); +}; - CGSize mmsize = CGDisplayScreenSize(display); - if (mmsize.width > 0 && mmsize.height > 0) { - return QPointF(CGDisplayPixelsWide(display) / mmsize.width, - CGDisplayPixelsHigh(display) / mmsize.height) * qreal(25.4); - } else { - return QPointF(); - } - [pool release]; -} +QT_END_NAMESPACE #endif diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp index 01ece09..4309140 100644 --- a/src/gui/painting/qgraphicssystemfactory.cpp +++ b/src/gui/painting/qgraphicssystemfactory.cpp @@ -74,7 +74,7 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key) if (system.isEmpty()) { system = QLatin1String("runtime"); } -#elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) || defined(Q_WS_X11) +#elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) || defined(Q_WS_X11) || (defined (Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) if (system.isEmpty()) { system = QLatin1String("raster"); } diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp index ccf9d51..ecc0280 100644 --- a/src/gui/painting/qpaintbuffer.cpp +++ b/src/gui/painting/qpaintbuffer.cpp @@ -1768,12 +1768,12 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd) rawFontD->fontEngine = fontD->engineForScript(QUnicodeTables::Common); rawFontD->fontEngine->ref.ref(); - QGlyphs glyphs; - glyphs.setFont(rawFont); + QGlyphRun glyphs; + glyphs.setRawFont(rawFont); glyphs.setGlyphIndexes(glyphIndexes); glyphs.setPositions(positions); - painter->drawGlyphs(QPointF(), glyphs); + painter->drawGlyphRun(QPointF(), glyphs); break; } #endif diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 471f67f..17b7451 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -62,7 +62,7 @@ #include "qthread.h" #include "qvarlengtharray.h" #include "qstatictext.h" -#include "qglyphs.h" +#include "qglyphrun.h" #include <private/qfontengine_p.h> #include <private/qpaintengine_p.h> @@ -73,7 +73,7 @@ #include <private/qpaintengine_raster_p.h> #include <private/qmath_p.h> #include <private/qstatictext_p.h> -#include <private/qglyphs_p.h> +#include <private/qglyphrun_p.h> #include <private/qstylehelper_p.h> #include <private/qrawfont_p.h> @@ -5798,19 +5798,19 @@ void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QR \since 4.8 - \sa QGlyphs::setFont(), QGlyphs::setPositions(), QGlyphs::setGlyphIndexes() + \sa QGlyphRun::setRawFont(), QGlyphRun::setPositions(), QGlyphRun::setGlyphIndexes() */ #if !defined(QT_NO_RAWFONT) -void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs) +void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun) { Q_D(QPainter); - QRawFont font = glyphs.font(); + QRawFont font = glyphRun.rawFont(); if (!font.isValid()) return; - QVector<quint32> glyphIndexes = glyphs.glyphIndexes(); - QVector<QPointF> glyphPositions = glyphs.positions(); + QVector<quint32> glyphIndexes = glyphRun.glyphIndexes(); + QVector<QPointF> glyphPositions = glyphRun.positions(); int count = qMin(glyphIndexes.size(), glyphPositions.size()); QVarLengthArray<QFixedPoint, 128> fixedPointPositions(count); @@ -5819,6 +5819,13 @@ void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs) d->extended != 0 ? qt_paintengine_supports_transformations(d->extended->type()) : qt_paintengine_supports_transformations(d->engine->type()); + + // If the matrix is not affine, the paint engine will fall back to + // drawing the glyphs as paths, which in turn means we should not + // preprocess the glyph positions + if (!d->state->matrix.isAffine()) + paintEngineSupportsTransformations = true; + for (int i=0; i<count; ++i) { QPointF processedPosition = position + glyphPositions.at(i); if (!paintEngineSupportsTransformations) @@ -5826,8 +5833,8 @@ void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs) fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition); } - d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count, font, glyphs.overline(), - glyphs.underline(), glyphs.strikeOut()); + d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count, font, glyphRun.overline(), + glyphRun.underline(), glyphRun.strikeOut()); } void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, int glyphCount, @@ -5862,7 +5869,7 @@ void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, in QFixed width = rightMost - leftMost; - if (extended != 0) { + if (extended != 0 && state->matrix.isAffine()) { QStaticTextItem staticTextItem; staticTextItem.color = state->pen.color(); staticTextItem.font = state->font; diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index d2a8630..30f8da0 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -79,7 +79,7 @@ class QTextItem; class QMatrix; class QTransform; class QStaticText; -class QGlyphs; +class QGlyphRun; class QPainterPrivateDeleter; @@ -400,7 +400,7 @@ public: Qt::LayoutDirection layoutDirection() const; #if !defined(QT_NO_RAWFONT) - void drawGlyphs(const QPointF &position, const QGlyphs &glyphs); + void drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun); #endif void drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText); diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h index 2fae48d..ec09c94 100644 --- a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h +++ b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h @@ -65,6 +65,39 @@ QT_BEGIN_NAMESPACE class QNativeImage; +// +// This is the implementation of the unified toolbar on Mac OS X +// with the graphics system raster. +// +// General idea: +// ------------- +// We redirect the painting of widgets inside the unified toolbar +// to a special window surface, the QUnifiedToolbarSurface. +// We need a separate window surface because the unified toolbar +// is out of the content view. +// The input system is the same as for the unified toolbar with the +// native (CoreGraphics) engine. +// +// Execution flow: +// --------------- +// The unified toolbar is triggered by QMainWindow::setUnifiedTitleAndToolBarOnMac(). +// It calls QMainWindowLayout::insertIntoMacToolbar() which will +// set all the appropriate variables (offsets, redirection, ...). +// When Qt tells a widget to repaint, QWidgetPrivate::drawWidget() +// checks if the widget is inside the unified toolbar and exits without +// painting is that is the case. +// We trigger the rendering of the unified toolbar in QWidget::repaint() +// and QWidget::update(). +// We keep track of flush requests via "flushRequested" variable. That +// allow flush() to be a no-op if no repaint occurred for a widget. +// We rely on the needsDisplay: and drawRect: mecanism for drawing our +// content into the graphics context. +// +// Notes: +// ------ +// The painting of items inside the unified toolbar is expensive. +// Too many repaints will drastically slow down the whole application. +// class QUnifiedToolbarSurfacePrivate { diff --git a/src/gui/text/qfont_mac.cpp b/src/gui/text/qfont_mac.cpp index 1856185..3bbff7f 100644 --- a/src/gui/text/qfont_mac.cpp +++ b/src/gui/text/qfont_mac.cpp @@ -43,6 +43,7 @@ #include "qfont_p.h" #include "qfontengine_p.h" #include "qfontengine_mac_p.h" +#include "qfontengine_coretext_p.h" #include "qfontinfo.h" #include "qfontmetrics.h" #include "qpaintdevice.h" @@ -119,10 +120,10 @@ quint32 QFont::macFontID() const // ### need 64-bit version // Returns an ATSUFonFamilyRef Qt::HANDLE QFont::handle() const { -#if 0 +#ifdef QT_MAC_USE_COCOA QFontEngine *fe = d->engineForScript(QUnicodeTables::Common); - if (fe && fe->type() == QFontEngine::Mac) - return (Qt::HANDLE)static_cast<QFontEngineMacMulti*>(fe)->fontFamilyRef(); + if (fe && fe->type() == QFontEngine::Multi) + return (Qt::HANDLE)static_cast<QCoreTextFontEngineMulti*>(fe)->macFontID(); #endif return 0; } diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index ae1cef6..24bd750 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -871,7 +871,7 @@ QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const newFontDef.pixelSize = pixelSize; newFontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi(); - return new QCoreTextFontEngine(cgFont, fontDef); + return new QCoreTextFontEngine(cgFont, newFontDef); } QT_END_NAMESPACE diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h index a9c938c..98d3b50 100644 --- a/src/gui/text/qfontengine_coretext_p.h +++ b/src/gui/text/qfontengine_coretext_p.h @@ -124,6 +124,8 @@ public: QScriptItem *si) const; virtual const char *name() const { return "CoreText"; } + inline CTFontRef macFontID() const { return ctfont; } + protected: virtual void loadEngine(int at); diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index ec47d2c..f514942 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1597,7 +1597,7 @@ void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlag FT_Face face = 0; bool design = (default_hint_style == HintNone || default_hint_style == HintLight || - (flags & HB_ShaperFlag_UseDesignMetrics)); + (flags & HB_ShaperFlag_UseDesignMetrics)) && FT_IS_SCALABLE(freetype->face); for (int i = 0; i < glyphs->numGlyphs; i++) { Glyph *g = defaultGlyphSet.getGlyph(glyphs->glyphs[i]); if (g) { @@ -1751,6 +1751,7 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe } else { glyphSet = &defaultGlyphSet; } + bool needsDelete = false; Glyph * g = glyphSet->getGlyph(glyph); if (!g || g->format != format) { face = lockFace(); @@ -1758,6 +1759,7 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe FT_Matrix_Multiply(&glyphSet->transformationMatrix, &m); freetype->matrix = m; g = loadGlyph(glyphSet, glyph, subPixelPosition, format); + needsDelete = true; } if (g) { @@ -1766,6 +1768,8 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe overall.width = g->width; overall.height = g->height; overall.xoff = g->advance; + if (needsDelete) + delete g; } else { int left = FLOOR(face->glyph->metrics.horiBearingX); int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width); diff --git a/src/gui/text/qglyphs.cpp b/src/gui/text/qglyphrun.cpp index 922024c..05e3b6b 100644 --- a/src/gui/text/qglyphs.cpp +++ b/src/gui/text/qglyphrun.cpp @@ -43,14 +43,14 @@ #if !defined(QT_NO_RAWFONT) -#include "qglyphs.h" -#include "qglyphs_p.h" +#include "qglyphrun.h" +#include "qglyphrun_p.h" QT_BEGIN_NAMESPACE /*! - \class QGlyphs - \brief The QGlyphs class provides direct access to the internal glyphs in a font. + \class QGlyphRun + \brief The QGlyphRun class provides direct access to the internal glyphs in a font. \since 4.8 \ingroup text @@ -67,42 +67,43 @@ QT_BEGIN_NAMESPACE Under certain circumstances, it can be useful as an application developer to have more low-level control over which glyphs in a specific font are drawn to the screen. This could for instance be the case in applications that use an external font engine and text shaper together with Qt. - QGlyphs provides an interface to the raw data needed to get text on the screen. It + QGlyphRun provides an interface to the raw data needed to get text on the screen. It contains a list of glyph indexes, a position for each glyph and a font. It is the user's responsibility to ensure that the selected font actually contains the provided glyph indexes. - QTextLayout::glyphs() or QTextFragment::glyphs() can be used to convert unicode encoded text - into a list of QGlyphs objects, and QPainter::drawGlyphs() can be used to draw the glyphs. + QTextLayout::glyphRuns() or QTextFragment::glyphRuns() can be used to convert unicode encoded + text into a list of QGlyphRun objects, and QPainter::drawGlyphRun() can be used to draw the + glyphs. \note Please note that QRawFont is considered local to the thread in which it is constructed. - This in turn means that a new QRawFont will have to be created and set on the QGlyphs if it is - moved to a different thread. If the QGlyphs contains a reference to a QRawFont from a different + This in turn means that a new QRawFont will have to be created and set on the QGlyphRun if it is + moved to a different thread. If the QGlyphRun contains a reference to a QRawFont from a different thread than the current, it will not be possible to draw the glyphs using a QPainter, as the QRawFont is considered invalid and inaccessible in this case. */ /*! - Constructs an empty QGlyphs object. + Constructs an empty QGlyphRun object. */ -QGlyphs::QGlyphs() : d(new QGlyphsPrivate) +QGlyphRun::QGlyphRun() : d(new QGlyphRunPrivate) { } /*! - Constructs a QGlyphs object which is a copy of \a other. + Constructs a QGlyphRun object which is a copy of \a other. */ -QGlyphs::QGlyphs(const QGlyphs &other) +QGlyphRun::QGlyphRun(const QGlyphRun &other) { d = other.d; } /*! - Destroys the QGlyphs. + Destroys the QGlyphRun. */ -QGlyphs::~QGlyphs() +QGlyphRun::~QGlyphRun() { // Required for QExplicitlySharedDataPointer } @@ -110,26 +111,26 @@ QGlyphs::~QGlyphs() /*! \internal */ -void QGlyphs::detach() +void QGlyphRun::detach() { if (d->ref != 1) d.detach(); } /*! - Assigns \a other to this QGlyphs object. + Assigns \a other to this QGlyphRun object. */ -QGlyphs &QGlyphs::operator=(const QGlyphs &other) +QGlyphRun &QGlyphRun::operator=(const QGlyphRun &other) { d = other.d; return *this; } /*! - Compares \a other to this QGlyphs object. Returns true if the list of glyph indexes, + Compares \a other to this QGlyphRun object. Returns true if the list of glyph indexes, the list of positions and the font are all equal, otherwise returns false. */ -bool QGlyphs::operator==(const QGlyphs &other) const +bool QGlyphRun::operator==(const QGlyphRun &other) const { return ((d == other.d) || (d->glyphIndexes == other.d->glyphIndexes @@ -137,14 +138,14 @@ bool QGlyphs::operator==(const QGlyphs &other) const && d->overline == other.d->overline && d->underline == other.d->underline && d->strikeOut == other.d->strikeOut - && d->font == other.d->font)); + && d->rawFont == other.d->rawFont)); } /*! - Compares \a other to this QGlyphs object. Returns true if any of the list of glyph + Compares \a other to this QGlyphRun object. Returns true if any of the list of glyph indexes, the list of positions or the font are different, otherwise returns false. */ -bool QGlyphs::operator!=(const QGlyphs &other) const +bool QGlyphRun::operator!=(const QGlyphRun &other) const { return !(*this == other); } @@ -152,13 +153,13 @@ bool QGlyphs::operator!=(const QGlyphs &other) const /*! \internal - Adds together the lists of glyph indexes and positions in \a other and this QGlyphs - object and returns the result. The font in the returned QGlyphs will be the same as in - this QGlyphs object. + Adds together the lists of glyph indexes and positions in \a other and this QGlyphRun + object and returns the result. The font in the returned QGlyphRun will be the same as in + this QGlyphRun object. */ -QGlyphs QGlyphs::operator+(const QGlyphs &other) const +QGlyphRun QGlyphRun::operator+(const QGlyphRun &other) const { - QGlyphs ret(*this); + QGlyphRun ret(*this); ret += other; return ret; } @@ -166,10 +167,10 @@ QGlyphs QGlyphs::operator+(const QGlyphs &other) const /*! \internal - Appends the glyph indexes and positions in \a other to this QGlyphs object and returns + Appends the glyph indexes and positions in \a other to this QGlyphRun object and returns a reference to the current object. */ -QGlyphs &QGlyphs::operator+=(const QGlyphs &other) +QGlyphRun &QGlyphRun::operator+=(const QGlyphRun &other) { detach(); @@ -180,41 +181,41 @@ QGlyphs &QGlyphs::operator+=(const QGlyphs &other) } /*! - Returns the font selected for this QGlyphs object. + Returns the font selected for this QGlyphRun object. - \sa setFont() + \sa setRawFont() */ -QRawFont QGlyphs::font() const +QRawFont QGlyphRun::rawFont() const { - return d->font; + return d->rawFont; } /*! Sets the font in which to look up the glyph indexes to \a font. - \sa font(), setGlyphIndexes() + \sa rawFont(), setGlyphIndexes() */ -void QGlyphs::setFont(const QRawFont &font) +void QGlyphRun::setRawFont(const QRawFont &rawFont) { detach(); - d->font = font; + d->rawFont = rawFont; } /*! - Returns the glyph indexes for this QGlyphs object. + Returns the glyph indexes for this QGlyphRun object. \sa setGlyphIndexes(), setPositions() */ -QVector<quint32> QGlyphs::glyphIndexes() const +QVector<quint32> QGlyphRun::glyphIndexes() const { return d->glyphIndexes; } /*! - Set the glyph indexes for this QGlyphs object to \a glyphIndexes. The glyph indexes must + Set the glyph indexes for this QGlyphRun object to \a glyphIndexes. The glyph indexes must be valid for the selected font. */ -void QGlyphs::setGlyphIndexes(const QVector<quint32> &glyphIndexes) +void QGlyphRun::setGlyphIndexes(const QVector<quint32> &glyphIndexes) { detach(); d->glyphIndexes = glyphIndexes; @@ -223,7 +224,7 @@ void QGlyphs::setGlyphIndexes(const QVector<quint32> &glyphIndexes) /*! Returns the position of the edge of the baseline for each glyph in this set of glyph indexes. */ -QVector<QPointF> QGlyphs::positions() const +QVector<QPointF> QGlyphRun::positions() const { return d->glyphPositions; } @@ -232,87 +233,87 @@ QVector<QPointF> QGlyphs::positions() const Sets the positions of the edge of the baseline for each glyph in this set of glyph indexes to \a positions. */ -void QGlyphs::setPositions(const QVector<QPointF> &positions) +void QGlyphRun::setPositions(const QVector<QPointF> &positions) { detach(); d->glyphPositions = positions; } /*! - Clears all data in the QGlyphs object. + Clears all data in the QGlyphRun object. */ -void QGlyphs::clear() +void QGlyphRun::clear() { detach(); d->glyphPositions = QVector<QPointF>(); d->glyphIndexes = QVector<quint32>(); - d->font = QRawFont(); + d->rawFont = QRawFont(); d->strikeOut = false; d->overline = false; d->underline = false; } /*! - Returns true if this QGlyphs should be painted with an overline decoration. + Returns true if this QGlyphRun should be painted with an overline decoration. \sa setOverline() */ -bool QGlyphs::overline() const +bool QGlyphRun::overline() const { return d->overline; } /*! - Indicates that this QGlyphs should be painted with an overline decoration if \a overline is true. - Otherwise the QGlyphs should be painted with no overline decoration. + Indicates that this QGlyphRun should be painted with an overline decoration if \a overline is true. + Otherwise the QGlyphRun should be painted with no overline decoration. \sa overline() */ -void QGlyphs::setOverline(bool overline) +void QGlyphRun::setOverline(bool overline) { detach(); d->overline = overline; } /*! - Returns true if this QGlyphs should be painted with an underline decoration. + Returns true if this QGlyphRun should be painted with an underline decoration. \sa setUnderline() */ -bool QGlyphs::underline() const +bool QGlyphRun::underline() const { return d->underline; } /*! - Indicates that this QGlyphs should be painted with an underline decoration if \a underline is - true. Otherwise the QGlyphs should be painted with no underline decoration. + Indicates that this QGlyphRun should be painted with an underline decoration if \a underline is + true. Otherwise the QGlyphRun should be painted with no underline decoration. \sa underline() */ -void QGlyphs::setUnderline(bool underline) +void QGlyphRun::setUnderline(bool underline) { detach(); d->underline = underline; } /*! - Returns true if this QGlyphs should be painted with a strike out decoration. + Returns true if this QGlyphRun should be painted with a strike out decoration. \sa setStrikeOut() */ -bool QGlyphs::strikeOut() const +bool QGlyphRun::strikeOut() const { return d->strikeOut; } /*! - Indicates that this QGlyphs should be painted with an strike out decoration if \a strikeOut is - true. Otherwise the QGlyphs should be painted with no strike out decoration. + Indicates that this QGlyphRun should be painted with an strike out decoration if \a strikeOut is + true. Otherwise the QGlyphRun should be painted with no strike out decoration. \sa strikeOut() */ -void QGlyphs::setStrikeOut(bool strikeOut) +void QGlyphRun::setStrikeOut(bool strikeOut) { detach(); d->strikeOut = strikeOut; diff --git a/src/gui/text/qglyphs.h b/src/gui/text/qglyphrun.h index 68b1868..e43f1ef 100644 --- a/src/gui/text/qglyphs.h +++ b/src/gui/text/qglyphrun.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QGLYPHS_H -#define QGLYPHS_H +#ifndef QGLYPHRUN_H +#define QGLYPHRUN_H #include <QtCore/qsharedpointer.h> #include <QtCore/qvector.h> @@ -55,16 +55,16 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -class QGlyphsPrivate; -class Q_GUI_EXPORT QGlyphs +class QGlyphRunPrivate; +class Q_GUI_EXPORT QGlyphRun { public: - QGlyphs(); - QGlyphs(const QGlyphs &other); - ~QGlyphs(); + QGlyphRun(); + QGlyphRun(const QGlyphRun &other); + ~QGlyphRun(); - QRawFont font() const; - void setFont(const QRawFont &font); + QRawFont rawFont() const; + void setRawFont(const QRawFont &rawFont); QVector<quint32> glyphIndexes() const; void setGlyphIndexes(const QVector<quint32> &glyphIndexes); @@ -74,9 +74,9 @@ public: void clear(); - QGlyphs &operator=(const QGlyphs &other); - bool operator==(const QGlyphs &other) const; - bool operator!=(const QGlyphs &other) const; + QGlyphRun &operator=(const QGlyphRun &other); + bool operator==(const QGlyphRun &other) const; + bool operator!=(const QGlyphRun &other) const; void setOverline(bool overline); bool overline() const; @@ -88,14 +88,14 @@ public: bool strikeOut() const; private: - friend class QGlyphsPrivate; + friend class QGlyphRunPrivate; friend class QTextLine; - QGlyphs operator+(const QGlyphs &other) const; - QGlyphs &operator+=(const QGlyphs &other); + QGlyphRun operator+(const QGlyphRun &other) const; + QGlyphRun &operator+=(const QGlyphRun &other); void detach(); - QExplicitlySharedDataPointer<QGlyphsPrivate> d; + QExplicitlySharedDataPointer<QGlyphRunPrivate> d; }; QT_END_NAMESPACE diff --git a/src/gui/text/qglyphs_p.h b/src/gui/text/qglyphrun_p.h index cd2261d..533679d 100644 --- a/src/gui/text/qglyphs_p.h +++ b/src/gui/text/qglyphrun_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QGLYPHS_P_H -#define QGLYPHS_P_H +#ifndef QGLYPHRUN_P_H +#define QGLYPHRUN_P_H // // W A R N I N G @@ -53,7 +53,7 @@ // We mean it. // -#include "qglyphs.h" +#include "qglyphrun.h" #include "qrawfont.h" #include <qfont.h> @@ -64,21 +64,21 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QGlyphsPrivate: public QSharedData +class QGlyphRunPrivate: public QSharedData { public: - QGlyphsPrivate() + QGlyphRunPrivate() : overline(false) , underline(false) , strikeOut(false) { } - QGlyphsPrivate(const QGlyphsPrivate &other) + QGlyphRunPrivate(const QGlyphRunPrivate &other) : QSharedData(other) , glyphIndexes(other.glyphIndexes) , glyphPositions(other.glyphPositions) - , font(other.font) + , rawFont(other.rawFont) , overline(other.overline) , underline(other.underline) , strikeOut(other.strikeOut) @@ -87,7 +87,7 @@ public: QVector<quint32> glyphIndexes; QVector<QPointF> glyphPositions; - QRawFont font; + QRawFont rawFont; uint overline : 1; uint underline : 1; diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index b72fc9b..843deb0 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -78,7 +78,7 @@ QT_BEGIN_NAMESPACE A QRawFont object represents a single, physical instance of a given font in a given pixel size. I.e. in the typical case it represents a set of TrueType or OpenType font tables and uses a user specified pixel size to convert metrics into logical pixel units. In can be used in - combination with the QGlyphs class to draw specific glyph indexes at specific positions, and + combination with the QGlyphRun class to draw specific glyph indexes at specific positions, and also have accessors to some relevant data in the physical font. QRawFont only provides support for the main font technologies: GDI and DirectWrite on Windows @@ -87,9 +87,9 @@ QT_BEGIN_NAMESPACE QRawFont can be constructed in a number of ways: \list - \o \l It can be constructed by calling QTextLayout::glyphs() or QTextFragment::glyphs(). The - returned QGlyphs objects will contain QRawFont objects which represent the actual fonts - used to render each portion of the text. + \o \l It can be constructed by calling QTextLayout::glyphRuns() or QTextFragment::glyphRuns(). + The returned QGlyphRun objects will contain QRawFont objects which represent the actual + fonts used to render each portion of the text. \o \l It can be constructed by passing a QFont object to QRawFont::fromFont(). The function will return a QRawFont object representing the font that will be selected as response to the QFont query and the selected writing system. @@ -234,7 +234,7 @@ void QRawFont::loadFromData(const QByteArray &fontData, the pixel in the rasterization of the glyph. Otherwise, the image will be in the format of QImage::Format_A8 and each pixel will contain the opacity of the pixel in the rasterization. - \sa pathForGlyph(), QPainter::drawGlyphs() + \sa pathForGlyph(), QPainter::drawGlyphRun() */ QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType, const QTransform &transform) const @@ -426,9 +426,9 @@ int QRawFont::weight() const underlying font. Note that in cases where there are other tables in the font that affect the shaping of the text, the returned glyph indexes will not correctly represent the rendering of the text. To get the correctly shaped text, you can use QTextLayout to lay out and shape the - text, and then call QTextLayout::glyphs() to get the set of glyph index list and QRawFont pairs. + text, and then call QTextLayout::glyphRuns() to get the set of glyph index list and QRawFont pairs. - \sa advancesForGlyphIndexes(), QGlyphs, QTextLayout::glyphs(), QTextFragment::glyphs() + \sa advancesForGlyphIndexes(), glyphIndexesForChars(), QGlyphRun, QTextLayout::glyphRuns(), QTextFragment::glyphRuns() */ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const { @@ -437,11 +437,9 @@ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const int nglyphs = text.size(); QVarLengthGlyphLayoutArray glyphs(nglyphs); - if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &nglyphs, - QTextEngine::GlyphIndicesOnly)) { + if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) { glyphs.resize(nglyphs); - if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &nglyphs, - QTextEngine::GlyphIndicesOnly)) { + if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) { Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice"); return QVector<quint32>(); } @@ -455,6 +453,26 @@ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const } /*! + Converts a string of unicode points to glyph indexes using the CMAP table in the + underlying font. The function works like glyphIndexesForString() except it take + an array (\a chars), the results will be returned though \a glyphIndexes array + and number of glyphs will be set in \a numGlyphs. The size of \a glyphIndexes array + must be at least \a numChars, if that's still not enough, this function will return + false, then you can resize \a glyphIndexes from the size returned in \a numGlyphs. + + \sa glyphIndexesForString(), advancesForGlyphIndexes(), QGlyphs, QTextLayout::glyphs(), QTextFragment::glyphs() +*/ +bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const +{ + if (!isValid()) + return false; + + QGlyphLayout glyphs; + glyphs.glyphs = glyphIndexes; + return d->fontEngine->stringToCMap(chars, numChars, &glyphs, numGlyphs, QTextEngine::GlyphIndicesOnly); +} + +/*! Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances give the distance from the position of a given glyph to where the next glyph should be drawn to make it appear as if the two glyphs are unspaced. @@ -480,6 +498,36 @@ QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyph } /*! + Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances + give the distance from the position of a given glyph to where the next glyph should be drawn + to make it appear as if the two glyphs are unspaced. The glyph indexes are given with the + array \a glyphIndexes while the results are returned through \a advances, both of them must + have \a numGlyphs elements. + + \sa QTextLine::horizontalAdvance(), QFontMetricsF::width() +*/ +bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const +{ + if (!isValid()) + return false; + + QGlyphLayout glyphs; + glyphs.glyphs = const_cast<HB_Glyph *>(glyphIndexes); + glyphs.numGlyphs = numGlyphs; + QVarLengthArray<QFixed> advances_x(numGlyphs); + QVarLengthArray<QFixed> advances_y(numGlyphs); + glyphs.advances_x = advances_x.data(); + glyphs.advances_y = advances_y.data(); + + d->fontEngine->recalcAdvances(&glyphs, 0); + + for (int i=0; i<numGlyphs; ++i) + advances[i] = QPointF(glyphs.advances_x[i].toReal(), glyphs.advances_y[i].toReal()); + + return true; +} + +/*! Returns the hinting preference used to construct this QRawFont. \sa QFont::hintingPreference() @@ -587,17 +635,17 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ layout.beginLayout(); QTextLine line = layout.createLine(); layout.endLayout(); - QList<QGlyphs> list = layout.glyphs(); + QList<QGlyphRun> list = layout.glyphRuns(); if (list.size()) { // Pick the one matches the family name we originally requested, // if none of them match, just pick the first one for (int i = 0; i < list.size(); i++) { - QGlyphs glyphs = list.at(i); - QRawFont rawfont = glyphs.font(); + QGlyphRun glyphs = list.at(i); + QRawFont rawfont = glyphs.rawFont(); if (rawfont.familyName() == font.family()) return rawfont; } - return list.at(0).font(); + return list.at(0).rawFont(); } return QRawFont(); #else diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h index 328cc1c..da56d3d 100644 --- a/src/gui/text/qrawfont.h +++ b/src/gui/text/qrawfont.h @@ -90,6 +90,8 @@ public: QVector<quint32> glyphIndexesForString(const QString &text) const; QVector<QPointF> advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const; + bool glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const; + bool advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const; QImage alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType = SubPixelAntialiasing, diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index 347761a..aacac04 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -677,7 +677,7 @@ void QTextControlPrivate::extendWordwiseSelection(int suggestedNewPosition, qrea const qreal wordEndX = line.cursorToX(curs.position() - blockPos) + blockCoordinates.x(); - if (mouseXPosition < wordStartX || mouseXPosition > wordEndX) + if (!wordSelectionEnabled && (mouseXPosition < wordStartX || mouseXPosition > wordEndX)) return; // keep the already selected word even when moving to the left @@ -1579,8 +1579,10 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con emit q->cursorPositionChanged(); _q_updateCurrentCharFormatAndSelection(); } else { - if (cursor.position() != oldCursorPos) + if (cursor.position() != oldCursorPos) { emit q->cursorPositionChanged(); + emit q->microFocusChanged(); + } selectionChanged(); } repaintOldAndNewSelection(oldSelection); diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 2b2a124..8bbe86c 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -362,7 +362,7 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor currentCharFormat = -1; bool adjustX = true; QTextBlock blockIt = block(); - bool visualMovement = priv->defaultCursorMoveStyle == QTextCursor::Visual; + bool visualMovement = priv->defaultCursorMoveStyle == Qt::VisualMoveStyle; if (!blockIt.isValid()) return false; @@ -2568,18 +2568,18 @@ QTextDocument *QTextCursor::document() const } /*! - \enum QTextCursor::MoveStyle + \enum Qt::CursorMoveStyle - This enum describes the movement style available to QTextCursor. The options + This enum describes the movement style available to text cursors. The options are: - \value Logical Within a left-to-right text block, increase cursor position - when pressing left arrow key, decrease cursor position when pressing the - right arrow key. If the text block is right-to-left, the opposite behavior + \value LogicalMoveStyle Within a left-to-right text block, decrease cursor + position when pressing left arrow key, increase cursor position when pressing + the right arrow key. If the text block is right-to-left, the opposite behavior applies. - \value Visual Pressing the left arrow key will always cause the cursor to move - left, regardless of the text's writing direction. The same behavior applies to - right arrow key. + \value VisualMoveStyle Pressing the left arrow key will always cause the cursor + to move left, regardless of the text's writing direction. Pressing the right + arrow key will always cause the cursor to move right. */ QT_END_NAMESPACE diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index 0bb90ea..697899b 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -86,10 +86,6 @@ public: MoveAnchor, KeepAnchor }; - enum MoveStyle { - Logical, - Visual - }; void setPosition(int pos, MoveMode mode = MoveAnchor); int position() const; diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index f8e6bb7..fe3c993 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -589,9 +589,9 @@ void QTextDocument::setDefaultTextOption(const QTextOption &option) \since 4.8 The default cursor movement style is used by all QTextCursor objects - created from the document. The default is QTextCursor::Logical. + created from the document. The default is Qt::LogicalMoveStyle. */ -QTextCursor::MoveStyle QTextDocument::defaultCursorMoveStyle() const +Qt::CursorMoveStyle QTextDocument::defaultCursorMoveStyle() const { Q_D(const QTextDocument); return d->defaultCursorMoveStyle; @@ -602,7 +602,7 @@ QTextCursor::MoveStyle QTextDocument::defaultCursorMoveStyle() const Set the default cursor movement style. */ -void QTextDocument::setDefaultCursorMoveStyle(QTextCursor::MoveStyle style) +void QTextDocument::setDefaultCursorMoveStyle(Qt::CursorMoveStyle style) { Q_D(QTextDocument); d->defaultCursorMoveStyle = style; @@ -2099,6 +2099,10 @@ QString QTextHtmlExporter::toHtml(const QByteArray &encoding, ExportMode mode) html += QLatin1String(" font-size:"); html += QString::number(defaultCharFormat.fontPointSize()); html += QLatin1String("pt;"); + } else if (defaultCharFormat.hasProperty(QTextFormat::FontPixelSize)) { + html += QLatin1String(" font-size:"); + html += QString::number(defaultCharFormat.intProperty(QTextFormat::FontPixelSize)); + html += QLatin1String("px;"); } html += QLatin1String(" font-weight:"); @@ -2179,6 +2183,10 @@ bool QTextHtmlExporter::emitCharFormatStyle(const QTextCharFormat &format) html += QLatin1Char(';'); attributesEmitted = true; } + } else if (format.hasProperty(QTextFormat::FontPixelSize)) { + html += QLatin1String(" font-size:"); + html += QString::number(format.intProperty(QTextFormat::FontPixelSize)); + html += QLatin1String("px;"); } if (format.hasProperty(QTextFormat::FontWeight) diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h index 3c7cb87..268b72e 100644 --- a/src/gui/text/qtextdocument.h +++ b/src/gui/text/qtextdocument.h @@ -46,7 +46,6 @@ #include <QtCore/qsize.h> #include <QtCore/qrect.h> #include <QtGui/qfont.h> -#include <QtGui/qtextcursor.h> QT_BEGIN_HEADER @@ -70,6 +69,7 @@ class QUrl; class QVariant; class QRectF; class QTextOption; +class QTextCursor; template<typename T> class QVector; @@ -269,8 +269,8 @@ public: QTextOption defaultTextOption() const; void setDefaultTextOption(const QTextOption &option); - QTextCursor::MoveStyle defaultCursorMoveStyle() const; - void setDefaultCursorMoveStyle(QTextCursor::MoveStyle style); + Qt::CursorMoveStyle defaultCursorMoveStyle() const; + void setDefaultCursorMoveStyle(Qt::CursorMoveStyle style); Q_SIGNALS: void contentsChange(int from, int charsRemoves, int charsAdded); diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 4abbcb7..f4cb742 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -209,7 +209,7 @@ QTextDocumentPrivate::QTextDocumentPrivate() defaultTextOption.setTabStop(80); // same as in qtextengine.cpp defaultTextOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); - defaultCursorMoveStyle = QTextCursor::Logical; + defaultCursorMoveStyle = Qt::LogicalMoveStyle; indentWidth = 40; documentMargin = 4; diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h index 3dd3388..fbf91bf 100644 --- a/src/gui/text/qtextdocument_p.h +++ b/src/gui/text/qtextdocument_p.h @@ -342,7 +342,7 @@ private: public: QTextOption defaultTextOption; - QTextCursor::MoveStyle defaultCursorMoveStyle; + Qt::CursorMoveStyle defaultCursorMoveStyle; #ifndef QT_NO_CSSPARSER QCss::StyleSheet parsedDefaultStyleSheet; #endif diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 358442f..ed24d59 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -598,7 +598,7 @@ public: inline bool visualCursorMovement() const { return (visualMovement || - (block.docHandle() ? block.docHandle()->defaultCursorMoveStyle == QTextCursor::Visual : false)); + (block.docHandle() ? block.docHandle()->defaultCursorMoveStyle == Qt::VisualMoveStyle : false)); } struct SpecialData { diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index df0ce9b..988ae93 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -52,8 +52,8 @@ #include "qtextformat_p.h" #include "qstyleoption.h" #include "qpainterpath.h" -#include "qglyphs.h" -#include "qglyphs_p.h" +#include "qglyphrun.h" +#include "qglyphrun_p.h" #include "qrawfont.h" #include "qrawfont_p.h" #include <limits.h> @@ -579,27 +579,27 @@ bool QTextLayout::cacheEnabled() const } /*! - Set the visual cursor movement style. If the QTextLayout is backed by + Set the cursor movement style. If the QTextLayout is backed by a document, you can ignore this and use the option in QTextDocument, this option is for widgets like QLineEdit or custom widgets without - a QTextDocument. Default value is QTextCursor::Logical. + a QTextDocument. Default value is Qt::LogicalMoveStyle. \sa setCursorMoveStyle() */ -void QTextLayout::setCursorMoveStyle(QTextCursor::MoveStyle style) +void QTextLayout::setCursorMoveStyle(Qt::CursorMoveStyle style) { - d->visualMovement = style == QTextCursor::Visual ? true : false; + d->visualMovement = style == Qt::VisualMoveStyle ? true : false; } /*! The cursor movement style of this QTextLayout. The default is - QTextCursor::Logical. + Qt::LogicalMoveStyle. \sa setCursorMoveStyle() */ -QTextCursor::MoveStyle QTextLayout::cursorMoveStyle() const +Qt::CursorMoveStyle QTextLayout::cursorMoveStyle() const { - return d->visualMovement ? QTextCursor::Visual : QTextCursor::Logical; + return d->visualMovement ? Qt::VisualMoveStyle : Qt::LogicalMoveStyle; } /*! @@ -994,12 +994,12 @@ static inline QRectF clipIfValid(const QRectF &rect, const QRectF &clip) \since 4.8 - \sa draw(), QPainter::drawGlyphs() + \sa draw(), QPainter::drawGlyphRun() */ #if !defined(QT_NO_RAWFONT) -QList<QGlyphs> QTextLayout::glyphs() const +QList<QGlyphRun> QTextLayout::glyphRuns() const { - QList<QGlyphs> glyphs; + QList<QGlyphRun> glyphs; for (int i=0; i<d->lines.size(); ++i) glyphs += QTextLine(i, d).glyphs(-1, -1); @@ -2093,15 +2093,15 @@ namespace { \since 4.8 - \sa QTextLayout::glyphs() + \sa QTextLayout::glyphRuns() */ #if !defined(QT_NO_RAWFONT) -QList<QGlyphs> QTextLine::glyphs(int from, int length) const +QList<QGlyphRun> QTextLine::glyphs(int from, int length) const { const QScriptLine &line = eng->lines[i]; if (line.length == 0) - return QList<QGlyphs>(); + return QList<QGlyphRun>(); QHash<QFontEngine *, GlyphInfo> glyphLayoutHash; @@ -2166,7 +2166,7 @@ QList<QGlyphs> QTextLine::glyphs(int from, int length) const } } - QHash<QPair<QFontEngine *, int>, QGlyphs> glyphsHash; + QHash<QPair<QFontEngine *, int>, QGlyphRun> glyphsHash; QList<QFontEngine *> keys = glyphLayoutHash.uniqueKeys(); for (int i=0; i<keys.size(); ++i) { @@ -2223,14 +2223,14 @@ QList<QGlyphs> QTextLine::glyphs(int from, int length) const positions.append(positionsArray.at(i).toPointF() + pos); } - QGlyphs glyphIndexes; + QGlyphRun glyphIndexes; glyphIndexes.setGlyphIndexes(glyphs); glyphIndexes.setPositions(positions); glyphIndexes.setOverline(flags.testFlag(QTextItem::Overline)); glyphIndexes.setUnderline(flags.testFlag(QTextItem::Underline)); glyphIndexes.setStrikeOut(flags.testFlag(QTextItem::StrikeOut)); - glyphIndexes.setFont(font); + glyphIndexes.setRawFont(font); QPair<QFontEngine *, int> key(fontEngine, int(flags)); if (!glyphsHash.contains(key)) diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h index cd34265..caff299 100644 --- a/src/gui/text/qtextlayout.h +++ b/src/gui/text/qtextlayout.h @@ -49,7 +49,7 @@ #include <QtCore/qobject.h> #include <QtGui/qevent.h> #include <QtGui/qtextformat.h> -#include <QtGui/qglyphs.h> +#include <QtGui/qglyphrun.h> #include <QtGui/qtextcursor.h> QT_BEGIN_HEADER @@ -137,8 +137,8 @@ public: void setCacheEnabled(bool enable); bool cacheEnabled() const; - void setCursorMoveStyle(QTextCursor::MoveStyle style); - QTextCursor::MoveStyle cursorMoveStyle() const; + void setCursorMoveStyle(Qt::CursorMoveStyle style); + Qt::CursorMoveStyle cursorMoveStyle() const; void beginLayout(); void endLayout(); @@ -174,7 +174,7 @@ public: qreal maximumWidth() const; #if !defined(QT_NO_RAWFONT) - QList<QGlyphs> glyphs() const; + QList<QGlyphRun> glyphRuns() const; #endif QTextEngine *engine() const { return d; } @@ -249,7 +249,7 @@ private: void layout_helper(int numGlyphs); #if !defined(QT_NO_RAWFONT) - QList<QGlyphs> glyphs(int from, int length) const; + QList<QGlyphRun> glyphs(int from, int length) const; #endif friend class QTextLayout; diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index b5f5448..c3f37d8 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -891,11 +891,6 @@ QTextBlockUserData::~QTextBlockUserData() Returns true if this text block is valid; otherwise returns false. */ -bool QTextBlock::isValid() const -{ - return p != 0 && p->blockMap().isValid(n); -} - /*! \fn QTextBlock &QTextBlock::operator=(const QTextBlock &other) @@ -1493,7 +1488,7 @@ QTextBlock::iterator QTextBlock::end() const */ QTextBlock QTextBlock::next() const { - if (!isValid()) + if (!isValid() || !p->blockMap().isValid(n)) return QTextBlock(); return QTextBlock(p, p->blockMap().next(n)); @@ -1664,25 +1659,25 @@ QTextBlock::iterator &QTextBlock::iterator::operator--() Returns the glyphs of this text fragment. The positions of the glyphs are relative to the position of the QTextBlock's layout. - \sa QGlyphs, QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphs() + \sa QGlyphRun, QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphRun() */ #if !defined(QT_NO_RAWFONT) -QList<QGlyphs> QTextFragment::glyphs() const +QList<QGlyphRun> QTextFragment::glyphRuns() const { if (!p || !n) - return QList<QGlyphs>(); + return QList<QGlyphRun>(); int pos = position(); int len = length(); if (len == 0) - return QList<QGlyphs>(); + return QList<QGlyphRun>(); int blockNode = p->blockMap().findNode(pos); const QTextBlockData *blockData = p->blockMap().fragment(blockNode); QTextLayout *layout = blockData->layout; - QList<QGlyphs> ret; + QList<QGlyphRun> ret; for (int i=0; i<layout->lineCount(); ++i) { QTextLine textLine = layout->lineAt(i); ret += textLine.glyphs(pos, len); diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h index f9d877a..dae1f92 100644 --- a/src/gui/text/qtextobject.h +++ b/src/gui/text/qtextobject.h @@ -44,7 +44,7 @@ #include <QtCore/qobject.h> #include <QtGui/qtextformat.h> -#include <QtGui/qglyphs.h> +#include <QtGui/qglyphrun.h> QT_BEGIN_HEADER @@ -205,7 +205,7 @@ public: inline QTextBlock(const QTextBlock &o) : p(o.p), n(o.n) {} inline QTextBlock &operator=(const QTextBlock &o) { p = o.p; n = o.n; return *this; } - bool isValid() const; + inline bool isValid() const { return p != 0 && n != 0; } inline bool operator==(const QTextBlock &o) const { return p == o.p && n == o.n; } inline bool operator!=(const QTextBlock &o) const { return p != o.p || n != o.n; } @@ -317,7 +317,7 @@ public: QString text() const; #if !defined(QT_NO_RAWFONT) - QList<QGlyphs> glyphs() const; + QList<QGlyphRun> glyphRuns() const; #endif private: diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index e5d57d0..b6cdc52 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -40,10 +40,10 @@ HEADERS += \ text/qtextodfwriter_p.h \ text/qstatictext_p.h \ text/qstatictext.h \ - text/qglyphs.h \ - text/qglyphs_p.h \ text/qrawfont.h \ - text/qrawfont_p.h + text/qrawfont_p.h \ + text/qglyphrun.h \ + text/qglyphrun_p.h SOURCES += \ text/qfont.cpp \ @@ -74,8 +74,8 @@ SOURCES += \ text/qzip.cpp \ text/qtextodfwriter.cpp \ text/qstatictext.cpp \ - text/qglyphs.cpp \ - text/qrawfont.cpp + text/qrawfont.cpp \ + text/qglyphrun.cpp win32 { SOURCES += \ diff --git a/src/gui/util/qflickgesture.cpp b/src/gui/util/qflickgesture.cpp deleted file mode 100644 index 07eca6c..0000000 --- a/src/gui/util/qflickgesture.cpp +++ /dev/null @@ -1,715 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgesture.h" -#include "qapplication.h" -#include "qevent.h" -#include "qwidget.h" -#include "qgraphicsitem.h" -#include "qgraphicsscene.h" -#include "qgraphicssceneevent.h" -#include "qgraphicsview.h" -#include "qscroller.h" -#include "private/qevent_p.h" -#include "private/qflickgesture_p.h" -#include "qdebug.h" - -#ifndef QT_NO_GESTURES - -QT_BEGIN_NAMESPACE - -//#define QFLICKGESTURE_DEBUG - -#ifdef QFLICKGESTURE_DEBUG -# define qFGDebug qDebug -#else -# define qFGDebug while (false) qDebug -#endif - -extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); - -static QMouseEvent *copyMouseEvent(QEvent *e) -{ - switch (e->type()) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseMove: { - QMouseEvent *me = static_cast<QMouseEvent *>(e); - return new QMouseEvent(me->type(), QPoint(0, 0), me->globalPos(), me->button(), me->buttons(), me->modifiers()); - } -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMousePress: - case QEvent::GraphicsSceneMouseRelease: - case QEvent::GraphicsSceneMouseMove: { - QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent *>(e); -#if 1 - QEvent::Type met = me->type() == QEvent::GraphicsSceneMousePress ? QEvent::MouseButtonPress : - (me->type() == QEvent::GraphicsSceneMouseRelease ? QEvent::MouseButtonRelease : QEvent::MouseMove); - return new QMouseEvent(met, QPoint(0, 0), me->screenPos(), me->button(), me->buttons(), me->modifiers()); -#else - QGraphicsSceneMouseEvent *copy = new QGraphicsSceneMouseEvent(me->type()); - copy->setPos(me->pos()); - copy->setScenePos(me->scenePos()); - copy->setScreenPos(me->screenPos()); - for (int i = 0x1; i <= 0x10; i <<= 1) { - Qt::MouseButton button = Qt::MouseButton(i); - copy->setButtonDownPos(button, me->buttonDownPos(button)); - copy->setButtonDownScenePos(button, me->buttonDownScenePos(button)); - copy->setButtonDownScreenPos(button, me->buttonDownScreenPos(button)); - } - copy->setLastPos(me->lastPos()); - copy->setLastScenePos(me->lastScenePos()); - copy->setLastScreenPos(me->lastScreenPos()); - copy->setButtons(me->buttons()); - copy->setButton(me->button()); - copy->setModifiers(me->modifiers()); - return copy; -#endif - } -#endif // QT_NO_GRAPHICSVIEW - default: - return 0; - } -} - -class PressDelayHandler : public QObject -{ -private: - PressDelayHandler(QObject *parent = 0) - : QObject(parent) - , pressDelayTimer(0) - , sendingEvent(false) - , mouseButton(Qt::NoButton) - , mouseTarget(0) - { } - - static PressDelayHandler *inst; - -public: - enum { - UngrabMouseBefore = 1, - RegrabMouseAfterwards = 2 - }; - - static PressDelayHandler *instance() - { - static PressDelayHandler *inst = 0; - if (!inst) - inst = new PressDelayHandler(QCoreApplication::instance()); - return inst; - } - - bool shouldEventBeIgnored(QEvent *) const - { - return sendingEvent; - } - - bool isDelaying() const - { - return !pressDelayEvent.isNull(); - } - - void pressed(QEvent *e, int delay) - { - if (!pressDelayEvent) { - pressDelayEvent.reset(copyMouseEvent(e)); - pressDelayTimer = startTimer(delay); - mouseTarget = QApplication::widgetAt(pressDelayEvent->globalPos()); - mouseButton = pressDelayEvent->button(); - qFGDebug() << "QFG: consuming/delaying mouse press"; - } else { - qFGDebug() << "QFG: NOT consuming/delaying mouse press"; - } - e->setAccepted(true); - } - - bool released(QEvent *e, bool scrollerWasActive, bool scrollerIsActive) - { - // consume this event if the scroller was or is active - bool result = scrollerWasActive || scrollerIsActive; - - // stop the timer - if (pressDelayTimer) { - killTimer(pressDelayTimer); - pressDelayTimer = 0; - } - // we still haven't even sent the press, so do it now - if (pressDelayEvent && mouseTarget && !scrollerIsActive) { - QScopedPointer<QMouseEvent> releaseEvent(copyMouseEvent(e)); - - qFGDebug() << "QFG: re-sending mouse press (due to release) for " << mouseTarget; - sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore); - - qFGDebug() << "QFG: faking mouse release (due to release) for " << mouseTarget; - sendMouseEvent(releaseEvent.data()); - - result = true; // consume this event - } else if (mouseTarget && scrollerIsActive) { - // we grabbed the mouse expicitly when the scroller became active, so undo that now - sendMouseEvent(0, UngrabMouseBefore); - } - pressDelayEvent.reset(0); - mouseTarget = 0; - return result; - } - - void scrollerWasIntercepted() - { - qFGDebug() << "QFG: deleting delayed mouse press, since scroller was only intercepted"; - if (pressDelayEvent) { - // we still haven't even sent the press, so just throw it away now - if (pressDelayTimer) { - killTimer(pressDelayTimer); - pressDelayTimer = 0; - } - pressDelayEvent.reset(0); - } - mouseTarget = 0; - } - - void scrollerBecameActive() - { - if (pressDelayEvent) { - // we still haven't even sent the press, so just throw it away now - qFGDebug() << "QFG: deleting delayed mouse press, since scroller is active now"; - if (pressDelayTimer) { - killTimer(pressDelayTimer); - pressDelayTimer = 0; - } - pressDelayEvent.reset(0); - mouseTarget = 0; - } else if (mouseTarget) { - // we did send a press, so we need to fake a release now - - // release all pressed mouse buttons - /* Qt::MouseButtons mouseButtons = QApplication::mouseButtons(); - for (int i = 0; i < 32; ++i) { - if (mouseButtons & (1 << i)) { - Qt::MouseButton b = static_cast<Qt::MouseButton>(1 << i); - mouseButtons &= ~b; - QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX); - - qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget; - QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway, - b, mouseButtons, QApplication::keyboardModifiers()); - sendMouseEvent(&re); - } - }*/ - - QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX); - - qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget; - QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway, - mouseButton, QApplication::mouseButtons() & ~mouseButton, - QApplication::keyboardModifiers()); - sendMouseEvent(&re, RegrabMouseAfterwards); - // don't clear the mouseTarget just yet, since we need to explicitly ungrab the mouse on release! - } - } - -protected: - void timerEvent(QTimerEvent *e) - { - if (e->timerId() == pressDelayTimer) { - if (pressDelayEvent && mouseTarget) { - qFGDebug() << "QFG: timer event: re-sending mouse press to " << mouseTarget; - sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore); - } - pressDelayEvent.reset(0); - - if (pressDelayTimer) { - killTimer(pressDelayTimer); - pressDelayTimer = 0; - } - } - } - - void sendMouseEvent(QMouseEvent *me, int flags = 0) - { - if (mouseTarget) { - sendingEvent = true; - -#ifndef QT_NO_GRAPHICSVIEW - QGraphicsItem *grabber = 0; - if (mouseTarget->parentWidget()) { - if (QGraphicsView *gv = qobject_cast<QGraphicsView *>(mouseTarget->parentWidget())) { - if (gv->scene()) - grabber = gv->scene()->mouseGrabberItem(); - } - } - - if (grabber && (flags & UngrabMouseBefore)) { - // GraphicsView Mouse Handling Workaround #1: - // we need to ungrab the mouse before re-sending the press, - // since the scene had already set the mouse grabber to the - // original (and consumed) event's receiver - qFGDebug() << "QFG: ungrabbing" << grabber; - grabber->ungrabMouse(); - } -#endif // QT_NO_GRAPHICSVIEW - - if (me) { - QMouseEvent copy(me->type(), mouseTarget->mapFromGlobal(me->globalPos()), me->globalPos(), me->button(), me->buttons(), me->modifiers()); - qt_sendSpontaneousEvent(mouseTarget, ©); - } - -#ifndef QT_NO_GRAPHICSVIEW - if (grabber && (flags & RegrabMouseAfterwards)) { - // GraphicsView Mouse Handling Workaround #2: - // we need to re-grab the mouse after sending a faked mouse - // release, since we still need the mouse moves for the gesture - // (the scene will clear the item's mouse grabber status on - // release). - qFGDebug() << "QFG: re-grabbing" << grabber; - grabber->grabMouse(); - } -#endif - sendingEvent = false; - } - } - - -private: - int pressDelayTimer; - QScopedPointer<QMouseEvent> pressDelayEvent; - bool sendingEvent; - Qt::MouseButton mouseButton; - QPointer<QWidget> mouseTarget; -}; - - -/*! - \internal - \class QFlickGesture - \since 4.8 - \brief The QFlickGesture class describes a flicking gesture made by the user. - \ingroup gestures - The QFlickGesture is more complex than the QPanGesture that uses QScroller and QScrollerProperties - to decide if it is triggered. - This gesture is reacting on touch event as compared to the QMouseFlickGesture. - - \sa {Gestures Programming}, QScroller, QScrollerProperties, QMouseFlickGesture -*/ - -/*! - \internal -*/ -QFlickGesture::QFlickGesture(QObject *receiver, Qt::MouseButton button, QObject *parent) - : QGesture(*new QFlickGesturePrivate, parent) -{ - d_func()->q_ptr = this; - d_func()->receiver = receiver; - d_func()->receiverScroller = (receiver && QScroller::hasScroller(receiver)) ? QScroller::scroller(receiver) : 0; - d_func()->button = button; -} - -QFlickGesture::~QFlickGesture() -{ } - -QFlickGesturePrivate::QFlickGesturePrivate() - : receiverScroller(0), button(Qt::NoButton), macIgnoreWheel(false) -{ } - - -// -// QFlickGestureRecognizer -// - - -QFlickGestureRecognizer::QFlickGestureRecognizer(Qt::MouseButton button) -{ - this->button = button; -} - -/*! \reimp - */ -QGesture *QFlickGestureRecognizer::create(QObject *target) -{ -#ifndef QT_NO_GRAPHICSVIEW - QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target); - if (go && button == Qt::NoButton) { - go->setAcceptTouchEvents(true); - } -#endif - return new QFlickGesture(target, button); -} - -/*! \internal - The recognize function detects a touch event suitable to start the attached QScroller. - The QFlickGesture will be triggered as soon as the scroller is no longer in the state - QScroller::Inactive or QScroller::Pressed. It will be finished or canceled - at the next QEvent::TouchEnd. - Note that the QScroller might continue scrolling (kinetically) at this point. - */ -QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state, - QObject *watched, - QEvent *event) -{ - Q_UNUSED(watched); - - static QElapsedTimer monotonicTimer; - if (!monotonicTimer.isValid()) - monotonicTimer.start(); - - QFlickGesture *q = static_cast<QFlickGesture *>(state); - QFlickGesturePrivate *d = q->d_func(); - - QScroller *scroller = d->receiverScroller; - if (!scroller) - return Ignore; // nothing to do without a scroller? - - QWidget *receiverWidget = qobject_cast<QWidget *>(d->receiver); -#ifndef QT_NO_GRAPHICSVIEW - QGraphicsObject *receiverGraphicsObject = qobject_cast<QGraphicsObject *>(d->receiver); -#endif - - // this is only set for events that we inject into the event loop via sendEvent() - if (PressDelayHandler::instance()->shouldEventBeIgnored(event)) { - //qFGDebug() << state << "QFG: ignored event: " << event->type(); - return Ignore; - } - - const QMouseEvent *me = 0; -#ifndef QT_NO_GRAPHICSVIEW - const QGraphicsSceneMouseEvent *gsme = 0; -#endif - const QTouchEvent *te = 0; - QPoint globalPos; - - // qFGDebug() << "FlickGesture "<<state<<"watched:"<<watched<<"receiver"<<d->receiver<<"event"<<event->type()<<"button"<<button; - - switch (event->type()) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseMove: - if (!receiverWidget) - return Ignore; - if (button != Qt::NoButton) { - me = static_cast<const QMouseEvent *>(event); - globalPos = me->globalPos(); - } - break; -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMousePress: - case QEvent::GraphicsSceneMouseRelease: - case QEvent::GraphicsSceneMouseMove: - if (!receiverGraphicsObject) - return Ignore; - if (button != Qt::NoButton) { - gsme = static_cast<const QGraphicsSceneMouseEvent *>(event); - globalPos = gsme->screenPos(); - } - break; -#endif - case QEvent::TouchBegin: - case QEvent::TouchEnd: - case QEvent::TouchUpdate: - if (button == Qt::NoButton) { - te = static_cast<const QTouchEvent *>(event); - if (!te->touchPoints().isEmpty()) - globalPos = te->touchPoints().at(0).screenPos().toPoint(); - } - break; - -#if defined(Q_WS_MAC) - // the only way to distinguish between real mouse wheels and wheel - // events generated by the native 2 finger swipe gesture is to listen - // for these events (according to Apple's Cocoa Event-Handling Guide) - - case QEvent::NativeGesture: { - QNativeGestureEvent *nge = static_cast<QNativeGestureEvent *>(event); - if (nge->gestureType == QNativeGestureEvent::GestureBegin) - d->macIgnoreWheel = true; - else if (nge->gestureType == QNativeGestureEvent::GestureEnd) - d->macIgnoreWheel = false; - break; - } -#endif - - // consume all wheel events if the scroller is active - case QEvent::Wheel: - if (d->macIgnoreWheel || (scroller->state() != QScroller::Inactive)) - return Ignore | ConsumeEventHint; - break; - - // consume all dbl click events if the scroller is active - case QEvent::MouseButtonDblClick: - if (scroller->state() != QScroller::Inactive) - return Ignore | ConsumeEventHint; - break; - - default: - break; - } - - if (!me -#ifndef QT_NO_GRAPHICSVIEW - && !gsme -#endif - && !te) // Neither mouse nor touch - return Ignore; - - // get the current pointer position in local coordinates. - QPointF point; - QScroller::Input inputType = (QScroller::Input) 0; - - switch (event->type()) { - case QEvent::MouseButtonPress: - if (me && me->button() == button && me->buttons() == button) { - point = me->globalPos(); - inputType = QScroller::InputPress; - } else if (me) { - scroller->stop(); - return CancelGesture; - } - break; - case QEvent::MouseButtonRelease: - if (me && me->button() == button) { - point = me->globalPos(); - inputType = QScroller::InputRelease; - } - break; - case QEvent::MouseMove: -#ifdef Q_OS_SYMBIAN - // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix - // relies on the windowing system to report the current buttons state. - if (me && (me->buttons() == button || !me->buttons())) { -#else - if (me && me->buttons() == button) { -#endif - point = me->globalPos(); - inputType = QScroller::InputMove; - } - break; - -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMousePress: - if (gsme && gsme->button() == button && gsme->buttons() == button) { - point = gsme->scenePos(); - inputType = QScroller::InputPress; - } else if (gsme) { - scroller->stop(); - return CancelGesture; - } - break; - case QEvent::GraphicsSceneMouseRelease: - if (gsme && gsme->button() == button) { - point = gsme->scenePos(); - inputType = QScroller::InputRelease; - } - break; - case QEvent::GraphicsSceneMouseMove: -#ifdef Q_OS_SYMBIAN - // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix - // relies on the windowing system to report the current buttons state. - if (gsme && (gsme->buttons() == button || !me->buttons())) { -#else - if (gsme && gsme->buttons() == button) { -#endif - point = gsme->scenePos(); - inputType = QScroller::InputMove; - } - break; -#endif - - case QEvent::TouchBegin: - inputType = QScroller::InputPress; - // fall through - case QEvent::TouchEnd: - if (!inputType) - inputType = QScroller::InputRelease; - // fallthrough - case QEvent::TouchUpdate: - if (!inputType) - inputType = QScroller::InputMove; - - if (te->deviceType() == QTouchEvent::TouchPad) { - if (te->touchPoints().count() != 2) // 2 fingers on pad - return Ignore; - - point = te->touchPoints().at(0).startScenePos() + - ((te->touchPoints().at(0).scenePos() - te->touchPoints().at(0).startScenePos()) + - (te->touchPoints().at(1).scenePos() - te->touchPoints().at(1).startScenePos())) / 2; - } else { // TouchScreen - if (te->touchPoints().count() != 1) // 1 finger on screen - return Ignore; - - point = te->touchPoints().at(0).scenePos(); - } - break; - - default: - break; - } - - // Check for an active scroller at globalPos - if (inputType == QScroller::InputPress) { - foreach (QScroller *as, QScroller::activeScrollers()) { - if (as != scroller) { - QRegion scrollerRegion; - - if (QWidget *w = qobject_cast<QWidget *>(as->target())) { - scrollerRegion = QRect(w->mapToGlobal(QPoint(0, 0)), w->size()); -#ifndef QT_NO_GRAPHICSVIEW - } else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(as->target())) { - if (go->scene() && !go->scene()->views().isEmpty()) { - foreach (QGraphicsView *gv, go->scene()->views()) - scrollerRegion |= gv->mapFromScene(go->mapToScene(go->boundingRect())) - .translated(gv->mapToGlobal(QPoint(0, 0))); - } -#endif - } - // active scrollers always have priority - if (scrollerRegion.contains(globalPos)) - return Ignore; - } - } - } - - bool scrollerWasDragging = (scroller->state() == QScroller::Dragging); - bool scrollerWasScrolling = (scroller->state() == QScroller::Scrolling); - - if (inputType) { - if (QWidget *w = qobject_cast<QWidget *>(d->receiver)) - point = w->mapFromGlobal(point.toPoint()); -#ifndef QT_NO_GRAPHICSVIEW - else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(d->receiver)) - point = go->mapFromScene(point); -#endif - - // inform the scroller about the new event - scroller->handleInput(inputType, point, monotonicTimer.elapsed()); - } - - // depending on the scroller state return the gesture state - Result result(0); - bool scrollerIsActive = (scroller->state() == QScroller::Dragging || - scroller->state() == QScroller::Scrolling); - - // Consume all mouse events while dragging or scrolling to avoid nasty - // side effects with Qt's standard widgets. - if ((me -#ifndef QT_NO_GRAPHICSVIEW - || gsme -#endif - ) && scrollerIsActive) - result |= ConsumeEventHint; - - // The only problem with this approach is that we consume the - // MouseRelease when we start the scrolling with a flick gesture, so we - // have to fake a MouseRelease "somewhere" to not mess with the internal - // states of Qt's widgets (a QPushButton would stay in 'pressed' state - // forever, if it doesn't receive a MouseRelease). - if (me -#ifndef QT_NO_GRAPHICSVIEW - || gsme -#endif - ) { - if (!scrollerWasDragging && !scrollerWasScrolling && scrollerIsActive) - PressDelayHandler::instance()->scrollerBecameActive(); - else if (scrollerWasScrolling && (scroller->state() == QScroller::Dragging || scroller->state() == QScroller::Inactive)) - PressDelayHandler::instance()->scrollerWasIntercepted(); - } - - if (!inputType) { - result |= Ignore; - } else { - switch (event->type()) { - case QEvent::MouseButtonPress: -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMousePress: -#endif - if (scroller->state() == QScroller::Pressed) { - int pressDelay = int(1000 * scroller->scrollerProperties().scrollMetric(QScrollerProperties::MousePressEventDelay).toReal()); - if (pressDelay > 0) { - result |= ConsumeEventHint; - - PressDelayHandler::instance()->pressed(event, pressDelay); - event->accept(); - } - } - // fall through - case QEvent::TouchBegin: - q->setHotSpot(globalPos); - result |= scrollerIsActive ? TriggerGesture : MayBeGesture; - break; - - case QEvent::MouseMove: -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMouseMove: -#endif - if (PressDelayHandler::instance()->isDelaying()) - result |= ConsumeEventHint; - // fall through - case QEvent::TouchUpdate: - result |= scrollerIsActive ? TriggerGesture : Ignore; - break; - -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMouseRelease: -#endif - case QEvent::MouseButtonRelease: - if (PressDelayHandler::instance()->released(event, scrollerWasDragging || scrollerWasScrolling, scrollerIsActive)) - result |= ConsumeEventHint; - // fall through - case QEvent::TouchEnd: - result |= scrollerIsActive ? FinishGesture : CancelGesture; - break; - - default: - result |= Ignore; - break; - } - } - return result; -} - - -/*! \reimp - */ -void QFlickGestureRecognizer::reset(QGesture *state) -{ - QGestureRecognizer::reset(state); -} - -QT_END_NAMESPACE - -#endif // QT_NO_GESTURES diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp deleted file mode 100644 index 33ceb6d..0000000 --- a/src/gui/util/qscroller.cpp +++ /dev/null @@ -1,2056 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qevent.h" -#include "qwidget.h" -#include "qscroller.h" -#include "private/qflickgesture_p.h" -#include "private/qscroller_p.h" -#include "qscrollerproperties.h" -#include "private/qscrollerproperties_p.h" -#include "qnumeric.h" -#include "math.h" - -#include <QTime> -#include <QElapsedTimer> -#include <QMap> -#include <QApplication> -#include <QAbstractScrollArea> -#include <QGraphicsObject> -#include <QGraphicsScene> -#include <QGraphicsView> -#include <QDesktopWidget> -#include <QtCore/qmath.h> -#include <QtGui/qevent.h> -#include <qnumeric.h> - -#include <QtDebug> - -#if defined(Q_WS_X11) -# include "private/qt_x11_p.h" -#endif - - -QT_BEGIN_NAMESPACE - -bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); - -//#define QSCROLLER_DEBUG - -#ifdef QSCROLLER_DEBUG -# define qScrollerDebug qDebug -#else -# define qScrollerDebug while (false) qDebug -#endif - -QDebug &operator<<(QDebug &dbg, const QScrollerPrivate::ScrollSegment &s) -{ - dbg << "\n Time: start:" << s.startTime << " duration:" << s.deltaTime << " stop progress:" << s.stopProgress; - dbg << "\n Pos: start:" << s.startPos << " delta:" << s.deltaPos << " stop:" << s.stopPos; - dbg << "\n Curve: type:" << s.curve.type() << "\n"; - return dbg; -} - - -// a few helper operators to make the code below a lot more readable: -// otherwise a lot of ifs would have to be multi-line to check both the x -// and y coordinate separately. - -// returns true only if the abs. value of BOTH x and y are <= f -inline bool operator<=(const QPointF &p, qreal f) -{ - return (qAbs(p.x()) <= f) && (qAbs(p.y()) <= f); -} - -// returns true only if the abs. value of BOTH x and y are < f -inline bool operator<(const QPointF &p, qreal f) -{ - return (qAbs(p.x()) < f) && (qAbs(p.y()) < f); -} - -// returns true if the abs. value of EITHER x or y are >= f -inline bool operator>=(const QPointF &p, qreal f) -{ - return (qAbs(p.x()) >= f) || (qAbs(p.y()) >= f); -} - -// returns true if the abs. value of EITHER x or y are > f -inline bool operator>(const QPointF &p, qreal f) -{ - return (qAbs(p.x()) > f) || (qAbs(p.y()) > f); -} - -// returns a new point with both coordinates having the abs. value of the original one -inline QPointF qAbs(const QPointF &p) -{ - return QPointF(qAbs(p.x()), qAbs(p.y())); -} - -// returns a new point with all components of p1 multiplied by the corresponding components of p2 -inline QPointF operator*(const QPointF &p1, const QPointF &p2) -{ - return QPointF(p1.x() * p2.x(), p1.y() * p2.y()); -} - -// returns a new point with all components of p1 divided by the corresponding components of p2 -inline QPointF operator/(const QPointF &p1, const QPointF &p2) -{ - return QPointF(p1.x() / p2.x(), p1.y() / p2.y()); -} - -inline QPointF clampToRect(const QPointF &p, const QRectF &rect) -{ - qreal x = qBound(rect.left(), p.x(), rect.right()); - qreal y = qBound(rect.top(), p.y(), rect.bottom()); - return QPointF(x, y); -} - -// returns -1, 0 or +1 according to r being <0, ==0 or >0 -inline int qSign(qreal r) -{ - return (r < 0) ? -1 : ((r > 0) ? 1 : 0); -} - -// this version is not mathematically exact, but it just works for every -// easing curve type (even custom ones) - -static qreal differentialForProgress(const QEasingCurve &curve, qreal pos) -{ - const qreal dx = 0.01; - qreal left = (pos < qreal(0.5)) ? pos : pos - qreal(dx); - qreal right = (pos >= qreal(0.5)) ? pos : pos + qreal(dx); - qreal d = (curve.valueForProgress(right) - curve.valueForProgress(left)) / qreal(dx); - - //qScrollerDebug() << "differentialForProgress(type: " << curve.type() << ", pos: " << pos << ") = " << d; - - return d; -} - -// this version is not mathematically exact, but it just works for every -// easing curve type (even custom ones) - -static qreal progressForValue(const QEasingCurve &curve, qreal value) -{ - if (curve.type() >= QEasingCurve::InElastic && - curve.type() < QEasingCurve::Custom) { - qWarning("progressForValue(): QEasingCurves of type %d do not have an inverse, since they are not injective.", curve.type()); - return value; - } - if (value < qreal(0) || value > qreal(1)) - return value; - - qreal progress = value, left(0), right(1); - for (int iterations = 6; iterations; --iterations) { - qreal v = curve.valueForProgress(progress); - if (v < value) - left = progress; - else if (v > value) - right = progress; - else - break; - progress = (left + right) / qreal(2); - } - return progress; -} - - -#ifndef QT_NO_ANIMATION -class QScrollTimer : public QAbstractAnimation -{ -public: - QScrollTimer(QScrollerPrivate *_d) - : d(_d), ignoreUpdate(false), skip(0) - { } - - int duration() const - { - return -1; - } - - void start() - { - // QAbstractAnimation::start() will immediately call - // updateCurrentTime(), but our state is not set correctly yet - ignoreUpdate = true; - QAbstractAnimation::start(); - ignoreUpdate = false; - skip = 0; - } - -protected: - void updateCurrentTime(int /*currentTime*/) - { - if (!ignoreUpdate) { - if (++skip >= d->frameRateSkip()) { - skip = 0; - d->timerTick(); - } - } - } - -private: - QScrollerPrivate *d; - bool ignoreUpdate; - int skip; -}; -#endif // QT_NO_ANIMATION - -/*! - \class QScroller - \brief The QScroller class enables kinetic scrolling for any scrolling widget or graphics item. - \since 4.8 - - With kinetic scrolling, the user can push the widget in a given - direction and it will continue to scroll in this direction until it is - stopped either by the user or by friction. Aspects of inertia, friction - and other physical concepts can be changed in order to fine-tune an - intuitive user experience. - - The QScroller object is the object that stores the current position and - scrolling speed and takes care of updates. - QScroller can be triggered by a flick gesture - - \code - QWidget *w = ...; - QScroller::grabGesture(w, QScroller::LeftMouseButtonGesture); - \endcode - - or directly like this: - - \code - QWidget *w = ...; - QScroller *scroller = QScroller::scroller(w); - scroller->scrollTo(QPointF(100, 100)); - \endcode - - The scrolled QObjects receive a QScrollPrepareEvent whenever the scroller needs to - update its geometry information and a QScrollEvent whenever the content of the object should - actually be scrolled. - - The scroller uses the global QAbstractAnimation timer to generate its QScrollEvents. This - can be changed with QScrollerProperties::FrameRate on a per-QScroller basis. - - Several examples in the \c scroller examples directory show how QScroller, - QScrollEvent and the scroller gesture can be used. - - Even though this kinetic scroller has a large number of settings available via - QScrollerProperties, we recommend that you leave them all at their default, platform optimized - values. Before changing them you can experiment with the \c plot example in - the \c scroller examples directory. - - \sa QScrollEvent, QScrollPrepareEvent, QScrollerProperties -*/ - -typedef QMap<QObject *, QScroller *> ScrollerHash; -typedef QSet<QScroller *> ScrollerSet; - -Q_GLOBAL_STATIC(ScrollerHash, qt_allScrollers) -Q_GLOBAL_STATIC(ScrollerSet, qt_activeScrollers) - -/*! - Returns \c true if a QScroller object was already created for \a target; \c false otherwise. - - \sa scroller() -*/ -bool QScroller::hasScroller(QObject *target) -{ - return (qt_allScrollers()->value(target)); -} - -/*! - Returns the scroller for the given \a target. - As long as the object exists this function will always return the same QScroller instance. - If no QScroller exists for the \a target, one will implicitly be created. - At no point more than one QScroller will be active on an object. - - \sa hasScroller(), target() -*/ -QScroller *QScroller::scroller(QObject *target) -{ - if (!target) { - qWarning("QScroller::scroller() was called with a null target."); - return 0; - } - - if (qt_allScrollers()->contains(target)) - return qt_allScrollers()->value(target); - - QScroller *s = new QScroller(target); - qt_allScrollers()->insert(target, s); - return s; -} - -/*! - \overload - This is the const version of scroller(). -*/ -const QScroller *QScroller::scroller(const QObject *target) -{ - return scroller(const_cast<QObject*>(target)); -} - -/*! - Returns an application wide list of currently active QScroller objects. - Active QScroller objects are in a state() that is not QScroller::Inactive. - This function is useful when writing your own gesture recognizer. -*/ -QList<QScroller *> QScroller::activeScrollers() -{ - return qt_activeScrollers()->toList(); -} - -/*! - Returns the target object of this scroller. - \sa hasScroller(), scroller() - */ -QObject *QScroller::target() const -{ - Q_D(const QScroller); - return d->target; -} - -/*! - \fn QScroller::scrollerPropertiesChanged(const QScrollerProperties &newProperties); - - QScroller emits this signal whenever its scroller properties change. - \a newProperties are the new scroller properties. - - \sa scrollerProperties -*/ - - -/*! \property QScroller::scrollerProperties - \brief The scroller properties of this scroller. - The properties are used by the QScroller to determine its scrolling behavior. -*/ -QScrollerProperties QScroller::scrollerProperties() const -{ - Q_D(const QScroller); - return d->properties; -} - -void QScroller::setScrollerProperties(const QScrollerProperties &sp) -{ - Q_D(QScroller); - if (d->properties != sp) { - d->properties = sp; - emit scrollerPropertiesChanged(sp); - - // we need to force the recalculation here, since the overshootPolicy may have changed and - // existing segments may include an overshoot animation. - d->recalcScrollingSegments(true); - } -} - -#ifndef QT_NO_GESTURES - -/*! - Registers a custom scroll gesture recognizer, grabs it for the \a - target and returns the resulting gesture type. If \a scrollGestureType is - set to TouchGesture the gesture triggers on touch events. If it is set to - one of LeftMouseButtonGesture, RightMouseButtonGesture or - MiddleMouseButtonGesture it triggers on mouse events of the - corresponding button. - - Only one scroll gesture can be active on a single object at the same - time. If you call this function twice on the same object, it will - ungrab the existing gesture before grabbing the new one. - - \note To avoid unwanted side-effects, mouse events are consumed while - the gesture is triggered. Since the initial mouse press event is - not consumed, the gesture sends a fake mouse release event - at the global position \c{(INT_MIN, INT_MIN)}. This ensures that - internal states of the widget that received the original mouse press - are consistent. - - \sa ungrabGesture, grabbedGesture -*/ -Qt::GestureType QScroller::grabGesture(QObject *target, ScrollerGestureType scrollGestureType) -{ - // ensure that a scroller for target is created - QScroller *s = scroller(target); - if (!s) - return Qt::GestureType(0); - - QScrollerPrivate *sp = s->d_ptr; - if (sp->recognizer) - ungrabGesture(target); // ungrab the old gesture - - Qt::MouseButton button; - switch (scrollGestureType) { - case LeftMouseButtonGesture : button = Qt::LeftButton; break; - case RightMouseButtonGesture : button = Qt::RightButton; break; - case MiddleMouseButtonGesture: button = Qt::MiddleButton; break; - default : - case TouchGesture : button = Qt::NoButton; break; // NoButton == Touch - } - - sp->recognizer = new QFlickGestureRecognizer(button); - sp->recognizerType = QGestureRecognizer::registerRecognizer(sp->recognizer); - - if (target->isWidgetType()) { - QWidget *widget = static_cast<QWidget *>(target); - widget->grabGesture(sp->recognizerType); - if (scrollGestureType == TouchGesture) - widget->setAttribute(Qt::WA_AcceptTouchEvents); -#ifndef QT_NO_GRAPHICSVIEW - } else if (QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target)) { - if (scrollGestureType == TouchGesture) - go->setAcceptTouchEvents(true); - go->grabGesture(sp->recognizerType); -#endif // QT_NO_GRAPHICSVIEW - } - return sp->recognizerType; -} - -/*! - Returns the gesture type currently grabbed for the \a target or 0 if no - gesture is grabbed. - - \sa grabGesture, ungrabGesture -*/ -Qt::GestureType QScroller::grabbedGesture(QObject *target) -{ - QScroller *s = scroller(target); - if (s && s->d_ptr) - return s->d_ptr->recognizerType; - else - return Qt::GestureType(0); -} - -/*! - Ungrabs the gesture for the \a target. - Does nothing if no gesture is grabbed. - - \sa grabGesture, grabbedGesture -*/ -void QScroller::ungrabGesture(QObject *target) -{ - QScroller *s = scroller(target); - if (!s) - return; - - QScrollerPrivate *sp = s->d_ptr; - if (!sp->recognizer) - return; // nothing to do - - if (target->isWidgetType()) { - QWidget *widget = static_cast<QWidget *>(target); - widget->ungrabGesture(sp->recognizerType); -#ifndef QT_NO_GRAPHICSVIEW - } else if (QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target)) { - go->ungrabGesture(sp->recognizerType); -#endif - } - - QGestureRecognizer::unregisterRecognizer(sp->recognizerType); - // do not delete the recognizer. The QGestureManager is doing this. - sp->recognizer = 0; -} - -#endif // QT_NO_GESTURES - -/*! - \internal -*/ -QScroller::QScroller(QObject *target) - : d_ptr(new QScrollerPrivate(this, target)) -{ - Q_ASSERT(target); // you can't create a scroller without a target in any normal way - Q_D(QScroller); - d->init(); -} - -/*! - \internal -*/ -QScroller::~QScroller() -{ - Q_D(QScroller); -#ifndef QT_NO_GESTURES - QGestureRecognizer::unregisterRecognizer(d->recognizerType); - // do not delete the recognizer. The QGestureManager is doing this. - d->recognizer = 0; -#endif - qt_allScrollers()->remove(d->target); - qt_activeScrollers()->remove(this); - - delete d_ptr; -} - - -/*! - \fn QScroller::stateChanged(QScroller::State newState); - - QScroller emits this signal whenever the state changes. \a newState is the new State. - - \sa state -*/ - -/*! - \property QScroller::state - \brief the state of the scroller - - \sa QScroller::State -*/ -QScroller::State QScroller::state() const -{ - Q_D(const QScroller); - return d->state; -} - -/*! - Stops the scroller and resets its state back to Inactive. -*/ -void QScroller::stop() -{ - Q_D(QScroller); - if (d->state != Inactive) { - QPointF here = clampToRect(d->contentPosition, d->contentPosRange); - qreal snapX = d->nextSnapPos(here.x(), 0, Qt::Horizontal); - qreal snapY = d->nextSnapPos(here.y(), 0, Qt::Vertical); - QPointF snap = here; - if (!qIsNaN(snapX)) - snap.setX(snapX); - if (!qIsNaN(snapY)) - snap.setY(snapY); - d->contentPosition = snap; - d->overshootPosition = QPointF(0, 0); - - d->setState(Inactive); - } -} - -/*! - Returns the pixel per meter metric for the scrolled widget. - - The value is reported for both the x and y axis separately by using a QPointF. - - \note Please note that this value should be physically correct. The actual DPI settings - that Qt returns for the display may be reported wrongly on purpose by the underlying - windowing system, for example on Mac OS X or Maemo 5. -*/ -QPointF QScroller::pixelPerMeter() const -{ - Q_D(const QScroller); - QPointF ppm = d->pixelPerMeter; - -#ifndef QT_NO_GRAPHICSVIEW - if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(d->target)) { - QTransform viewtr; - //TODO: the first view isn't really correct - maybe use an additional field in the prepare event? - if (go->scene() && !go->scene()->views().isEmpty()) - viewtr = go->scene()->views().first()->viewportTransform(); - QTransform tr = go->deviceTransform(viewtr); - if (tr.isScaling()) { - QPointF p0 = tr.map(QPointF(0, 0)); - QPointF px = tr.map(QPointF(1, 0)); - QPointF py = tr.map(QPointF(0, 1)); - ppm.rx() /= QLineF(p0, px).length(); - ppm.ry() /= QLineF(p0, py).length(); - } - } -#endif // QT_NO_GRAPHICSVIEW - return ppm; -} - -/*! - Returns the current scrolling velocity in meter per second when the state is Scrolling or Dragging. - Returns a zero velocity otherwise. - - The velocity is reported for both the x and y axis separately by using a QPointF. - - \sa pixelPerMeter() -*/ -QPointF QScroller::velocity() const -{ - Q_D(const QScroller); - const QScrollerPropertiesPrivate *sp = d->properties.d.data(); - - switch (state()) { - case Dragging: - return d->releaseVelocity; - case Scrolling: { - QPointF vel; - qint64 now = d->monotonicTimer.elapsed(); - - if (!d->xSegments.isEmpty()) { - const QScrollerPrivate::ScrollSegment &s = d->xSegments.head(); - qreal progress = qreal(now - s.startTime) / qreal(s.deltaTime); - qreal v = qSign(s.deltaPos) * qreal(s.deltaTime) / qreal(1000) * sp->decelerationFactor * qreal(0.5) * differentialForProgress(s.curve, progress); - vel.setX(v); - } - - if (!d->ySegments.isEmpty()) { - const QScrollerPrivate::ScrollSegment &s = d->ySegments.head(); - qreal progress = qreal(now - s.startTime) / qreal(s.deltaTime); - qreal v = qSign(s.deltaPos) * qreal(s.deltaTime) / qreal(1000) * sp->decelerationFactor * qreal(0.5) * differentialForProgress(s.curve, progress); - vel.setY(v); - } - return vel; - } - default: - return QPointF(0, 0); - } -} - -/*! - Returns the estimated final position for the current scroll movement. - Returns the current position if the scroller state is not Scrolling. - The result is undefined when the scroller state is Inactive. - - The target position is in pixel. - - \sa pixelPerMeter(), scrollTo() -*/ -QPointF QScroller::finalPosition() const -{ - Q_D(const QScroller); - return QPointF(d->scrollingSegmentsEndPos(Qt::Horizontal), - d->scrollingSegmentsEndPos(Qt::Vertical)); -} - -/*! - Starts scrolling the widget so that point \a pos is at the top-left position in - the viewport. - - The behaviour when scrolling outside the valid scroll area is undefined. - In this case the scroller might or might not overshoot. - - The scrolling speed will be calculated so that the given position will - be reached after a platform-defined time span. - - \a pos is given in viewport coordinates. - - \sa ensureVisible() -*/ -void QScroller::scrollTo(const QPointF &pos) -{ - // we could make this adjustable via QScrollerProperties - scrollTo(pos, 300); -} - -/*! \overload - - This version will reach its destination position in \a scrollTime milliseconds. -*/ -void QScroller::scrollTo(const QPointF &pos, int scrollTime) -{ - Q_D(QScroller); - - if (d->state == Pressed || d->state == Dragging ) - return; - - // no need to resend a prepare event if we are already scrolling - if (d->state == Inactive && !d->prepareScrolling(QPointF())) - return; - - QPointF newpos = clampToRect(pos, d->contentPosRange); - qreal snapX = d->nextSnapPos(newpos.x(), 0, Qt::Horizontal); - qreal snapY = d->nextSnapPos(newpos.y(), 0, Qt::Vertical); - if (!qIsNaN(snapX)) - newpos.setX(snapX); - if (!qIsNaN(snapY)) - newpos.setY(snapY); - - qScrollerDebug() << "QScroller::scrollTo(req:" << pos << " [pix] / snap:" << newpos << ", " << scrollTime << " [ms])"; - - if (newpos == d->contentPosition + d->overshootPosition) - return; - - QPointF vel = velocity(); - - if (scrollTime < 0) - scrollTime = 0; - qreal time = qreal(scrollTime) / 1000; - - d->createScrollToSegments(vel.x(), time, newpos.x(), Qt::Horizontal, QScrollerPrivate::ScrollTypeScrollTo); - d->createScrollToSegments(vel.y(), time, newpos.y(), Qt::Vertical, QScrollerPrivate::ScrollTypeScrollTo); - - if (!scrollTime) - d->setContentPositionHelperScrolling(); - d->setState(scrollTime ? Scrolling : Inactive); -} - -/*! - Starts scrolling so that the rectangle \a rect is visible inside the - viewport with additional margins specified in pixels by \a xmargin and \a ymargin around - the rect. - - In cases where it is not possible to fit the rect plus margins inside the viewport the contents - are scrolled so that as much as possible is visible from \a rect. - - The scrolling speed is calculated so that the given position is reached after a platform-defined - time span. - - This function performs the actual scrolling by calling scrollTo(). - - \sa scrollTo -*/ -void QScroller::ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin) -{ - // we could make this adjustable via QScrollerProperties - ensureVisible(rect, xmargin, ymargin, 1000); -} - -/*! \overload - - This version will reach its destination position in \a scrollTime milliseconds. -*/ -void QScroller::ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin, int scrollTime) -{ - Q_D(QScroller); - - if (d->state == Pressed || d->state == Dragging ) - return; - - if (d->state == Inactive && !d->prepareScrolling(QPointF())) - return; - - // -- calculate the current pos (or the position after the current scroll) - QPointF startPos = d->contentPosition + d->overshootPosition; - startPos = QPointF(d->scrollingSegmentsEndPos(Qt::Horizontal), - d->scrollingSegmentsEndPos(Qt::Vertical)); - - QRectF marginRect(rect.x() - xmargin, rect.y() - ymargin, - rect.width() + 2 * xmargin, rect.height() + 2 * ymargin); - - QSizeF visible = d->viewportSize; - QRectF visibleRect(startPos, visible); - - qScrollerDebug() << "QScroller::ensureVisible(" << rect << " [pix], " << xmargin << " [pix], " << ymargin << " [pix], " << scrollTime << "[ms])"; - qScrollerDebug() << " --> content position:" << d->contentPosition; - - if (visibleRect.contains(marginRect)) - return; - - QPointF newPos = startPos; - - if (visibleRect.width() < rect.width()) { - // at least try to move the rect into view - if (rect.left() > visibleRect.left()) - newPos.setX(rect.left()); - else if (rect.right() < visibleRect.right()) - newPos.setX(rect.right() - visible.width()); - - } else if (visibleRect.width() < marginRect.width()) { - newPos.setX(rect.center().x() - visibleRect.width() / 2); - } else if (marginRect.left() > visibleRect.left()) { - newPos.setX(marginRect.left()); - } else if (marginRect.right() < visibleRect.right()) { - newPos.setX(marginRect.right() - visible.width()); - } - - if (visibleRect.height() < rect.height()) { - // at least try to move the rect into view - if (rect.top() > visibleRect.top()) - newPos.setX(rect.top()); - else if (rect.bottom() < visibleRect.bottom()) - newPos.setX(rect.bottom() - visible.height()); - - } else if (visibleRect.height() < marginRect.height()) { - newPos.setY(rect.center().y() - visibleRect.height() / 2); - } else if (marginRect.top() > visibleRect.top()) { - newPos.setY(marginRect.top()); - } else if (marginRect.bottom() < visibleRect.bottom()) { - newPos.setY(marginRect.bottom() - visible.height()); - } - - // clamp to maximum content position - newPos = clampToRect(newPos, d->contentPosRange); - if (newPos == startPos) - return; - - scrollTo(newPos, scrollTime); -} - -/*! This function resends the QScrollPrepareEvent. - Calling resendPrepareEvent triggers a QScrollPrepareEvent from the scroller. - This allows the receiver to re-set content position and content size while - scrolling. - Calling this function while in the Inactive state is useless as the prepare event - is sent again before scrolling starts. - */ -void QScroller::resendPrepareEvent() -{ - Q_D(QScroller); - d->prepareScrolling(d->pressPosition); -} - -/*! Set the snap positions for the horizontal axis to a list of \a positions. - This overwrites all previously set snap positions and also a previously - set snapping interval. - Snapping can be deactivated by setting an empty list of positions. - */ -void QScroller::setSnapPositionsX(const QList<qreal> &positions) -{ - Q_D(QScroller); - d->snapPositionsX = positions; - d->snapIntervalX = 0.0; - - d->recalcScrollingSegments(); -} - -/*! Set the snap positions for the horizontal axis to regular spaced intervals. - The first snap position is at \a first. The next at \a first + \a interval. - This can be used to implement a list header. - This overwrites all previously set snap positions and also a previously - set snapping interval. - Snapping can be deactivated by setting an interval of 0.0 - */ -void QScroller::setSnapPositionsX(qreal first, qreal interval) -{ - Q_D(QScroller); - d->snapFirstX = first; - d->snapIntervalX = interval; - d->snapPositionsX.clear(); - - d->recalcScrollingSegments(); -} - -/*! Set the snap positions for the vertical axis to a list of \a positions. - This overwrites all previously set snap positions and also a previously - set snapping interval. - Snapping can be deactivated by setting an empty list of positions. - */ -void QScroller::setSnapPositionsY(const QList<qreal> &positions) -{ - Q_D(QScroller); - d->snapPositionsY = positions; - d->snapIntervalY = 0.0; - - d->recalcScrollingSegments(); -} - -/*! Set the snap positions for the vertical axis to regular spaced intervals. - The first snap position is at \a first. The next at \a first + \a interval. - This overwrites all previously set snap positions and also a previously - set snapping interval. - Snapping can be deactivated by setting an interval of 0.0 - */ -void QScroller::setSnapPositionsY(qreal first, qreal interval) -{ - Q_D(QScroller); - d->snapFirstY = first; - d->snapIntervalY = interval; - d->snapPositionsY.clear(); - - d->recalcScrollingSegments(); -} - - - -// -------------- private ------------ - -QScrollerPrivate::QScrollerPrivate(QScroller *q, QObject *_target) - : target(_target) -#ifndef QT_NO_GESTURES - , recognizer(0) - , recognizerType(Qt::CustomGesture) -#endif - , state(QScroller::Inactive) - , firstScroll(true) - , pressTimestamp(0) - , lastTimestamp(0) - , snapFirstX(-1.0) - , snapIntervalX(0.0) - , snapFirstY(-1.0) - , snapIntervalY(0.0) -#ifndef QT_NO_ANIMATION - , scrollTimer(new QScrollTimer(this)) -#endif - , q_ptr(q) -{ - connect(target, SIGNAL(destroyed(QObject*)), this, SLOT(targetDestroyed())); -} - -void QScrollerPrivate::init() -{ - setDpiFromWidget(0); - monotonicTimer.start(); -} - -void QScrollerPrivate::sendEvent(QObject *o, QEvent *e) -{ - qt_sendSpontaneousEvent(o, e); -} - -const char *QScrollerPrivate::stateName(QScroller::State state) -{ - switch (state) { - case QScroller::Inactive: return "inactive"; - case QScroller::Pressed: return "pressed"; - case QScroller::Dragging: return "dragging"; - case QScroller::Scrolling: return "scrolling"; - default: return "(invalid)"; - } -} - -const char *QScrollerPrivate::inputName(QScroller::Input input) -{ - switch (input) { - case QScroller::InputPress: return "press"; - case QScroller::InputMove: return "move"; - case QScroller::InputRelease: return "release"; - default: return "(invalid)"; - } -} - -void QScrollerPrivate::targetDestroyed() -{ -#ifndef QT_NO_ANIMATION - scrollTimer->stop(); -#endif - delete q_ptr; -} - -void QScrollerPrivate::timerTick() -{ - struct timerevent { - QScroller::State state; - typedef void (QScrollerPrivate::*timerhandler_t)(); - timerhandler_t handler; - }; - - timerevent timerevents[] = { - { QScroller::Dragging, &QScrollerPrivate::timerEventWhileDragging }, - { QScroller::Scrolling, &QScrollerPrivate::timerEventWhileScrolling }, - }; - - for (int i = 0; i < int(sizeof(timerevents) / sizeof(*timerevents)); ++i) { - timerevent *te = timerevents + i; - - if (state == te->state) { - (this->*te->handler)(); - return; - } - } - -#ifndef QT_NO_ANIMATION - scrollTimer->stop(); -#endif -} - -/*! - This function is used by gesture recognizers to inform the scroller about a new input event. - The scroller changes its internal state() according to the input event and its attached - scroller properties. The scroller doesn't distinguish between the kind of input device the - event came from. Therefore the event needs to be split into the \a input type, a \a position and a - milli-second \a timestamp. The \a position needs to be in the target's coordinate system. - - The return value is \c true if the event should be consumed by the calling filter or \c false - if the event should be forwarded to the control. - - \note Using grabGesture() should be sufficient for most use cases. -*/ -bool QScroller::handleInput(Input input, const QPointF &position, qint64 timestamp) -{ - Q_D(QScroller); - - qScrollerDebug() << "QScroller::handleInput(" << input << ", " << d->stateName(d->state) << ", " << position << ", " << timestamp << ")"; - struct statechange { - State state; - Input input; - typedef bool (QScrollerPrivate::*inputhandler_t)(const QPointF &position, qint64 timestamp); - inputhandler_t handler; - }; - - statechange statechanges[] = { - { QScroller::Inactive, InputPress, &QScrollerPrivate::pressWhileInactive }, - { QScroller::Pressed, InputMove, &QScrollerPrivate::moveWhilePressed }, - { QScroller::Pressed, InputRelease, &QScrollerPrivate::releaseWhilePressed }, - { QScroller::Dragging, InputMove, &QScrollerPrivate::moveWhileDragging }, - { QScroller::Dragging, InputRelease, &QScrollerPrivate::releaseWhileDragging }, - { QScroller::Scrolling, InputPress, &QScrollerPrivate::pressWhileScrolling } - }; - - for (int i = 0; i < int(sizeof(statechanges) / sizeof(*statechanges)); ++i) { - statechange *sc = statechanges + i; - - if (d->state == sc->state && input == sc->input) - return (d->*sc->handler)(position - d->overshootPosition, timestamp); - } - return false; -} - -#if !defined(Q_WS_MAC) -// the Mac version is implemented in qscroller_mac.mm - -QPointF QScrollerPrivate::realDpi(int screen) -{ -# ifdef Q_WS_MAEMO_5 - Q_UNUSED(screen); - - // The DPI value is hardcoded to 96 on Maemo5: - // https://projects.maemo.org/bugzilla/show_bug.cgi?id=152525 - // This value (260) is only correct for the N900 though, but - // there's no way to get the real DPI at run time. - return QPointF(260, 260); - -# elif defined(Q_WS_X11) && !defined(QT_NO_XRANDR) - if (X11 && X11->use_xrandr && X11->ptrXRRSizes && X11->ptrXRRRootToScreen) { - int nsizes = 0; - // QDesktopWidget is based on Xinerama screens, which do not always - // correspond to RandR screens: NVidia's TwinView e.g. will show up - // as 2 screens in QDesktopWidget, but libXRandR will only see 1 screen. - // (although with the combined size of the Xinerama screens). - // Additionally, libXrandr will simply crash when calling XRRSizes - // for (the non-existent) screen 1 in this scenario. - Window root = RootWindow(X11->display, screen == -1 ? X11->defaultScreen : screen); - int randrscreen = (root != XNone) ? X11->ptrXRRRootToScreen(X11->display, root) : -1; - - XRRScreenSize *sizes = X11->ptrXRRSizes(X11->display, randrscreen == -1 ? 0 : randrscreen, &nsizes); - if (nsizes > 0 && sizes && sizes->width && sizes->height && sizes->mwidth && sizes->mheight) { - qScrollerDebug() << "XRandR DPI:" << QPointF(qreal(25.4) * qreal(sizes->width) / qreal(sizes->mwidth), - qreal(25.4) * qreal(sizes->height) / qreal(sizes->mheight)); - return QPointF(qreal(25.4) * qreal(sizes->width) / qreal(sizes->mwidth), - qreal(25.4) * qreal(sizes->height) / qreal(sizes->mheight)); - } - } -# endif - - QWidget *w = QApplication::desktop()->screen(screen); - return QPointF(w->physicalDpiX(), w->physicalDpiY()); -} - -#endif // !Q_WS_MAC - - -/*! \internal - Returns the resolution of the used screen. -*/ -QPointF QScrollerPrivate::dpi() const -{ - return pixelPerMeter * qreal(0.0254); -} - -/*! \internal - Sets the resolution used for scrolling. - This resolution is only used by the kinetic scroller. If you change this - then the scroller will behave quite different as a lot of the values are - given in physical distances (millimeter). -*/ -void QScrollerPrivate::setDpi(const QPointF &dpi) -{ - pixelPerMeter = dpi / qreal(0.0254); -} - -/*! \internal - Sets the dpi used for scrolling to the value of the widget. -*/ -void QScrollerPrivate::setDpiFromWidget(QWidget *widget) -{ - QDesktopWidget *dw = QApplication::desktop(); - setDpi(realDpi(widget ? dw->screenNumber(widget) : dw->primaryScreen())); -} - -/*! \internal - Updates the velocity during dragging. - Sets releaseVelocity. -*/ -void QScrollerPrivate::updateVelocity(const QPointF &deltaPixelRaw, qint64 deltaTime) -{ - if (deltaTime <= 0) - return; - - Q_Q(QScroller); - QPointF ppm = q->pixelPerMeter(); - const QScrollerPropertiesPrivate *sp = properties.d.data(); - QPointF deltaPixel = deltaPixelRaw; - - qScrollerDebug() << "QScroller::updateVelocity(" << deltaPixelRaw << " [delta pix], " << deltaTime << " [delta ms])"; - - // faster than 2.5mm/ms seems bogus (that would be a screen height in ~20 ms) - if (((deltaPixelRaw / qreal(deltaTime)).manhattanLength() / ((ppm.x() + ppm.y()) / 2) * 1000) > qreal(2.5)) - deltaPixel = deltaPixelRaw * qreal(2.5) * ppm / 1000 / (deltaPixelRaw / qreal(deltaTime)).manhattanLength(); - - QPointF newv = -deltaPixel / qreal(deltaTime) * qreal(1000) / ppm; - // around 95% of all updates are in the [1..50] ms range, so make sure - // to scale the smoothing factor over that range: this way a 50ms update - // will have full impact, while 5ms update will only have a 10% impact. - qreal smoothing = sp->dragVelocitySmoothingFactor * qMin(qreal(deltaTime), qreal(50)) / qreal(50); - - // only smooth if we already have a release velocity and only if the - // user hasn't stopped to move his finger for more than 100ms - if ((releaseVelocity != QPointF(0, 0)) && (deltaTime < 100)) { - qScrollerDebug() << "SMOOTHED from " << newv << " to " << newv * smoothing + releaseVelocity * (qreal(1) - smoothing); - // smooth x or y only if the new velocity is either 0 or at least in - // the same direction of the release velocity - if (!newv.x() || (qSign(releaseVelocity.x()) == qSign(newv.x()))) - newv.setX(newv.x() * smoothing + releaseVelocity.x() * (qreal(1) - smoothing)); - if (!newv.y() || (qSign(releaseVelocity.y()) == qSign(newv.y()))) - newv.setY(newv.y() * smoothing + releaseVelocity.y() * (qreal(1) - smoothing)); - } else - qScrollerDebug() << "NO SMOOTHING to " << newv; - - releaseVelocity.setX(qBound(-sp->maximumVelocity, newv.x(), sp->maximumVelocity)); - releaseVelocity.setY(qBound(-sp->maximumVelocity, newv.y(), sp->maximumVelocity)); - - qScrollerDebug() << " --> new velocity:" << releaseVelocity; -} - -void QScrollerPrivate::pushSegment(ScrollType type, qreal deltaTime, qreal stopProgress, qreal startPos, qreal deltaPos, qreal stopPos, QEasingCurve::Type curve, Qt::Orientation orientation) -{ - if (startPos == stopPos || deltaPos == 0) - return; - - ScrollSegment s; - if (orientation == Qt::Horizontal && !xSegments.isEmpty()) - s.startTime = xSegments.last().startTime + xSegments.last().deltaTime * xSegments.last().stopProgress; - else if (orientation == Qt::Vertical && !ySegments.isEmpty()) - s.startTime = ySegments.last().startTime + ySegments.last().deltaTime * ySegments.last().stopProgress; - else - s.startTime = monotonicTimer.elapsed(); - - s.startPos = startPos; - s.deltaPos = deltaPos; - s.stopPos = stopPos; - s.deltaTime = deltaTime * 1000; - s.stopProgress = stopProgress; - s.curve.setType(curve); - s.type = type; - - if (orientation == Qt::Horizontal) - xSegments.enqueue(s); - else - ySegments.enqueue(s); - - qScrollerDebug() << "+++ Added a new ScrollSegment: " << s; -} - - -/*! \internal - Clears the old segments and recalculates them if the current segments are not longer valid -*/ -void QScrollerPrivate::recalcScrollingSegments(bool forceRecalc) -{ - Q_Q(QScroller); - QPointF ppm = q->pixelPerMeter(); - - releaseVelocity = q->velocity(); - - if (forceRecalc || !scrollingSegmentsValid(Qt::Horizontal)) - createScrollingSegments(releaseVelocity.x(), contentPosition.x() + overshootPosition.x(), ppm.x(), Qt::Horizontal); - - if (forceRecalc || !scrollingSegmentsValid(Qt::Vertical)) - createScrollingSegments(releaseVelocity.y(), contentPosition.y() + overshootPosition.y(), ppm.y(), Qt::Vertical); -} - -/*! \internal - Returns the end position after the current scroll has finished. -*/ -qreal QScrollerPrivate::scrollingSegmentsEndPos(Qt::Orientation orientation) const -{ - if (orientation == Qt::Horizontal) { - if (xSegments.isEmpty()) - return contentPosition.x() + overshootPosition.x(); - else - return xSegments.last().stopPos; - } else { - if (ySegments.isEmpty()) - return contentPosition.y() + overshootPosition.y(); - else - return ySegments.last().stopPos; - } -} - -/*! \internal - Checks if the scroller segment end in a valid position. -*/ -bool QScrollerPrivate::scrollingSegmentsValid(Qt::Orientation orientation) -{ - QQueue<ScrollSegment> *segments; - qreal minPos; - qreal maxPos; - - if (orientation == Qt::Horizontal) { - segments = &xSegments; - minPos = contentPosRange.left(); - maxPos = contentPosRange.right(); - } else { - segments = &ySegments; - minPos = contentPosRange.top(); - maxPos = contentPosRange.bottom(); - } - - if (segments->isEmpty()) - return true; - - const ScrollSegment &last = segments->last(); - qreal stopPos = last.stopPos; - - if (last.type == ScrollTypeScrollTo) - return true; // scrollTo is always valid - - if (last.type == ScrollTypeOvershoot && - (stopPos != minPos && stopPos != maxPos)) - return false; - - if (stopPos < minPos || stopPos > maxPos) - return false; - - if (stopPos == minPos || stopPos == maxPos) // the begin and the end of the list are always ok - return true; - - qreal nextSnap = nextSnapPos(stopPos, 0, orientation); - if (!qIsNaN(nextSnap) && stopPos != nextSnap) - return false; - - return true; -} - -/*! \internal - Creates the sections needed to scroll to the specific \a endPos to the segments queue. -*/ -void QScrollerPrivate::createScrollToSegments(qreal v, qreal deltaTime, qreal endPos, Qt::Orientation orientation, ScrollType type) -{ - Q_UNUSED(v); - - if (orientation == Qt::Horizontal) - xSegments.clear(); - else - ySegments.clear(); - - qScrollerDebug() << "+++ createScrollToSegments: t:" << deltaTime << "ep:" << endPos << "o:" << int(orientation); - - const QScrollerPropertiesPrivate *sp = properties.d.data(); - - qreal startPos = (orientation == Qt::Horizontal) ? contentPosition.x() + overshootPosition.x() - : contentPosition.y() + overshootPosition.y(); - qreal deltaPos = (endPos - startPos) / 2; - - pushSegment(type, deltaTime * qreal(0.3), qreal(1.0), startPos, deltaPos, startPos + deltaPos, QEasingCurve::InQuad, orientation); - pushSegment(type, deltaTime * qreal(0.7), qreal(1.0), startPos + deltaPos, deltaPos, endPos, sp->scrollingCurve.type(), orientation); -} - -/*! \internal -*/ -void QScrollerPrivate::createScrollingSegments(qreal v, qreal startPos, qreal ppm, Qt::Orientation orientation) -{ - const QScrollerPropertiesPrivate *sp = properties.d.data(); - - QScrollerProperties::OvershootPolicy policy; - qreal minPos; - qreal maxPos; - qreal viewSize; - - if (orientation == Qt::Horizontal) { - xSegments.clear(); - policy = sp->hOvershootPolicy; - minPos = contentPosRange.left(); - maxPos = contentPosRange.right(); - viewSize = viewportSize.width(); - } else { - ySegments.clear(); - policy = sp->vOvershootPolicy; - minPos = contentPosRange.top(); - maxPos = contentPosRange.bottom(); - viewSize = viewportSize.height(); - } - - bool alwaysOvershoot = (policy == QScrollerProperties::OvershootAlwaysOn); - bool noOvershoot = (policy == QScrollerProperties::OvershootAlwaysOff) || !sp->overshootScrollDistanceFactor; - bool canOvershoot = !noOvershoot && (alwaysOvershoot || maxPos); - - qScrollerDebug() << "+++ createScrollingSegments: s:" << startPos << "maxPos:" << maxPos << "o:" << int(orientation); - - qScrollerDebug() << "v = " << v << ", decelerationFactor = " << sp->decelerationFactor << ", curveType = " << sp->scrollingCurve.type(); - - // This is only correct for QEasingCurve::OutQuad (linear velocity, - // constant deceleration), but the results look and feel ok for OutExpo - // and OutSine as well - - // v(t) = deltaTime * a * 0.5 * differentialForProgress(t / deltaTime) - // v(0) = vrelease - // v(deltaTime) = 0 - // deltaTime = (2 * vrelease) / (a * differntial(0)) - - // pos(t) = integrate(v(t)dt) - // pos(t) = vrelease * t - 0.5 * a * t * t - // pos(t) = deltaTime * a * 0.5 * progress(t / deltaTime) * deltaTime - // deltaPos = pos(deltaTime) - - qreal deltaTime = (qreal(2) * qAbs(v)) / (sp->decelerationFactor * differentialForProgress(sp->scrollingCurve, 0)); - qreal deltaPos = qSign(v) * deltaTime * deltaTime * qreal(0.5) * sp->decelerationFactor * ppm; - qreal endPos = startPos + deltaPos; - - qScrollerDebug() << " Real Delta:" << deltaPos; - - // -- determine snap points - qreal nextSnap = nextSnapPos(endPos, 0, orientation); - qreal lowerSnapPos = nextSnapPos(startPos, -1, orientation); - qreal higherSnapPos = nextSnapPos(startPos, 1, orientation); - - qScrollerDebug() << " Real Delta:" << lowerSnapPos <<"-"<<nextSnap <<"-"<<higherSnapPos; - - // - check if we can reach another snap point - if (nextSnap > higherSnapPos || qIsNaN(higherSnapPos)) - higherSnapPos = nextSnap; - if (nextSnap < lowerSnapPos || qIsNaN(lowerSnapPos)) - lowerSnapPos = nextSnap; - - // -- check if are in overshoot and end in overshoot - if ((startPos < minPos && endPos < minPos) || - (startPos > maxPos && endPos > maxPos)) { - qreal stopPos = endPos < minPos ? minPos : maxPos; - qreal oDeltaTime = sp->overshootScrollTime; - - pushSegment(ScrollTypeOvershoot, oDeltaTime * qreal(0.7), qreal(1.0), startPos, stopPos - startPos, stopPos, sp->scrollingCurve.type(), orientation); - return; - } - - if (qAbs(v) < sp->minimumVelocity) { - - qScrollerDebug() << "### below minimum Vel" << orientation; - - // - no snap points or already at one - if (qIsNaN(nextSnap) || nextSnap == startPos) - return; // nothing to do, no scrolling needed. - - // - decide which point to use - - qreal snapDistance = higherSnapPos - lowerSnapPos; - - qreal pressDistance = (orientation == Qt::Horizontal) ? - lastPosition.x() - pressPosition.x() : - lastPosition.y() - pressPosition.y(); - - // if not dragged far enough, pick the next snap point. - if (sp->snapPositionRatio == 0.0 || qAbs(pressDistance / sp->snapPositionRatio) > snapDistance) - endPos = nextSnap; - else if (pressDistance < 0.0) - endPos = lowerSnapPos; - else - endPos = higherSnapPos; - - deltaPos = endPos - startPos; - qreal midPos = startPos + deltaPos * qreal(0.3); - pushSegment(ScrollTypeFlick, sp->snapTime * qreal(0.3), qreal(1.0), startPos, midPos - startPos, midPos, QEasingCurve::InQuad, orientation); - pushSegment(ScrollTypeFlick, sp->snapTime * qreal(0.7), qreal(1.0), midPos, endPos - midPos, endPos, sp->scrollingCurve.type(), orientation); - return; - } - - // - go to the next snappoint if there is one - if (v > 0 && !qIsNaN(higherSnapPos)) { - // change the time in relation to the changed end position - if (endPos - startPos) - deltaTime *= qAbs((higherSnapPos - startPos) / (endPos - startPos)); - if (deltaTime > sp->snapTime) - deltaTime = sp->snapTime; - endPos = higherSnapPos; - - } else if (v < 0 && !qIsNaN(lowerSnapPos)) { - // change the time in relation to the changed end position - if (endPos - startPos) - deltaTime *= qAbs((lowerSnapPos - startPos) / (endPos - startPos)); - if (deltaTime > sp->snapTime) - deltaTime = sp->snapTime; - endPos = lowerSnapPos; - - // -- check if we are overshooting - } else if (endPos < minPos || endPos > maxPos) { - qreal stopPos = endPos < minPos ? minPos : maxPos; - - qScrollerDebug() << "Overshoot: delta:" << (stopPos - startPos); - - qreal stopProgress = progressForValue(sp->scrollingCurve, qAbs((stopPos - startPos) / deltaPos)); - - if (!canOvershoot) { - qScrollerDebug() << "Overshoot stopp:" << stopProgress; - - pushSegment(ScrollTypeFlick, deltaTime, stopProgress, startPos, endPos, stopPos, sp->scrollingCurve.type(), orientation); - } else { - qreal oDeltaTime = sp->overshootScrollTime; - qreal oStopProgress = qMin(stopProgress + oDeltaTime * qreal(0.3) / deltaTime, qreal(1)); - qreal oDistance = startPos + deltaPos * sp->scrollingCurve.valueForProgress(oStopProgress) - stopPos; - qreal oMaxDistance = qSign(oDistance) * (viewSize * sp->overshootScrollDistanceFactor); - - qScrollerDebug() << "1 oDistance:" << oDistance << "Max:" << oMaxDistance << "stopP/oStopP" << stopProgress << oStopProgress; - - if (qAbs(oDistance) > qAbs(oMaxDistance)) { - oStopProgress = progressForValue(sp->scrollingCurve, qAbs((stopPos + oMaxDistance - startPos) / deltaPos)); - oDistance = oMaxDistance; - qScrollerDebug() << "2 oDistance:" << oDistance << "Max:" << oMaxDistance << "stopP/oStopP" << stopProgress << oStopProgress; - } - - pushSegment(ScrollTypeFlick, deltaTime, oStopProgress, startPos, deltaPos, stopPos + oDistance, sp->scrollingCurve.type(), orientation); - pushSegment(ScrollTypeOvershoot, oDeltaTime * qreal(0.7), qreal(1.0), stopPos + oDistance, -oDistance, stopPos, sp->scrollingCurve.type(), orientation); - } - return; - } - - pushSegment(ScrollTypeFlick, deltaTime, qreal(1.0), startPos, deltaPos, endPos, sp->scrollingCurve.type(), orientation); -} - - -/*! \internal - Prepares scrolling by sending a QScrollPrepareEvent to the receiver widget. - Returns true if the scrolling was accepted and a target was returned. -*/ -bool QScrollerPrivate::prepareScrolling(const QPointF &position) -{ - QScrollPrepareEvent spe(position); - spe.ignore(); - sendEvent(target, &spe); - - qScrollerDebug() << "QScrollPrepareEvent returned from" << target << "with" << spe.isAccepted() << "mcp:" << spe.contentPosRange() << "cp:" << spe.contentPos(); - if (spe.isAccepted()) { - QPointF oldContentPos = contentPosition + overshootPosition; - QPointF contentDelta = spe.contentPos() - oldContentPos; - - viewportSize = spe.viewportSize(); - contentPosRange = spe.contentPosRange(); - if (contentPosRange.width() < 0) - contentPosRange.setWidth(0); - if (contentPosRange.height() < 0) - contentPosRange.setHeight(0); - contentPosition = clampToRect(spe.contentPos(), contentPosRange); - overshootPosition = spe.contentPos() - contentPosition; - - // - check if the content position was moved - if (contentDelta != QPointF(0, 0)) { - // need to correct all segments - for (int i = 0; i < xSegments.count(); i++) - xSegments[i].startPos -= contentDelta.x(); - - for (int i = 0; i < ySegments.count(); i++) - ySegments[i].startPos -= contentDelta.y(); - } - - if (QWidget *w = qobject_cast<QWidget *>(target)) - setDpiFromWidget(w); -#ifndef QT_NO_GRAPHICSVIEW - if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(target)) { - //TODO: the first view isn't really correct - maybe use an additional field in the prepare event? - if (go->scene() && !go->scene()->views().isEmpty()) - setDpiFromWidget(go->scene()->views().first()); - } -#endif - - if (state == QScroller::Scrolling) { - recalcScrollingSegments(); - } - return true; - } - - return false; -} - -void QScrollerPrivate::handleDrag(const QPointF &position, qint64 timestamp) -{ - const QScrollerPropertiesPrivate *sp = properties.d.data(); - - QPointF deltaPixel = position - lastPosition; - qint64 deltaTime = timestamp - lastTimestamp; - - if (sp->axisLockThreshold) { - int dx = qAbs(deltaPixel.x()); - int dy = qAbs(deltaPixel.y()); - if (dx || dy) { - bool vertical = (dy > dx); - qreal alpha = qreal(vertical ? dx : dy) / qreal(vertical ? dy : dx); - //qScrollerDebug() << "QScroller::handleDrag() -- axis lock:" << alpha << " / " << axisLockThreshold << "- isvertical:" << vertical << "- dx:" << dx << "- dy:" << dy; - if (alpha <= sp->axisLockThreshold) { - if (vertical) - deltaPixel.setX(0); - else - deltaPixel.setY(0); - } - } - } - - // calculate velocity (if the user would release the mouse NOW) - updateVelocity(deltaPixel, deltaTime); - - // restrict velocity, if content is not scrollable - QRectF max = contentPosRange; - bool canScrollX = (max.width() > 0) || (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn); - bool canScrollY = (max.height() > 0) || (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn); - - if (!canScrollX) { - deltaPixel.setX(0); - releaseVelocity.setX(0); - } - if (!canScrollY) { - deltaPixel.setY(0); - releaseVelocity.setY(0); - } - -// if (firstDrag) { -// // Do not delay the first drag -// setContentPositionHelper(q->contentPosition() - overshootDistance - deltaPixel); -// dragDistance = QPointF(0, 0); -// } else { - dragDistance += deltaPixel; -// } -//qScrollerDebug() << "######################" << deltaPixel << position.y() << lastPosition.y(); - if (canScrollX) - lastPosition.setX(position.x()); - if (canScrollY) - lastPosition.setY(position.y()); - lastTimestamp = timestamp; -} - -bool QScrollerPrivate::pressWhileInactive(const QPointF &position, qint64 timestamp) -{ - if (prepareScrolling(position)) { - const QScrollerPropertiesPrivate *sp = properties.d.data(); - - if (!contentPosRange.isNull() || - (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn) || - (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn)) { - - lastPosition = pressPosition = position; - lastTimestamp = pressTimestamp = timestamp; - setState(QScroller::Pressed); - } - } - return false; -} - -bool QScrollerPrivate::releaseWhilePressed(const QPointF &, qint64) -{ - if (overshootPosition != QPointF(0.0, 0.0)) { - setState(QScroller::Scrolling); - return true; - } else { - setState(QScroller::Inactive); - return false; - } -} - -bool QScrollerPrivate::moveWhilePressed(const QPointF &position, qint64 timestamp) -{ - Q_Q(QScroller); - const QScrollerPropertiesPrivate *sp = properties.d.data(); - QPointF ppm = q->pixelPerMeter(); - - QPointF deltaPixel = position - pressPosition; - - bool moveAborted = false; - bool moveStarted = (((deltaPixel / ppm).manhattanLength()) > sp->dragStartDistance); - - // check the direction of the mouse drag and abort if it's too much in the wrong direction. - if (moveStarted) { - QRectF max = contentPosRange; - bool canScrollX = (max.width() > 0); - bool canScrollY = (max.height() > 0); - - if (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn) - canScrollX = true; - if (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn) - canScrollY = true; - - if (qAbs(deltaPixel.x() / ppm.x()) < qAbs(deltaPixel.y() / ppm.y())) { - if (!canScrollY) - moveAborted = true; - } else { - if (!canScrollX) - moveAborted = true; - } - } - - if (moveAborted) { - setState(QScroller::Inactive); - moveStarted = false; - - } else if (moveStarted) { - setState(QScroller::Dragging); - - // subtract the dragStartDistance - deltaPixel = deltaPixel - deltaPixel * (sp->dragStartDistance / deltaPixel.manhattanLength()); - - if (deltaPixel != QPointF(0, 0)) { - // handleDrag updates lastPosition, lastTimestamp and velocity - handleDrag(pressPosition + deltaPixel, timestamp); - } - } - return moveStarted; -} - -bool QScrollerPrivate::moveWhileDragging(const QPointF &position, qint64 timestamp) -{ - // handleDrag updates lastPosition, lastTimestamp and velocity - handleDrag(position, timestamp); - return true; -} - -void QScrollerPrivate::timerEventWhileDragging() -{ - if (dragDistance != QPointF(0, 0)) { - qScrollerDebug() << "QScroller::timerEventWhileDragging() -- dragDistance:" << dragDistance; - - setContentPositionHelperDragging(-dragDistance); - dragDistance = QPointF(0, 0); - } -} - -bool QScrollerPrivate::releaseWhileDragging(const QPointF &position, qint64 timestamp) -{ - Q_Q(QScroller); - const QScrollerPropertiesPrivate *sp = properties.d.data(); - - // handleDrag updates lastPosition, lastTimestamp and velocity - handleDrag(position, timestamp); - - // check if we moved at all - this can happen if you stop a running - // scroller with a press and release shortly afterwards - QPointF deltaPixel = position - pressPosition; - if (((deltaPixel / q->pixelPerMeter()).manhattanLength()) > sp->dragStartDistance) { - - // handle accelerating flicks - if ((oldVelocity != QPointF(0, 0)) && sp->acceleratingFlickMaximumTime && - ((timestamp - pressTimestamp) < qint64(sp->acceleratingFlickMaximumTime * 1000))) { - - // - determine if the direction was changed - int signX = 0, signY = 0; - if (releaseVelocity.x()) - signX = (releaseVelocity.x() > 0) == (oldVelocity.x() > 0) ? 1 : -1; - if (releaseVelocity.y()) - signY = (releaseVelocity.y() > 0) == (oldVelocity.y() > 0) ? 1 : -1; - - if (signX > 0) - releaseVelocity.setX(qBound(-sp->maximumVelocity, - oldVelocity.x() * sp->acceleratingFlickSpeedupFactor, - sp->maximumVelocity)); - if (signY > 0) - releaseVelocity.setY(qBound(-sp->maximumVelocity, - oldVelocity.y() * sp->acceleratingFlickSpeedupFactor, - sp->maximumVelocity)); - } - } - - QPointF ppm = q->pixelPerMeter(); - createScrollingSegments(releaseVelocity.x(), contentPosition.x() + overshootPosition.x(), ppm.x(), Qt::Horizontal); - createScrollingSegments(releaseVelocity.y(), contentPosition.y() + overshootPosition.y(), ppm.y(), Qt::Vertical); - - qScrollerDebug() << "QScroller::releaseWhileDragging() -- velocity:" << releaseVelocity << "-- minimum velocity:" << sp->minimumVelocity << "overshoot" << overshootPosition; - - if (xSegments.isEmpty() && ySegments.isEmpty()) - setState(QScroller::Inactive); - else - setState(QScroller::Scrolling); - - return true; -} - -void QScrollerPrivate::timerEventWhileScrolling() -{ - qScrollerDebug() << "QScroller::timerEventWhileScrolling()"; - - setContentPositionHelperScrolling(); - if (xSegments.isEmpty() && ySegments.isEmpty()) - setState(QScroller::Inactive); -} - -bool QScrollerPrivate::pressWhileScrolling(const QPointF &position, qint64 timestamp) -{ - Q_Q(QScroller); - - if ((q->velocity() <= properties.d->maximumClickThroughVelocity) && - (overshootPosition == QPointF(0.0, 0.0))) { - setState(QScroller::Inactive); - return false; - } else { - lastPosition = pressPosition = position; - lastTimestamp = pressTimestamp = timestamp; - setState(QScroller::Pressed); - setState(QScroller::Dragging); - return true; - } -} - -/*! \internal - This function handles all state changes of the scroller. -*/ -void QScrollerPrivate::setState(QScroller::State newstate) -{ - Q_Q(QScroller); - bool sendLastScroll = false; - - if (state == newstate) - return; - - qScrollerDebug() << q << "QScroller::setState(" << stateName(newstate) << ")"; - - switch (newstate) { - case QScroller::Inactive: -#ifndef QT_NO_ANIMATION - scrollTimer->stop(); -#endif - - // send the last scroll event (but only after the current state change was finished) - if (!firstScroll) - sendLastScroll = true; - - releaseVelocity = QPointF(0, 0); - break; - - case QScroller::Pressed: -#ifndef QT_NO_ANIMATION - scrollTimer->stop(); -#endif - - oldVelocity = releaseVelocity; - releaseVelocity = QPointF(0, 0); - break; - - case QScroller::Dragging: - dragDistance = QPointF(0, 0); -#ifndef QT_NO_ANIMATION - if (state == QScroller::Pressed) - scrollTimer->start(); -#endif - break; - - case QScroller::Scrolling: -#ifndef QT_NO_ANIMATION - scrollTimer->start(); -#endif - break; - } - - qSwap(state, newstate); - - if (sendLastScroll) { - QScrollEvent se(contentPosition, overshootPosition, QScrollEvent::ScrollFinished); - sendEvent(target, &se); - firstScroll = true; - } - if (state == QScroller::Dragging || state == QScroller::Scrolling) - qt_activeScrollers()->insert(q); - else - qt_activeScrollers()->remove(q); - emit q->stateChanged(state); -} - - -/*! \internal - Helps when setting the content position. - It will try to move the content by the requested delta but stop in case - when we are coming back from an overshoot or a scrollTo. - It will also indicate a new overshooting condition by the overshootX and oversthootY flags. - - In this cases it will reset the velocity variables and other flags. - - Also keeps track of the current over-shooting value in overshootPosition. - - \a deltaPos is the amount of pixels the current content position should be moved -*/ -void QScrollerPrivate::setContentPositionHelperDragging(const QPointF &deltaPos) -{ - const QScrollerPropertiesPrivate *sp = properties.d.data(); - - if (sp->overshootDragResistanceFactor) - overshootPosition /= sp->overshootDragResistanceFactor; - - QPointF oldPos = contentPosition + overshootPosition; - QPointF newPos = oldPos + deltaPos; - - qScrollerDebug() << "QScroller::setContentPositionHelperDragging(" << deltaPos << " [pix])"; - qScrollerDebug() << " --> overshoot:" << overshootPosition << "- old pos:" << oldPos << "- new pos:" << newPos; - - QPointF oldClampedPos = clampToRect(oldPos, contentPosRange); - QPointF newClampedPos = clampToRect(newPos, contentPosRange); - - // --- handle overshooting and stop if the coordinate is going back inside the normal area - bool alwaysOvershootX = (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn); - bool alwaysOvershootY = (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn); - bool noOvershootX = (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOff) || - ((state == QScroller::Dragging) && !sp->overshootDragResistanceFactor) || - !sp->overshootDragDistanceFactor; - bool noOvershootY = (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOff) || - ((state == QScroller::Dragging) && !sp->overshootDragResistanceFactor) || - !sp->overshootDragDistanceFactor; - bool canOvershootX = !noOvershootX && (alwaysOvershootX || contentPosRange.width()); - bool canOvershootY = !noOvershootY && (alwaysOvershootY || contentPosRange.height()); - - qreal oldOvershootX = (canOvershootX) ? oldPos.x() - oldClampedPos.x() : 0; - qreal oldOvershootY = (canOvershootY) ? oldPos.y() - oldClampedPos.y() : 0; - - qreal newOvershootX = (canOvershootX) ? newPos.x() - newClampedPos.x() : 0; - qreal newOvershootY = (canOvershootY) ? newPos.y() - newClampedPos.y() : 0; - - qreal maxOvershootX = viewportSize.width() * sp->overshootDragDistanceFactor; - qreal maxOvershootY = viewportSize.height() * sp->overshootDragDistanceFactor; - - qScrollerDebug() << " --> noOs:" << noOvershootX << "drf:" << sp->overshootDragResistanceFactor << "mdf:" << sp->overshootScrollDistanceFactor << "ossP:"<<sp->hOvershootPolicy; - qScrollerDebug() << " --> canOS:" << canOvershootX << "newOS:" << newOvershootX << "maxOS:" << maxOvershootX; - - if (sp->overshootDragResistanceFactor) { - oldOvershootX *= sp->overshootDragResistanceFactor; - oldOvershootY *= sp->overshootDragResistanceFactor; - newOvershootX *= sp->overshootDragResistanceFactor; - newOvershootY *= sp->overshootDragResistanceFactor; - } - - // -- stop at the maximum overshoot distance - - newOvershootX = qBound(-maxOvershootX, newOvershootX, maxOvershootX); - newOvershootY = qBound(-maxOvershootY, newOvershootY, maxOvershootY); - - overshootPosition.setX(newOvershootX); - overshootPosition.setY(newOvershootY); - contentPosition = newClampedPos; - - QScrollEvent se(contentPosition, overshootPosition, firstScroll ? QScrollEvent::ScrollStarted : QScrollEvent::ScrollUpdated); - sendEvent(target, &se); - firstScroll = false; - - qScrollerDebug() << " --> new position:" << newClampedPos << "- new overshoot:" << overshootPosition << - "- overshoot x/y?:" << overshootPosition; -} - - -qreal QScrollerPrivate::nextSegmentPosition(QQueue<ScrollSegment> &segments, qint64 now, qreal oldPos) -{ - qreal pos = oldPos; - - // check the X segments for new positions - while (!segments.isEmpty()) { - const ScrollSegment s = segments.head(); - - if ((s.startTime + s.deltaTime * s.stopProgress) <= now) { - segments.dequeue(); - pos = s.stopPos; - } else if (s.startTime <= now) { - qreal progress = qreal(now - s.startTime) / qreal(s.deltaTime); - pos = s.startPos + s.deltaPos * s.curve.valueForProgress(progress); - if (s.deltaPos > 0 ? pos > s.stopPos : pos < s.stopPos) { - segments.dequeue(); - pos = s.stopPos; - } else { - break; - } - } else { - break; - } - } - return pos; -} - -void QScrollerPrivate::setContentPositionHelperScrolling() -{ - qint64 now = monotonicTimer.elapsed(); - QPointF newPos = contentPosition + overshootPosition; - - newPos.setX(nextSegmentPosition(xSegments, now, newPos.x())); - newPos.setY(nextSegmentPosition(ySegments, now, newPos.y())); - - // -- set the position and handle overshoot - qScrollerDebug() << "QScroller::setContentPositionHelperScrolling()"; - qScrollerDebug() << " --> overshoot:" << overshootPosition << "- new pos:" << newPos; - - QPointF newClampedPos = clampToRect(newPos, contentPosRange); - - overshootPosition = newPos - newClampedPos; - contentPosition = newClampedPos; - - QScrollEvent se(contentPosition, overshootPosition, firstScroll ? QScrollEvent::ScrollStarted : QScrollEvent::ScrollUpdated); - sendEvent(target, &se); - firstScroll = false; - - qScrollerDebug() << " --> new position:" << newClampedPos << "- new overshoot:" << overshootPosition; -} - -/*! \internal - Returns the next snap point in direction. - If \a direction >0 it will return the next snap point that is larger than the current position. - If \a direction <0 it will return the next snap point that is smaller than the current position. - If \a direction ==0 it will return the nearest snap point (or the current position if we are already - on a snap point. - Returns the nearest snap position or NaN if no such point could be found. - */ -qreal QScrollerPrivate::nextSnapPos(qreal p, int dir, Qt::Orientation orientation) -{ - qreal bestSnapPos = Q_QNAN; - qreal bestSnapPosDist = Q_INFINITY; - - qreal minPos; - qreal maxPos; - - if (orientation == Qt::Horizontal) { - minPos = contentPosRange.left(); - maxPos = contentPosRange.right(); - } else { - minPos = contentPosRange.top(); - maxPos = contentPosRange.bottom(); - } - - if (orientation == Qt::Horizontal) { - // the snap points in the list - foreach (qreal snapPos, snapPositionsX) { - qreal snapPosDist = snapPos - p; - if ((dir > 0 && snapPosDist < 0) || - (dir < 0 && snapPosDist > 0)) - continue; // wrong direction - if (snapPos < minPos || snapPos > maxPos ) - continue; // invalid - - if (qIsNaN(bestSnapPos) || - qAbs(snapPosDist) < bestSnapPosDist ) { - bestSnapPos = snapPos; - bestSnapPosDist = qAbs(snapPosDist); - } - } - - // the snap point interval - if (snapIntervalX > 0.0) { - qreal first = minPos + snapFirstX; - qreal snapPos; - if (dir > 0) - snapPos = qCeil((p - first) / snapIntervalX) * snapIntervalX + first; - else if (dir < 0) - snapPos = qFloor((p - first) / snapIntervalX) * snapIntervalX + first; - else if (p <= first) - snapPos = first; - else - { - qreal last = qFloor((maxPos - first) / snapIntervalX) * snapIntervalX + first; - if (p >= last) - snapPos = last; - else - snapPos = qRound((p - first) / snapIntervalX) * snapIntervalX + first; - } - - if (snapPos >= first && snapPos <= maxPos ) { - qreal snapPosDist = snapPos - p; - - if (qIsNaN(bestSnapPos) || - qAbs(snapPosDist) < bestSnapPosDist ) { - bestSnapPos = snapPos; - bestSnapPosDist = qAbs(snapPosDist); - } - } - } - - } else { // (orientation == Qt::Vertical) - // the snap points in the list - foreach (qreal snapPos, snapPositionsY) { - qreal snapPosDist = snapPos - p; - if ((dir > 0 && snapPosDist < 0) || - (dir < 0 && snapPosDist > 0)) - continue; // wrong direction - if (snapPos < minPos || snapPos > maxPos ) - continue; // invalid - - if (qIsNaN(bestSnapPos) || - qAbs(snapPosDist) < bestSnapPosDist) { - bestSnapPos = snapPos; - bestSnapPosDist = qAbs(snapPosDist); - } - } - - // the snap point interval - if (snapIntervalY > 0.0) { - qreal first = minPos + snapFirstY; - qreal snapPos; - if (dir > 0) - snapPos = qCeil((p - first) / snapIntervalY) * snapIntervalY + first; - else if (dir < 0) - snapPos = qFloor((p - first) / snapIntervalY) * snapIntervalY + first; - else if (p <= first) - snapPos = first; - else - { - qreal last = qFloor((maxPos - first) / snapIntervalY) * snapIntervalY + first; - if (p >= last) - snapPos = last; - else - snapPos = qRound((p - first) / snapIntervalY) * snapIntervalY + first; - } - - if (snapPos >= first && snapPos <= maxPos ) { - qreal snapPosDist = snapPos - p; - - if (qIsNaN(bestSnapPos) || - qAbs(snapPosDist) < bestSnapPosDist) { - bestSnapPos = snapPos; - bestSnapPosDist = qAbs(snapPosDist); - } - } - } - } - - return bestSnapPos; -} - -/*! - \enum QScroller::State - - This enum contains the different QScroller states. - - \value Inactive The scroller is not scrolling and nothing is pressed. - \value Pressed A touch event was received or the mouse button was pressed but the scroll area is currently not dragged. - \value Dragging The scroll area is currently following the touch point or mouse. - \value Scrolling The scroll area is moving on it's own. -*/ - -/*! - \enum QScroller::ScrollerGestureType - - This enum contains the different gesture types that are supported by the QScroller gesture recognizer. - - \value TouchGesture The gesture recognizer will only trigger on touch - events. Specifically it will react on single touch points when using a - touch screen and dual touch points when using a touchpad. - \value LeftMouseButtonGesture The gesture recognizer will only trigger on left mouse button events. - \value MiddleMouseButtonGesture The gesture recognizer will only trigger on middle mouse button events. - \value RightMouseButtonGesture The gesture recognizer will only trigger on right mouse button events. -*/ - -/*! - \enum QScroller::Input - - This enum contains an input device agnostic view of input events that are relevant for QScroller. - - \value InputPress The user pressed the input device (e.g. QEvent::MouseButtonPress, - QEvent::GraphicsSceneMousePress, QEvent::TouchBegin) - - \value InputMove The user moved the input device (e.g. QEvent::MouseMove, - QEvent::GraphicsSceneMouseMove, QEvent::TouchUpdate) - - \value InputRelease The user released the input device (e.g. QEvent::MouseButtonRelease, - QEvent::GraphicsSceneMouseRelease, QEvent::TouchEnd) - -*/ - -QT_END_NAMESPACE diff --git a/src/gui/util/qscroller.h b/src/gui/util/qscroller.h deleted file mode 100644 index 16a7f2e..0000000 --- a/src/gui/util/qscroller.h +++ /dev/null @@ -1,155 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCROLLER_H -#define QSCROLLER_H - -#include <QtCore/QObject> -#include <QtCore/QPointF> -#include <QtGui/QScrollerProperties> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QWidget; -class QScrollerPrivate; -class QScrollerProperties; -#ifndef QT_NO_GESTURES -class QFlickGestureRecognizer; -class QMouseFlickGestureRecognizer; -#endif - -class Q_GUI_EXPORT QScroller : public QObject -{ - Q_OBJECT - Q_PROPERTY(State state READ state NOTIFY stateChanged) - Q_PROPERTY(QScrollerProperties scrollerProperties READ scrollerProperties WRITE setScrollerProperties NOTIFY scrollerPropertiesChanged) - Q_ENUMS(State) - -public: - enum State - { - Inactive, - Pressed, - Dragging, - Scrolling - }; - - enum ScrollerGestureType - { - TouchGesture, - LeftMouseButtonGesture, - RightMouseButtonGesture, - MiddleMouseButtonGesture - }; - - enum Input - { - InputPress = 1, - InputMove, - InputRelease - }; - - static bool hasScroller(QObject *target); - - static QScroller *scroller(QObject *target); - static const QScroller *scroller(const QObject *target); - -#ifndef QT_NO_GESTURES - static Qt::GestureType grabGesture(QObject *target, ScrollerGestureType gestureType = TouchGesture); - static Qt::GestureType grabbedGesture(QObject *target); - static void ungrabGesture(QObject *target); -#endif - - static QList<QScroller *> activeScrollers(); - - QObject *target() const; - - State state() const; - - bool handleInput(Input input, const QPointF &position, qint64 timestamp = 0); - - void stop(); - QPointF velocity() const; - QPointF finalPosition() const; - QPointF pixelPerMeter() const; - - QScrollerProperties scrollerProperties() const; - - void setSnapPositionsX( const QList<qreal> &positions ); - void setSnapPositionsX( qreal first, qreal interval ); - void setSnapPositionsY( const QList<qreal> &positions ); - void setSnapPositionsY( qreal first, qreal interval ); - -public Q_SLOTS: - void setScrollerProperties(const QScrollerProperties &prop); - void scrollTo(const QPointF &pos); - void scrollTo(const QPointF &pos, int scrollTime); - void ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin); - void ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin, int scrollTime); - void resendPrepareEvent(); - -Q_SIGNALS: - void stateChanged(QScroller::State newstate); - void scrollerPropertiesChanged(const QScrollerProperties &); - -private: - QScrollerPrivate *d_ptr; - - QScroller(QObject *target); - virtual ~QScroller(); - - Q_DISABLE_COPY(QScroller) - Q_DECLARE_PRIVATE(QScroller) - -#ifndef QT_NO_GESTURES - friend class QFlickGestureRecognizer; -#endif -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSCROLLER_H diff --git a/src/gui/util/qscroller_p.h b/src/gui/util/qscroller_p.h deleted file mode 100644 index b4f4db5..0000000 --- a/src/gui/util/qscroller_p.h +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCROLLER_P_H -#define QSCROLLER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QObject> -#include <QPointer> -#include <QQueue> -#include <QSet> -#include <QEasingCurve> -#include <QElapsedTimer> -#include <QSizeF> -#include <QPointF> -#include <QRectF> -#include <qscroller.h> -#include <qscrollerproperties.h> -#include <private/qscrollerproperties_p.h> -#include <QAbstractAnimation> - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_GESTURES -class QFlickGestureRecognizer; -#endif - -#ifndef QT_NO_ANIMATION -class QScrollTimer; -#endif -class QScrollerPrivate : public QObject -{ - Q_OBJECT - Q_DECLARE_PUBLIC(QScroller) - -public: - QScrollerPrivate(QScroller *q, QObject *target); - void init(); - - void sendEvent(QObject *o, QEvent *e); - - void setState(QScroller::State s); - - enum ScrollType { - ScrollTypeFlick = 0, - ScrollTypeScrollTo, - ScrollTypeOvershoot - }; - - struct ScrollSegment { - qint64 startTime; - qint64 deltaTime; - qreal startPos; - qreal deltaPos; - QEasingCurve curve; - qreal stopProgress; // whatever is.. - qreal stopPos; // ..reached first - ScrollType type; - }; - - bool pressWhileInactive(const QPointF &position, qint64 timestamp); - bool moveWhilePressed(const QPointF &position, qint64 timestamp); - bool releaseWhilePressed(const QPointF &position, qint64 timestamp); - bool moveWhileDragging(const QPointF &position, qint64 timestamp); - bool releaseWhileDragging(const QPointF &position, qint64 timestamp); - bool pressWhileScrolling(const QPointF &position, qint64 timestamp); - - void timerTick(); - void timerEventWhileDragging(); - void timerEventWhileScrolling(); - - bool prepareScrolling(const QPointF &position); - void handleDrag(const QPointF &position, qint64 timestamp); - - QPointF realDpi(int screen); - QPointF dpi() const; - void setDpi(const QPointF &dpi); - void setDpiFromWidget(QWidget *widget); - - void updateVelocity(const QPointF &deltaPixelRaw, qint64 deltaTime); - void pushSegment(ScrollType type, qreal deltaTime, qreal stopProgress, qreal startPos, qreal deltaPos, qreal stopPos, QEasingCurve::Type curve, Qt::Orientation orientation); - void recalcScrollingSegments(bool forceRecalc = false); - qreal scrollingSegmentsEndPos(Qt::Orientation orientation) const; - bool scrollingSegmentsValid(Qt::Orientation orientation); - void createScrollToSegments(qreal v, qreal deltaTime, qreal endPos, Qt::Orientation orientation, ScrollType type); - void createScrollingSegments(qreal v, qreal startPos, qreal ppm, Qt::Orientation orientation); - - void setContentPositionHelperDragging(const QPointF &deltaPos); - void setContentPositionHelperScrolling(); - - qreal nextSnapPos(qreal p, int dir, Qt::Orientation orientation); - static qreal nextSegmentPosition(QQueue<ScrollSegment> &segments, qint64 now, qreal oldPos); - - inline int frameRateSkip() const { return properties.d.data()->frameRate; } - - static const char *stateName(QScroller::State state); - static const char *inputName(QScroller::Input input); - -public slots: - void targetDestroyed(); - -public: - // non static - QObject *target; - QScrollerProperties properties; -#ifndef QT_NO_GESTURES - QFlickGestureRecognizer *recognizer; - Qt::GestureType recognizerType; -#endif - - // scroller state: - - // QPointer<QObject> scrollTarget; - QSizeF viewportSize; - QRectF contentPosRange; - QPointF contentPosition; - QPointF overshootPosition; // the number of pixels we are overshooting (before overshootDragResistanceFactor) - - // state - - bool enabled; - QScroller::State state; - bool firstScroll; // true if we haven't already send a scroll event - - QPointF oldVelocity; // the release velocity of the last drag - - QPointF pressPosition; - QPointF lastPosition; - qint64 pressTimestamp; - qint64 lastTimestamp; - - QPointF dragDistance; // the distance we should move during the next drag timer event - - QQueue<ScrollSegment> xSegments; - QQueue<ScrollSegment> ySegments; - - // snap positions - QList<qreal> snapPositionsX; - qreal snapFirstX; - qreal snapIntervalX; - QList<qreal> snapPositionsY; - qreal snapFirstY; - qreal snapIntervalY; - - QPointF pixelPerMeter; - - QElapsedTimer monotonicTimer; - - QPointF releaseVelocity; // the starting velocity of the scrolling state -#ifndef QT_NO_ANIMATION - QScrollTimer *scrollTimer; -#endif - - QScroller *q_ptr; -}; - - -QT_END_NAMESPACE - -#endif // QSCROLLER_P_H - diff --git a/src/gui/util/qscrollerproperties.cpp b/src/gui/util/qscrollerproperties.cpp deleted file mode 100644 index 5e2459a..0000000 --- a/src/gui/util/qscrollerproperties.cpp +++ /dev/null @@ -1,393 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QPointer> -#include <QObject> -#include <QtCore/qmath.h> -#ifdef Q_WS_WIN -# include <QLibrary> -#endif - -#include "qscrollerproperties.h" -#include "private/qscrollerproperties_p.h" - -QT_BEGIN_NAMESPACE - -static QScrollerPropertiesPrivate *userDefaults = 0; -static QScrollerPropertiesPrivate *systemDefaults = 0; - -QScrollerPropertiesPrivate *QScrollerPropertiesPrivate::defaults() -{ - if (!systemDefaults) { - QScrollerPropertiesPrivate spp; - spp.mousePressEventDelay = qreal(0.25); - spp.dragStartDistance = qreal(5.0 / 1000); - spp.dragVelocitySmoothingFactor = qreal(0.8); - spp.axisLockThreshold = qreal(0); - spp.scrollingCurve.setType(QEasingCurve::OutQuad); - spp.decelerationFactor = qreal(0.125); - spp.minimumVelocity = qreal(50.0 / 1000); - spp.maximumVelocity = qreal(500.0 / 1000); - spp.maximumClickThroughVelocity = qreal(66.5 / 1000); - spp.acceleratingFlickMaximumTime = qreal(1.25); - spp.acceleratingFlickSpeedupFactor = qreal(3.0); - spp.snapPositionRatio = qreal(0.5); - spp.snapTime = qreal(0.3); - spp.overshootDragResistanceFactor = qreal(0.5); - spp.overshootDragDistanceFactor = qreal(1); - spp.overshootScrollDistanceFactor = qreal(0.5); - spp.overshootScrollTime = qreal(0.7); -# ifdef Q_WS_WIN - if (QLibrary::resolve(QLatin1String("UxTheme"), "BeginPanningFeedback")) - spp.overshootScrollTime = qreal(0.35); -# endif - spp.hOvershootPolicy = QScrollerProperties::OvershootWhenScrollable; - spp.vOvershootPolicy = QScrollerProperties::OvershootWhenScrollable; - spp.frameRate = QScrollerProperties::Standard; - - systemDefaults = new QScrollerPropertiesPrivate(spp); - } - return new QScrollerPropertiesPrivate(userDefaults ? *userDefaults : *systemDefaults); -} - -/*! - \class QScrollerProperties - \brief The QScrollerProperties class stores the settings for a QScroller. - \since 4.8 - - The QScrollerProperties class stores the parameters used by QScroller. - - The default settings are platform dependent so that Qt emulates the - platform behaviour for kinetic scrolling. - - As a convention the QScrollerProperties are in physical units (meter, - seconds) and are converted by QScroller using the current DPI. - - \sa QScroller -*/ - -/*! - Constructs new scroller properties. -*/ -QScrollerProperties::QScrollerProperties() - : d(QScrollerPropertiesPrivate::defaults()) -{ -} - -/*! - Constructs a copy of \a sp. -*/ -QScrollerProperties::QScrollerProperties(const QScrollerProperties &sp) - : d(new QScrollerPropertiesPrivate(*sp.d)) -{ -} - -/*! - Assigns \a sp to these scroller properties and returns a reference to these scroller properties. -*/ -QScrollerProperties &QScrollerProperties::operator=(const QScrollerProperties &sp) -{ - *d.data() = *sp.d.data(); - return *this; -} - -/*! - Destroys the scroller properties. -*/ -QScrollerProperties::~QScrollerProperties() -{ -} - -/*! - Returns true if these scroller properties are equal to \a sp; otherwise returns false. -*/ -bool QScrollerProperties::operator==(const QScrollerProperties &sp) const -{ - return *d.data() == *sp.d.data(); -} - -/*! - Returns true if these scroller properties are different from \a sp; otherwise returns false. -*/ -bool QScrollerProperties::operator!=(const QScrollerProperties &sp) const -{ - return !(*d.data() == *sp.d.data()); -} - -bool QScrollerPropertiesPrivate::operator==(const QScrollerPropertiesPrivate &p) const -{ - bool same = true; - same &= (mousePressEventDelay == p.mousePressEventDelay); - same &= (dragStartDistance == p.dragStartDistance); - same &= (dragVelocitySmoothingFactor == p.dragVelocitySmoothingFactor); - same &= (axisLockThreshold == p.axisLockThreshold); - same &= (scrollingCurve == p.scrollingCurve); - same &= (decelerationFactor == p.decelerationFactor); - same &= (minimumVelocity == p.minimumVelocity); - same &= (maximumVelocity == p.maximumVelocity); - same &= (maximumClickThroughVelocity == p.maximumClickThroughVelocity); - same &= (acceleratingFlickMaximumTime == p.acceleratingFlickMaximumTime); - same &= (acceleratingFlickSpeedupFactor == p.acceleratingFlickSpeedupFactor); - same &= (snapPositionRatio == p.snapPositionRatio); - same &= (snapTime == p.snapTime); - same &= (overshootDragResistanceFactor == p.overshootDragResistanceFactor); - same &= (overshootDragDistanceFactor == p.overshootDragDistanceFactor); - same &= (overshootScrollDistanceFactor == p.overshootScrollDistanceFactor); - same &= (overshootScrollTime == p.overshootScrollTime); - same &= (hOvershootPolicy == p.hOvershootPolicy); - same &= (vOvershootPolicy == p.vOvershootPolicy); - same &= (frameRate == p.frameRate); - return same; -} - -/*! - Sets the scroller properties for all new QScrollerProperties objects to \a sp. - - Use this function to override the platform default properties returned by the default - constructor. If you only want to change the scroller properties of a single scroller, use - QScroller::setScrollerProperties() - - \note Calling this function will not change the content of already existing - QScrollerProperties objects. - - \sa unsetDefaultScrollerProperties() -*/ -void QScrollerProperties::setDefaultScrollerProperties(const QScrollerProperties &sp) -{ - if (!userDefaults) - userDefaults = new QScrollerPropertiesPrivate(*sp.d); - else - *userDefaults = *sp.d; -} - -/*! - Sets the scroller properties returned by the default constructor back to the platform default - properties. - - \sa setDefaultScrollerProperties() -*/ -void QScrollerProperties::unsetDefaultScrollerProperties() -{ - delete userDefaults; - userDefaults = 0; -} - -/*! - Query the \a metric value of the scroller properties. - - \sa setScrollMetric(), ScrollMetric -*/ -QVariant QScrollerProperties::scrollMetric(ScrollMetric metric) const -{ - switch (metric) { - case MousePressEventDelay: return d->mousePressEventDelay; - case DragStartDistance: return d->dragStartDistance; - case DragVelocitySmoothingFactor: return d->dragVelocitySmoothingFactor; - case AxisLockThreshold: return d->axisLockThreshold; - case ScrollingCurve: return d->scrollingCurve; - case DecelerationFactor: return d->decelerationFactor; - case MinimumVelocity: return d->minimumVelocity; - case MaximumVelocity: return d->maximumVelocity; - case MaximumClickThroughVelocity: return d->maximumClickThroughVelocity; - case AcceleratingFlickMaximumTime: return d->acceleratingFlickMaximumTime; - case AcceleratingFlickSpeedupFactor:return d->acceleratingFlickSpeedupFactor; - case SnapPositionRatio: return d->snapPositionRatio; - case SnapTime: return d->snapTime; - case OvershootDragResistanceFactor: return d->overshootDragResistanceFactor; - case OvershootDragDistanceFactor: return d->overshootDragDistanceFactor; - case OvershootScrollDistanceFactor: return d->overshootScrollDistanceFactor; - case OvershootScrollTime: return d->overshootScrollTime; - case HorizontalOvershootPolicy: return QVariant::fromValue(d->hOvershootPolicy); - case VerticalOvershootPolicy: return QVariant::fromValue(d->vOvershootPolicy); - case FrameRate: return QVariant::fromValue(d->frameRate); - case ScrollMetricCount: break; - } - return QVariant(); -} - -/*! - Set a specific value of the \a metric ScrollerMetric to \a value. - - \sa scrollMetric(), ScrollMetric -*/ -void QScrollerProperties::setScrollMetric(ScrollMetric metric, const QVariant &value) -{ - switch (metric) { - case MousePressEventDelay: d->mousePressEventDelay = value.toReal(); break; - case DragStartDistance: d->dragStartDistance = value.toReal(); break; - case DragVelocitySmoothingFactor: d->dragVelocitySmoothingFactor = qBound(qreal(0), value.toReal(), qreal(1)); break; - case AxisLockThreshold: d->axisLockThreshold = qBound(qreal(0), value.toReal(), qreal(1)); break; - case ScrollingCurve: d->scrollingCurve = value.toEasingCurve(); break; - case DecelerationFactor: d->decelerationFactor = value.toReal(); break; - case MinimumVelocity: d->minimumVelocity = value.toReal(); break; - case MaximumVelocity: d->maximumVelocity = value.toReal(); break; - case MaximumClickThroughVelocity: d->maximumClickThroughVelocity = value.toReal(); break; - case AcceleratingFlickMaximumTime: d->acceleratingFlickMaximumTime = value.toReal(); break; - case AcceleratingFlickSpeedupFactor:d->acceleratingFlickSpeedupFactor = value.toReal(); break; - case SnapPositionRatio: d->snapPositionRatio = qBound(qreal(0), value.toReal(), qreal(1)); break; - case SnapTime: d->snapTime = value.toReal(); break; - case OvershootDragResistanceFactor: d->overshootDragResistanceFactor = value.toReal(); break; - case OvershootDragDistanceFactor: d->overshootDragDistanceFactor = qBound(qreal(0), value.toReal(), qreal(1)); break; - case OvershootScrollDistanceFactor: d->overshootScrollDistanceFactor = qBound(qreal(0), value.toReal(), qreal(1)); break; - case OvershootScrollTime: d->overshootScrollTime = value.toReal(); break; - case HorizontalOvershootPolicy: d->hOvershootPolicy = value.value<QScrollerProperties::OvershootPolicy>(); break; - case VerticalOvershootPolicy: d->vOvershootPolicy = value.value<QScrollerProperties::OvershootPolicy>(); break; - case FrameRate: d->frameRate = value.value<QScrollerProperties::FrameRates>(); break; - case ScrollMetricCount: break; - } -} - -/*! - \enum QScrollerProperties::FrameRates - - This enum describes the available frame rates used while dragging or scrolling. - - \value Fps60 60 frames per second - \value Fps30 30 frames per second - \value Fps20 20 frames per second - \value Standard the default value is 60 frames per second (which corresponds to QAbstractAnimation). -*/ - -/*! - \enum QScrollerProperties::OvershootPolicy - - This enum describes the various modes of overshooting. - - \value OvershootWhenScrollable Overshooting is possible when the content is scrollable. This is the - default. - - \value OvershootAlwaysOff Overshooting is never enabled, even when the content is scrollable. - - \value OvershootAlwaysOn Overshooting is always enabled, even when the content is not - scrollable. -*/ - -/*! - \enum QScrollerProperties::ScrollMetric - - This enum contains the different scroll metric types. When not indicated otherwise the - setScrollMetric function expects a QVariant of type qreal. - - See the QScroller documentation for further details of the concepts behind the different - values. - - \value MousePressEventDelay This is the time a mouse press event is delayed when starting - a flick gesture in \c{[s]}. If the gesture is triggered within that time, no mouse press or - release is sent to the scrolled object. If it triggers after that delay the delayed - mouse press plus a faked release event at global postion \c{QPoint(-QWIDGETSIZE_MAX, - -QWIDGETSIZE_MAX)} is sent. If the gesture is canceled, then both the delayed mouse - press plus the real release event are delivered. - - \value DragStartDistance This is the minimum distance the touch or mouse point needs to be - moved before the flick gesture is triggered in \c m. - - \value DragVelocitySmoothingFactor A value that describes to which extent new drag velocities are - included in the final scrolling velocity. This value should be in the range between \c 0 and - \c 1. The lower the value, the more smoothing is applied to the dragging velocity. - - \value AxisLockThreshold Restricts the movement to one axis if the movement is inside an angle - around the axis. The threshold must be in the range \c 0 to \c 1. - - \value ScrollingCurve The QEasingCurve used when decelerating the scrolling velocity after an - user initiated flick. Please note that this is the easing curve for the positions, \bold{not} - the velocity: the default is QEasingCurve::OutQuad, which results in a linear decrease in - velocity (1st derivative) and a constant deceleration (2nd derivative). - - \value DecelerationFactor This factor influences how long it takes the scroller to decelerate - to 0 velocity. The actual value depends on the chosen ScrollingCurve. For most - types the value should be in the range from \c 0.1 to \c 2.0 - - \value MinimumVelocity The minimum velocity that is needed after ending the touch or releasing - the mouse to start scrolling in \c{m/s}. - - \value MaximumVelocity This is the maximum velocity that can be reached in \c{m/s}. - - \value MaximumClickThroughVelocity This is the maximum allowed scroll speed for a click-through - in \c{m/s}. This means that a click on a currently (slowly) scrolling object will not only stop - the scrolling but the click event will also be delivered to the UI control. This is - useful when using exponential-type scrolling curves. - - \value AcceleratingFlickMaximumTime This is the maximum time in \c seconds that a flick gesture - can take to be recognized as an accelerating flick. If set to zero no such gesture is - detected. An "accelerating flick" is a flick gesture executed on an already scrolling object. - In such cases the scrolling speed is multiplied by AcceleratingFlickSpeedupFactor in order to - accelerate it. - - \value AcceleratingFlickSpeedupFactor The current speed is multiplied by this number if an - accelerating flick is detected. Should be \c{>= 1}. - - \value SnapPositionRatio This is the distance that the user must drag the area beween two snap - points in order to snap it to the next position. \c{0.33} means that the scroll must only - reach one third of the distance between two snap points to snap to the next one. The ratio must - be between \c 0 and \c 1. - - \value SnapTime This is the time factor for the scrolling curve. A lower value means that the - scrolling will take longer. The scrolling distance is independet of this value. - - \value OvershootDragResistanceFactor This value is the factor between the mouse dragging and - the actual scroll area movement (during overshoot). The factor must be between \c 0 and \c 1. - - \value OvershootDragDistanceFactor This is the maximum distance for overshoot movements while - dragging. The actual overshoot distance is calculated by multiplying this value with the - viewport size of the scrolled object. The factor must be between \c 0 and \c 1. - - \value OvershootScrollDistanceFactor This is the maximum distance for overshoot movements while - scrolling. The actual overshoot distance is calculated by multiplying this value with the - viewport size of the scrolled object. The factor must be between \c 0 and \c 1. - - \value OvershootScrollTime This is the time in \c seconds that is used to play the - complete overshoot animation. - - \value HorizontalOvershootPolicy This is the horizontal overshooting policy (see OvershootPolicy). - - \value VerticalOvershootPolicy This is the horizontal overshooting policy (see OvershootPolicy). - - \value FrameRate This is the frame rate which should be used while dragging or scrolling. - QScroller uses a QAbstractAnimation timer internally to sync all scrolling operations to other - animations that might be active at the same time. If the standard value of 60 frames per - second is too fast, it can be lowered with this setting, - while still being in-sync with QAbstractAnimation. Please note that only the values of the - FrameRates enum are allowed here. - - \value ScrollMetricCount This is always the last entry. -*/ - -QT_END_NAMESPACE diff --git a/src/gui/util/qscrollerproperties.h b/src/gui/util/qscrollerproperties.h deleted file mode 100644 index 46d1c2f..0000000 --- a/src/gui/util/qscrollerproperties.h +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCROLLERPROPERTIES_H -#define QSCROLLERPROPERTIES_H - -#include <QtCore/QScopedPointer> -#include <QtCore/QMetaType> -#include <QtCore/QVariant> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QScroller; -class QScrollerPrivate; -class QScrollerPropertiesPrivate; - -class Q_GUI_EXPORT QScrollerProperties -{ -public: - QScrollerProperties(); - QScrollerProperties(const QScrollerProperties &sp); - QScrollerProperties &operator=(const QScrollerProperties &sp); - virtual ~QScrollerProperties(); - - bool operator==(const QScrollerProperties &sp) const; - bool operator!=(const QScrollerProperties &sp) const; - - static void setDefaultScrollerProperties(const QScrollerProperties &sp); - static void unsetDefaultScrollerProperties(); - - enum OvershootPolicy - { - OvershootWhenScrollable, - OvershootAlwaysOff, - OvershootAlwaysOn - }; - - enum FrameRates { - Standard, - Fps60, - Fps30, - Fps20 - }; - - enum ScrollMetric - { - MousePressEventDelay, // qreal [s] - DragStartDistance, // qreal [m] - DragVelocitySmoothingFactor, // qreal [0..1/s] (complex calculation involving time) v = v_new* DASF + v_old * (1-DASF) - AxisLockThreshold, // qreal [0..1] atan(|min(dx,dy)|/|max(dx,dy)|) - - ScrollingCurve, // QEasingCurve - DecelerationFactor, // slope of the curve - - MinimumVelocity, // qreal [m/s] - MaximumVelocity, // qreal [m/s] - MaximumClickThroughVelocity, // qreal [m/s] - - AcceleratingFlickMaximumTime, // qreal [s] - AcceleratingFlickSpeedupFactor, // qreal [1..] - - SnapPositionRatio, // qreal [0..1] - SnapTime, // qreal [s] - - OvershootDragResistanceFactor, // qreal [0..1] - OvershootDragDistanceFactor, // qreal [0..1] - OvershootScrollDistanceFactor, // qreal [0..1] - OvershootScrollTime, // qreal [s] - - HorizontalOvershootPolicy, // enum OvershootPolicy - VerticalOvershootPolicy, // enum OvershootPolicy - FrameRate, // enum FrameRates - - ScrollMetricCount - }; - - QVariant scrollMetric(ScrollMetric metric) const; - void setScrollMetric(ScrollMetric metric, const QVariant &value); - -protected: - QScopedPointer<QScrollerPropertiesPrivate> d; - -private: - QScrollerProperties(QScrollerPropertiesPrivate &dd); - - friend class QScrollerPropertiesPrivate; - friend class QScroller; - friend class QScrollerPrivate; -}; - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(QScrollerProperties::OvershootPolicy) -Q_DECLARE_METATYPE(QScrollerProperties::FrameRates) - -QT_END_HEADER - -#endif // QSCROLLERPROPERTIES_H diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri index 2814a2d..f125f82 100644 --- a/src/gui/util/util.pri +++ b/src/gui/util/util.pri @@ -6,11 +6,6 @@ HEADERS += \ util/qcompleter_p.h \ util/qdesktopservices.h \ util/qsystemtrayicon_p.h \ - util/qscroller.h \ - util/qscroller_p.h \ - util/qscrollerproperties.h \ - util/qscrollerproperties_p.h \ - util/qflickgesture_p.h \ util/qundogroup.h \ util/qundostack.h \ util/qundostack_p.h \ @@ -20,9 +15,6 @@ SOURCES += \ util/qsystemtrayicon.cpp \ util/qcompleter.cpp \ util/qdesktopservices.cpp \ - util/qscroller.cpp \ - util/qscrollerproperties.cpp \ - util/qflickgesture.cpp \ util/qundogroup.cpp \ util/qundostack.cpp \ util/qundoview.cpp @@ -65,7 +57,3 @@ symbian { DEFINES += USE_SCHEMEHANDLER } } - -macx { - OBJECTIVE_SOURCES += util/qscroller_mac.mm -} diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 6081bc8..c9c937f 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -53,8 +53,6 @@ #include "qpainter.h" #include "qmargins.h" -#include <QDebug> - #include "qabstractscrollarea_p.h" #include <qwidget.h> @@ -64,10 +62,6 @@ #include <private/qt_mac_p.h> #include <private/qt_cocoa_helpers_mac_p.h> #endif -#ifdef Q_WS_WIN -# include <qlibrary.h> -# include <windows.h> -#endif QT_BEGIN_NAMESPACE @@ -301,14 +295,9 @@ void QAbstractScrollAreaPrivate::init() q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); layoutChildren(); #ifndef Q_WS_MAC -# ifndef QT_NO_GESTURES +#ifndef QT_NO_GESTURES viewport->grabGesture(Qt::PanGesture); -# endif #endif -#ifdef Q_WS_MAEMO_5 -# ifndef QT_NO_GESTURES - // viewport->grabGesture(Qt::TouchFlickGesture); -# endif #endif } @@ -563,11 +552,6 @@ void QAbstractScrollArea::setViewport(QWidget *widget) d->viewport->grabGesture(Qt::PanGesture); #endif #endif -#ifdef Q_WS_MAEMO_5 -#ifndef QT_NO_GESTURES -// d->viewport->grabGesture(Qt::TouchFlickGesture); -#endif -#endif d->layoutChildren(); if (isVisible()) d->viewport->show(); @@ -1002,66 +986,6 @@ bool QAbstractScrollArea::event(QEvent *e) return false; } #endif // QT_NO_GESTURES - case QEvent::ScrollPrepare: - { - QScrollPrepareEvent *se = static_cast<QScrollPrepareEvent *>(e); - if (d->canStartScrollingAt(se->startPos().toPoint())) { - QScrollBar *hBar = horizontalScrollBar(); - QScrollBar *vBar = verticalScrollBar(); - - se->setViewportSize(QSizeF(viewport()->size())); - se->setContentPosRange(QRectF(0, 0, hBar->maximum(), vBar->maximum())); - se->setContentPos(QPointF(hBar->value(), vBar->value())); - se->accept(); - return true; - } - return false; - } - case QEvent::Scroll: - { - QScrollEvent *se = static_cast<QScrollEvent *>(e); - - QScrollBar *hBar = horizontalScrollBar(); - QScrollBar *vBar = verticalScrollBar(); - hBar->setValue(se->contentPos().x()); - vBar->setValue(se->contentPos().y()); - -#ifdef Q_WS_WIN - typedef BOOL (*PtrBeginPanningFeedback)(HWND); - typedef BOOL (*PtrUpdatePanningFeedback)(HWND, LONG, LONG, BOOL); - typedef BOOL (*PtrEndPanningFeedback)(HWND, BOOL); - - static PtrBeginPanningFeedback ptrBeginPanningFeedback = 0; - static PtrUpdatePanningFeedback ptrUpdatePanningFeedback = 0; - static PtrEndPanningFeedback ptrEndPanningFeedback = 0; - - if (!ptrBeginPanningFeedback) - ptrBeginPanningFeedback = (PtrBeginPanningFeedback) QLibrary::resolve(QLatin1String("UxTheme"), "BeginPanningFeedback"); - if (!ptrUpdatePanningFeedback) - ptrUpdatePanningFeedback = (PtrUpdatePanningFeedback) QLibrary::resolve(QLatin1String("UxTheme"), "UpdatePanningFeedback"); - if (!ptrEndPanningFeedback) - ptrEndPanningFeedback = (PtrEndPanningFeedback) QLibrary::resolve(QLatin1String("UxTheme"), "EndPanningFeedback"); - - if (ptrBeginPanningFeedback && ptrUpdatePanningFeedback && ptrEndPanningFeedback) { - WId wid = window()->winId(); - - if (!se->overshootDistance().isNull() && d->overshoot.isNull()) - ptrBeginPanningFeedback(wid); - if (!se->overshootDistance().isNull()) - ptrUpdatePanningFeedback(wid, -se->overshootDistance().x(), -se->overshootDistance().y(), false); - if (se->overshootDistance().isNull() && !d->overshoot.isNull()) - ptrEndPanningFeedback(wid, true); - } else -#endif - { - QPoint delta = d->overshoot - se->overshootDistance().toPoint(); - if (!delta.isNull()) - viewport()->move(viewport()->pos() + delta); - } - d->overshoot = se->overshootDistance().toPoint(); - - return true; - } case QEvent::StyleChange: case QEvent::LayoutDirectionChange: case QEvent::ApplicationLayoutDirectionChange: @@ -1123,9 +1047,6 @@ bool QAbstractScrollArea::viewportEvent(QEvent *e) case QEvent::GestureOverride: return event(e); #endif - case QEvent::ScrollPrepare: - case QEvent::Scroll: - return event(e); default: break; } @@ -1382,32 +1303,6 @@ void QAbstractScrollArea::scrollContentsBy(int, int) viewport()->update(); } -bool QAbstractScrollAreaPrivate::canStartScrollingAt( const QPoint &startPos ) -{ - Q_Q(QAbstractScrollArea); - -#ifndef QT_NO_GRAPHICSVIEW - // don't start scrolling when a drag mode has been set. - // don't start scrolling on a movable item. - if (QGraphicsView *view = qobject_cast<QGraphicsView *>(q)) { - if (view->dragMode() != QGraphicsView::NoDrag) - return false; - - QGraphicsItem *childItem = view->itemAt(startPos); - - if (childItem && (childItem->flags() & QGraphicsItem::ItemIsMovable)) - return false; - } -#endif - - // don't start scrolling on a QAbstractSlider - if (qobject_cast<QAbstractSlider *>(q->viewport()->childAt(startPos))) { - return false; - } - - return true; -} - void QAbstractScrollAreaPrivate::_q_hslide(int x) { Q_Q(QAbstractScrollArea); diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h index 27ee19f..84a9b57 100644 --- a/src/gui/widgets/qabstractscrollarea_p.h +++ b/src/gui/widgets/qabstractscrollarea_p.h @@ -84,13 +84,11 @@ public: int left, top, right, bottom; // viewport margin int xoffset, yoffset; - QPoint overshoot; void init(); void layoutChildren(); // ### Fix for 4.4, talk to Bjoern E or Girish. virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {} - bool canStartScrollingAt( const QPoint &startPos ); void _q_hslide(int); void _q_vslide(int); diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index dc08bb6..bf36033 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -435,6 +435,8 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event) c += event->commitString().length() - qMin(-event->replacementStart(), event->replacementLength()); m_cursor += event->replacementStart(); + if (m_cursor < 0) + m_cursor = 0; // insert commit string if (event->replacementLength()) { @@ -447,7 +449,7 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event) cursorPositionChanged = true; } - m_cursor = qMin(c, m_text.length()); + m_cursor = qBound(0, c, m_text.length()); for (int i = 0; i < event->attributes().size(); ++i) { const QInputMethodEvent::Attribute &a = event->attributes().at(i); @@ -1593,7 +1595,7 @@ void QLineControl::processKeyEvent(QKeyEvent* event) } bool unknown = false; - bool visual = cursorMoveStyle() == QTextCursor::Visual; + bool visual = cursorMoveStyle() == Qt::VisualMoveStyle; if (false) { } diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 6f4d658..cca4bfa 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -160,8 +160,8 @@ public: int cursorWidth() const { return m_cursorWidth; } void setCursorWidth(int value) { m_cursorWidth = value; } - QTextCursor::MoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); } - void setCursorMoveStyle(QTextCursor::MoveStyle style) { m_textLayout.setCursorMoveStyle(style); } + Qt::CursorMoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); } + void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); } void moveCursor(int pos, bool mark = false); void cursorForward(bool mark, int steps) @@ -169,11 +169,11 @@ public: int c = m_cursor; if (steps > 0) { while (steps--) - c = cursorMoveStyle() == QTextCursor::Visual ? m_textLayout.rightCursorPosition(c) + c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.rightCursorPosition(c) : m_textLayout.nextCursorPosition(c); } else if (steps < 0) { while (steps++) - c = cursorMoveStyle() == QTextCursor::Visual ? m_textLayout.leftCursorPosition(c) + c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.leftCursorPosition(c) : m_textLayout.previousCursorPosition(c); } moveCursor(c, mark); diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 1d076f1..8a93c28 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1116,24 +1116,24 @@ void QLineEdit::setDragEnabled(bool b) \brief the movement style of cursor in this line edit \since 4.8 - When this property is set to QTextCursor::Visual, the line edit will use visual + When this property is set to Qt::VisualMoveStyle, the line edit will use visual movement style. Pressing the left arrow key will always cause the cursor to move left, regardless of the text's writing direction. The same behavior applies to right arrow key. - When the property is QTextCursor::Logical (the default), within a LTR text block, + When the property is Qt::LogicalMoveStyle (the default), within a LTR text block, increase cursor position when pressing left arrow key, decrease cursor position when pressing the right arrow key. If the text block is right to left, the opposite behavior applies. */ -QTextCursor::MoveStyle QLineEdit::cursorMoveStyle() const +Qt::CursorMoveStyle QLineEdit::cursorMoveStyle() const { Q_D(const QLineEdit); return d->control->cursorMoveStyle(); } -void QLineEdit::setCursorMoveStyle(QTextCursor::MoveStyle style) +void QLineEdit::setCursorMoveStyle(Qt::CursorMoveStyle style) { Q_D(QLineEdit); d->control->setCursorMoveStyle(style); diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h index 6c5e338..73d2289 100644 --- a/src/gui/widgets/qlineedit.h +++ b/src/gui/widgets/qlineedit.h @@ -85,6 +85,7 @@ class Q_GUI_EXPORT QLineEdit : public QWidget Q_PROPERTY(bool redoAvailable READ isRedoAvailable) Q_PROPERTY(bool acceptableInput READ hasAcceptableInput) Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText) + Q_PROPERTY(Qt::CursorMoveStyle cursorMoveStyle READ cursorMoveStyle WRITE setCursorMoveStyle) public: explicit QLineEdit(QWidget* parent=0); @@ -159,8 +160,8 @@ public: void setDragEnabled(bool b); bool dragEnabled() const; - void setCursorMoveStyle(QTextCursor::MoveStyle style); - QTextCursor::MoveStyle cursorMoveStyle() const; + void setCursorMoveStyle(Qt::CursorMoveStyle style); + Qt::CursorMoveStyle cursorMoveStyle() const; QString inputMask() const; void setInputMask(const QString &inputMask); diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index f214bcb..8f468c6 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -78,7 +78,6 @@ public: : layout(0), explicitIconSize(false), toolButtonStyle(Qt::ToolButtonIconOnly) #ifdef Q_WS_MAC , useHIToolBar(false) - , activateUnifiedToolbarAfterFullScreen(false) #endif #if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR) , hasOldCursor(false) , cursorAdjusted(false) @@ -90,7 +89,6 @@ public: Qt::ToolButtonStyle toolButtonStyle; #ifdef Q_WS_MAC bool useHIToolBar; - bool activateUnifiedToolbarAfterFullScreen; #endif void init(); QList<int> hoverSeparator; diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index ebabf2d..fbde3a9 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -1699,6 +1699,7 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow, QLayout *parentLay , gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow)) #endif //QT_NO_RUBBERBAND #ifdef Q_WS_MAC + , activateUnifiedToolbarAfterFullScreen(false) , blockVisiblityCheck(false) #endif { diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index 439d87d..14ec1fb 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -338,7 +338,6 @@ public: void removeFromMacToolbar(QToolBar *toolbar); void cleanUpMacToolbarItems(); void fixSizeInUnifiedToolbar(QToolBar *tb) const; - bool useHIToolBar; bool activateUnifiedToolbarAfterFullScreen; void syncUnifiedToolbarVisibility(); bool blockVisiblityCheck; diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 932b14f..a490286 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -82,6 +82,10 @@ # include <private/qt_cocoa_helpers_mac_p.h> #endif +#ifdef Q_WS_S60 +# include "private/qt_s60_p.h" +#endif + QT_BEGIN_NAMESPACE @@ -172,6 +176,14 @@ void QMenuPrivate::init() q->addAction(selectAction); q->addAction(cancelAction); #endif + +#ifdef Q_WS_S60 + if (S60->avkonComponentsSupportTransparency) { + bool noSystemBackground = q->testAttribute(Qt::WA_NoSystemBackground); + q->setAttribute(Qt::WA_TranslucentBackground); // also sets WA_NoSystemBackground + q->setAttribute(Qt::WA_NoSystemBackground, noSystemBackground); // restore system background attribute + } +#endif } int QMenuPrivate::scrollerHeight() const diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index da0a5bd..8e301a1 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -860,6 +860,8 @@ void QNetworkReplyImpl::abort() if (d->state != QNetworkReplyImplPrivate::Finished) { // call finished which will emit signals d->error(OperationCanceledError, tr("Operation canceled")); + if (d->state == QNetworkReplyImplPrivate::WaitingForSession) + d->state = QNetworkReplyImplPrivate::Working; d->finished(); } d->state = QNetworkReplyImplPrivate::Aborted; @@ -1019,10 +1021,6 @@ bool QNetworkReplyImplPrivate::migrateBackend() if (state == Finished || state == Aborted) return true; - // Backend does not support resuming download. - if (!backend->canResume()) - return false; - // Request has outgoing data, not migrating. if (outgoingData) return false; @@ -1031,6 +1029,10 @@ bool QNetworkReplyImplPrivate::migrateBackend() if (copyDevice) return true; + // Backend does not support resuming download. + if (!backend->canResume()) + return false; + state = QNetworkReplyImplPrivate::Reconnecting; if (backend) { diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index d174147..54cd898 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -385,8 +385,6 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() this, SLOT(configurationRemoved(QNetworkConfigurationPrivatePointer))); connect(engine, SIGNAL(configurationChanged(QNetworkConfigurationPrivatePointer)), this, SLOT(configurationChanged(QNetworkConfigurationPrivatePointer))); - - QMetaObject::invokeMethod(engine, "initialize"); } } @@ -410,8 +408,19 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() startPolling(); } - if (firstUpdate) + if (firstUpdate) { firstUpdate = false; + QList<QBearerEngine*> enginesToInitialize = sessionEngines; //shallow copy the list in case it is modified when we unlock mutex + Qt::ConnectionType connectionType; + if (QCoreApplicationPrivate::mainThread() == QThread::currentThread()) + connectionType = Qt::DirectConnection; + else + connectionType = Qt::BlockingQueuedConnection; + locker.unlock(); + foreach (QBearerEngine* engine, enginesToInitialize) { + QMetaObject::invokeMethod(engine, "initialize", connectionType); + } + } } void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate() @@ -479,7 +488,7 @@ void QNetworkConfigurationManagerPrivate::enablePolling() ++forcedPolling; if (forcedPolling == 1) - startPolling(); + QMetaObject::invokeMethod(this, "startPolling"); } void QNetworkConfigurationManagerPrivate::disablePolling() diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h index 02e00b9a..04cce20 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.h +++ b/src/network/bearer/qnetworkconfigmanager_p.h @@ -107,7 +107,7 @@ private Q_SLOTS: void pollEngines(); private: - void startPolling(); + Q_INVOKABLE void startPolling(); QTimer *pollTimer; private: diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp index c9797d5..0ce21f9 100644 --- a/src/network/kernel/qnetworkinterface_unix.cpp +++ b/src/network/kernel/qnetworkinterface_unix.cpp @@ -219,7 +219,7 @@ static QNetworkInterfacePrivate *findInterface(int socket, QList<QNetworkInterfa #ifdef SIOCGIFHWADDR // Get the HW address if (qt_safe_ioctl(socket, SIOCGIFHWADDR, &req) >= 0) { - uchar *addr = (uchar *)&req.ifr_addr; + uchar *addr = (uchar *)req.ifr_addr.sa_data; iface->hardwareAddress = iface->makeHwAddress(6, addr); } #endif diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 4666517..5316626 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -1908,7 +1908,7 @@ bool QAbstractSocket::waitForReadyRead(int msecs) if (state() != ConnectedState) return false; - } while (qt_timeout_value(msecs, stopWatch.elapsed()) > 0); + } while (msecs == -1 || qt_timeout_value(msecs, stopWatch.elapsed()) > 0); return false; } diff --git a/src/opengl/qgl_symbian.cpp b/src/opengl/qgl_symbian.cpp index bc65bcd..91904d0 100644 --- a/src/opengl/qgl_symbian.cpp +++ b/src/opengl/qgl_symbian.cpp @@ -49,6 +49,9 @@ #include <private/qpaintengine_opengl_p.h> #include <private/qwidget_p.h> // to access QWExtra #include <private/qnativeimagehandleprovider_p.h> +#include <private/qapplication_p.h> +#include <private/qgraphicssystem_p.h> +#include <private/qgraphicssystemex_symbian_p.h> #include "qgl_egl_p.h" #include "qpixmapdata_gl_p.h" #include "qgltexturepool_p.h" @@ -180,6 +183,15 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // almost same as d->ownsEglContext = true; d->eglContext->setApi(QEgl::OpenGL); + QGraphicsSystemEx *ex = QApplicationPrivate::graphicsSystem()->platformExtension(); + QSymbianGraphicsSystemEx *symex = static_cast<QSymbianGraphicsSystemEx*>(ex); + if (symex && !symex->hasBCM2727()) { + // Most likely we have hw support for multisampling + // so let's enable it. + d->glFormat.setSampleBuffers(1); + d->glFormat.setSamples(4); + } + // If the device is a widget with WA_TranslucentBackground set, make sure the glFormat // has the alpha channel option set: if (devType == QInternal::Widget) { @@ -229,20 +241,20 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // almost same as d->eglSurface = QEgl::createSurface(device(), d->eglContext->config()); - eglGetError(); // Clear error state first. + eglGetError(); // Clear error state first. #ifdef QGL_NO_PRESERVED_SWAP - eglSurfaceAttrib(QEgl::display(), d->eglSurface, - EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); + eglSurfaceAttrib(QEgl::display(), d->eglSurface, + EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); - if (eglGetError() != EGL_SUCCESS) - qWarning("QGLContext: could not enable destroyed swap behaviour"); + if (eglGetError() != EGL_SUCCESS) + qWarning("QGLContext: could not enable destroyed swap behaviour"); #else - eglSurfaceAttrib(QEgl::display(), d->eglSurface, - EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); + eglSurfaceAttrib(QEgl::display(), d->eglSurface, + EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); - if (eglGetError() != EGL_SUCCESS) - qWarning("QGLContext: could not enable preserved swap behaviour"); + if (eglGetError() != EGL_SUCCESS) + qWarning("QGLContext: could not enable preserved swap behaviour"); #endif setWindowCreated(true); diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp index 2724921..c11c4a8 100644 --- a/src/opengl/qglfunctions.cpp +++ b/src/opengl/qglfunctions.cpp @@ -211,19 +211,24 @@ QGLFunctions::QGLFunctions(const QGLContext *context) static int qt_gl_resolve_features() { #if defined(QT_OPENGL_ES_2) - return QGLFunctions::Multitexture | - QGLFunctions::Shaders | - QGLFunctions::Buffers | - QGLFunctions::Framebuffers | - QGLFunctions::BlendColor | - QGLFunctions::BlendEquation | - QGLFunctions::BlendEquationSeparate | - QGLFunctions::BlendFuncSeparate | - QGLFunctions::BlendSubtract | - QGLFunctions::CompressedTextures | - QGLFunctions::Multisample | - QGLFunctions::StencilSeparate | - QGLFunctions::NPOTTextures; + int features = QGLFunctions::Multitexture | + QGLFunctions::Shaders | + QGLFunctions::Buffers | + QGLFunctions::Framebuffers | + QGLFunctions::BlendColor | + QGLFunctions::BlendEquation | + QGLFunctions::BlendEquationSeparate | + QGLFunctions::BlendFuncSeparate | + QGLFunctions::BlendSubtract | + QGLFunctions::CompressedTextures | + QGLFunctions::Multisample | + QGLFunctions::StencilSeparate; + QGLExtensionMatcher extensions; + if (extensions.match("GL_OES_texture_npot")) + features |= QGLFunctions::NPOTTextures; + if (extensions.match("GL_IMG_texture_npot")) + features |= QGLFunctions::NPOTTextures; + return features; #elif defined(QT_OPENGL_ES) int features = QGLFunctions::Multitexture | QGLFunctions::Buffers | @@ -240,6 +245,8 @@ static int qt_gl_resolve_features() features |= QGLFunctions::BlendSubtract; if (extensions.match("GL_OES_texture_npot")) features |= QGLFunctions::NPOTTextures; + if (extensions.match("GL_IMG_texture_npot")) + features |= QGLFunctions::NPOTTextures; return features; #else int features = 0; diff --git a/src/opengl/qgraphicssystem_gl.cpp b/src/opengl/qgraphicssystem_gl.cpp index 01a2864..8530b52 100644 --- a/src/opengl/qgraphicssystem_gl.cpp +++ b/src/opengl/qgraphicssystem_gl.cpp @@ -104,11 +104,17 @@ QWindowSurface *QGLGraphicsSystem::createWindowSurface(QWidget *widget) const return new QGLWindowSurface(widget); } -#ifdef QGL_USE_TEXTURE_POOL -void QGLGraphicsSystem::releaseCachedResources() +#ifdef Q_OS_SYMBIAN +void QGLGraphicsSystem::releaseCachedGpuResources() { QGLTexturePool::instance()->hibernate(); } + +QGraphicsSystemEx* QGLGraphicsSystem::platformExtension() +{ + return this; +} #endif + QT_END_NAMESPACE diff --git a/src/opengl/qgraphicssystem_gl_p.h b/src/opengl/qgraphicssystem_gl_p.h index 6e8e9a8..c8387e4 100644 --- a/src/opengl/qgraphicssystem_gl_p.h +++ b/src/opengl/qgraphicssystem_gl_p.h @@ -55,11 +55,19 @@ #include "private/qgraphicssystem_p.h" +#ifdef Q_OS_SYMBIAN +#include "private/qgraphicssystemex_symbian_p.h" +#endif + #include <QMap> QT_BEGIN_NAMESPACE class Q_OPENGL_EXPORT QGLGraphicsSystem : public QGraphicsSystem +#ifdef Q_OS_SYMBIAN + , public QSymbianGraphicsSystemEx +#endif + { public: QGLGraphicsSystem(bool useX11GL); @@ -67,8 +75,9 @@ public: QPixmapData *createPixmapData(QPixmapData::PixelType type) const; QWindowSurface *createWindowSurface(QWidget *widget) const; -#ifdef QGL_USE_TEXTURE_POOL - void releaseCachedResources(); +#ifdef Q_OS_SYMBIAN + void releaseCachedGpuResources(); + QGraphicsSystemEx* platformExtension(); #endif private: bool m_useX11GL; diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp index 829996b..3fd5c28 100644 --- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp +++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp @@ -80,9 +80,15 @@ QWindowSurface *QVGGraphicsSystem::createWindowSurface(QWidget *widget) const return new QVGWindowSurface(widget); } -void QVGGraphicsSystem::releaseCachedResources() +#ifdef Q_OS_SYMBIAN +void QVGGraphicsSystem::releaseCachedGpuResources() { QVGImagePool::instance()->hibernate(); } +QGraphicsSystemEx *QVGGraphicsSystem::platformExtension() +{ + return this; +} +#endif QT_END_NAMESPACE diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h index 6f8f8dc..c9f1815 100644 --- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h +++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h @@ -55,9 +55,16 @@ #include <QtGui/private/qgraphicssystem_p.h> +#ifdef Q_OS_SYMBIAN +#include <QtGui/private/qgraphicssystemex_symbian_p.h> +#endif + QT_BEGIN_NAMESPACE class QVGGraphicsSystem : public QGraphicsSystem +#ifdef Q_OS_SYMBIAN + , public QSymbianGraphicsSystemEx +#endif { public: QVGGraphicsSystem(); @@ -65,7 +72,10 @@ public: QPixmapData *createPixmapData(QPixmapData::PixelType type) const; QWindowSurface *createWindowSurface(QWidget *widget) const; - void releaseCachedResources(); +#ifdef Q_OS_SYMBIAN + void releaseCachedGpuResources(); + QGraphicsSystemEx* platformExtension(); +#endif }; QT_END_NAMESPACE diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 7479d2f..2d0c201 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -7,9 +7,9 @@ unix:!symbian { SUBDIRS *= codecs } !contains(QT_CONFIG, no-gui): SUBDIRS *= imageformats iconengines -!embedded:!qpa:SUBDIRS *= graphicssystems +!embedded:!qpa:!contains(QT_CONFIG, no-gui):SUBDIRS *= graphicssystems embedded:SUBDIRS *= gfxdrivers decorations mousedrivers kbddrivers -!win32:!embedded:!mac:!symbian:SUBDIRS *= inputmethods +!win32:!embedded:!mac:!symbian:!contains(QT_CONFIG, no-gui):SUBDIRS *= inputmethods !symbian:!contains(QT_CONFIG, no-gui):SUBDIRS += accessible symbian:SUBDIRS += s60 contains(QT_CONFIG, phonon): SUBDIRS *= phonon diff --git a/src/tools/uic3/uic3.pro b/src/tools/uic3/uic3.pro index 5ad3c4d..54f7dc8 100644 --- a/src/tools/uic3/uic3.pro +++ b/src/tools/uic3/uic3.pro @@ -1,5 +1,6 @@ TEMPLATE = app CONFIG += console qt_no_compat_warning +win32-msvc*:CONFIG += no_batch # otherwise the wrong main.cpp may be picked up CONFIG -= app_bundle build_all:!build_pass { CONFIG -= build_all |