diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-06-15 07:37:43 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-06-15 07:37:43 (GMT) |
commit | 6100dd1ccda7fce60625e99ffb2a90dc62cb1486 (patch) | |
tree | 7de5d72c227a163c3d042d8c04b8551176e4460a /src/gui | |
parent | 7b7f3869b15cee6f6815e10d49dcb8209a415edd (diff) | |
parent | 3a54e5ead647a318641d9a2bcf75eda4b8859d1b (diff) | |
download | Qt-6100dd1ccda7fce60625e99ffb2a90dc62cb1486.zip Qt-6100dd1ccda7fce60625e99ffb2a90dc62cb1486.tar.gz Qt-6100dd1ccda7fce60625e99ffb2a90dc62cb1486.tar.bz2 |
Merge remote branch 'origin/master'
Conflicts:
src/gui/painting/qpainter.cpp
Diffstat (limited to 'src/gui')
71 files changed, 914 insertions, 226 deletions
diff --git a/src/gui/embedded/qwsmanager_qws.cpp b/src/gui/embedded/qwsmanager_qws.cpp index 79076c5..b0259b9 100644 --- a/src/gui/embedded/qwsmanager_qws.cpp +++ b/src/gui/embedded/qwsmanager_qws.cpp @@ -394,7 +394,7 @@ void QWSManagerPrivate::dirtyRegion(int decorationRegion, const QRegion &clip) { QTLWExtra *topextra = managed->d_func()->extra->topextra; - QWidgetBackingStore *bs = topextra->backingStore; + QWidgetBackingStore *bs = topextra->backingStore.data(); const bool pendingUpdateRequest = bs->isDirty(); if (decorationRegion == QDecoration::All) { diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index d1f6eb3..6867410 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1427,12 +1427,14 @@ QGraphicsItem::~QGraphicsItem() d_ptr->inDestructor = 1; d_ptr->removeExtraItemCache(); +#ifndef QT_NO_GESTURES if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) { QGraphicsObject *o = static_cast<QGraphicsObject *>(this); QGestureManager *manager = QGestureManager::instance(); foreach (Qt::GestureType type, d_ptr->gestureContext.keys()) manager->cleanupCachedGestures(o, type); } +#endif clearFocus(); @@ -5687,18 +5689,20 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect) return; } - // Find pixmap in cache, then remove to avoid deep copy when modifying.s + // Find pixmap in cache. QPixmap cachedPixmap; if (!QPixmapCache::find(cache->key, &cachedPixmap)) { update(rect); return; } - QPixmapCache::remove(cache->key); QRect scrollRect = (rect.isNull() ? boundingRect() : rect).toAlignedRect(); if (!scrollRect.intersects(cache->boundingRect)) return; // Nothing to scroll. + // Remove from cache to avoid deep copy when modifying. + QPixmapCache::remove(cache->key); + QRegion exposed; cachedPixmap.scroll(dx, dy, scrollRect.translated(-cache->boundingRect.topLeft()), &exposed); @@ -7569,6 +7573,7 @@ QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent QGraphicsItem::d_ptr->isObject = true; } +#ifndef QT_NO_GESTURES /*! Subscribes the graphics object to the given \a gesture with specific \a flags. @@ -7592,6 +7597,8 @@ void QGraphicsObject::ungrabGesture(Qt::GestureType gesture) if (QGraphicsItem::d_ptr->gestureContext.remove(gesture) && QGraphicsItem::d_ptr->scene) QGraphicsItem::d_ptr->scene->d_func()->ungrabGesture(this, gesture); } +#endif // QT_NO_GESTURES + /*! Updates the item's micro focus. This is slot for convenience. diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 9891af3..d7d5332 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -485,7 +485,9 @@ private: friend class QGraphicsSceneBspTreeIndexPrivate; friend class QGraphicsItemEffectSourcePrivate; friend class QGraphicsTransformPrivate; +#ifndef QT_NO_GESTURES friend class QGestureManager; +#endif friend class ::tst_QGraphicsItem; friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *); friend bool qt_closestItemFirst(const QGraphicsItem *, const QGraphicsItem *); @@ -572,8 +574,10 @@ public: using QObject::children; #endif +#ifndef QT_NO_GESTURES void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags()); void ungrabGesture(Qt::GestureType type); +#endif protected Q_SLOTS: void updateMicroFocus(); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index e812f29..bde6e7d 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -525,7 +525,9 @@ public: QGraphicsItem *focusScopeItem; Qt::InputMethodHints imHints; QGraphicsItem::PanelModality panelModality; +#ifndef QT_NO_GESTURES QMap<Qt::GestureType, Qt::GestureFlags> gestureContext; +#endif // Packed 32 bits quint32 acceptedMouseButtons : 5; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 22c3f92..7b0722e 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -699,6 +699,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) if (!selectionChanging && selectedItems.size() != oldSelectedItemsSize) emit q->selectionChanged(); +#ifndef QT_NO_GESTURES QHash<QGesture *, QGraphicsObject *>::iterator it; for (it = gestureTargets.begin(); it != gestureTargets.end();) { if (it.value() == item) @@ -706,6 +707,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) else ++it; } + QGraphicsObject *dummy = static_cast<QGraphicsObject *>(item); cachedTargetItems.removeOne(dummy); cachedItemGestures.remove(dummy); @@ -713,6 +715,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys()) ungrabGesture(item, gesture); +#endif // QT_NO_GESTURES } /*! @@ -1180,11 +1183,13 @@ bool QGraphicsScenePrivate::filterEvent(QGraphicsItem *item, QEvent *event) bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event) { if (QGraphicsObject *object = item->toGraphicsObject()) { +#ifndef QT_NO_GESTURES QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager; if (gestureManager) { if (gestureManager->filterEvent(object, event)) return true; } +#endif // QT_NO_GESTURES } if (filterEvent(item, event)) @@ -2602,8 +2607,10 @@ void QGraphicsScene::addItem(QGraphicsItem *item) d->enableTouchEventsOnViews(); } +#ifndef QT_NO_GESTURES foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys()) d->grabGesture(item, gesture); +#endif // Update selection lists if (item->isSelected()) @@ -3525,10 +3532,12 @@ bool QGraphicsScene::event(QEvent *event) case QEvent::TouchEnd: d->touchEventHandler(static_cast<QTouchEvent *>(event)); break; +#ifndef QT_NO_GESTURES case QEvent::Gesture: case QEvent::GestureOverride: d->gestureEventHandler(static_cast<QGestureEvent *>(event)); break; +#endif // QT_NO_GESTURES default: return QObject::event(event); } @@ -5637,8 +5646,10 @@ bool QGraphicsScene::sendEvent(QGraphicsItem *item, QEvent *event) void QGraphicsScenePrivate::addView(QGraphicsView *view) { views << view; +#ifndef QT_NO_GESTURES foreach (Qt::GestureType gesture, grabbedGestures.keys()) view->viewport()->grabGesture(gesture); +#endif } void QGraphicsScenePrivate::removeView(QGraphicsView *view) @@ -5968,6 +5979,7 @@ void QGraphicsScenePrivate::leaveModal(QGraphicsItem *panel) dispatchHoverEvent(&hoverEvent); } +#ifndef QT_NO_GESTURES void QGraphicsScenePrivate::gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures, Qt::GestureFlag flag, QHash<QGraphicsObject *, QSet<QGesture *> > *targets, @@ -6356,6 +6368,7 @@ void QGraphicsScenePrivate::ungrabGesture(QGraphicsItem *item, Qt::GestureType g view->viewport()->ungrabGesture(gesture); } } +#endif // QT_NO_GESTURES QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index c34a303..f8615f4 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -313,7 +313,9 @@ private: friend class QGraphicsSceneBspTreeIndex; friend class QGraphicsSceneBspTreeIndexPrivate; friend class QGraphicsItemEffectSourcePrivate; +#ifndef QT_NO_GESTURES friend class QGesture; +#endif }; Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsScene::SceneLayers) diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 8ad2a0a..f28dfe9 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -299,6 +299,7 @@ public: void enableTouchEventsOnViews(); QList<QGraphicsObject *> cachedTargetItems; +#ifndef QT_NO_GESTURES QHash<QGraphicsObject *, QSet<QGesture *> > cachedItemGestures; QHash<QGraphicsObject *, QSet<QGesture *> > cachedAlreadyDeliveredGestures; QHash<QGesture *, QGraphicsObject *> gestureTargets; @@ -313,6 +314,7 @@ public: void cancelGesturesForChildren(QGesture *original); void grabGesture(QGraphicsItem *, Qt::GestureType gesture); void ungrabGesture(QGraphicsItem *, Qt::GestureType gesture); +#endif // QT_NO_GESTURES void updateInputMethodSensitivityInViews(); diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 8076a21..32560be 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -2688,10 +2688,12 @@ void QGraphicsView::setupViewport(QWidget *widget) if (d->scene && !d->scene->d_func()->allItemsIgnoreTouchEvents) widget->setAttribute(Qt::WA_AcceptTouchEvents); +#ifndef QT_NO_GESTURES if (d->scene) { foreach (Qt::GestureType gesture, d->scene->d_func()->grabbedGestures.keys()) widget->grabGesture(gesture); } +#endif widget->setAcceptDrops(acceptDrops()); } @@ -2838,6 +2840,7 @@ bool QGraphicsView::viewportEvent(QEvent *event) return true; } +#ifndef QT_NO_GESTURES case QEvent::Gesture: case QEvent::GestureOverride: { @@ -2851,6 +2854,7 @@ bool QGraphicsView::viewportEvent(QEvent *event) } return true; } +#endif // QT_NO_GESTURES default: break; } diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index a515ef8..34f40a9 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -63,6 +63,8 @@ #include <private/qt_x11_p.h> #endif +#include <private/qstylehelper_p.h> + QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance) @@ -488,14 +490,12 @@ QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State st basePixmap.load(filename); int actualSize = qMin(size.width(), size.height()); - QString key = QLatin1String("$qt_theme_") - + QString::number(basePixmap.cacheKey(), 16) - + QLatin1Char('_') - + QString::number(mode) - + QLatin1Char('_') - + QString::number(qApp->palette().cacheKey(), 16) - + QLatin1Char('_') - + QString::number(actualSize); + + QString key = QLatin1Literal("$qt_theme_") + % HexString<qint64>(basePixmap.cacheKey()) + % HexString<int>(mode) + % HexString<qint64>(qApp->palette().cacheKey()) + % HexString<int>(actualSize); QPixmap cachedPixmap; if (QPixmapCache::find(key, &cachedPixmap)) { diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 98f235e..d89ffe6 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -272,6 +272,8 @@ bool QImageData::checkForAlphaPixels() const switch (format) { + case QImage::Format_Mono: + case QImage::Format_MonoLSB: case QImage::Format_Indexed8: has_alpha_pixels = has_alpha_clut; break; diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 3013726..20e4b50 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -82,6 +82,7 @@ #endif #include "qpixmap_raster_p.h" +#include "private/qstylehelper_p.h" QT_BEGIN_NAMESPACE @@ -829,8 +830,14 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers return false; QFileInfo info(fileName); - QString key = QLatin1String("qt_pixmap_") + info.absoluteFilePath() + QLatin1Char('_') + QString::number(info.lastModified().toTime_t()) + QLatin1Char('_') + - QString::number(info.size()) + QLatin1Char('_') + QString::number(data ? data->pixelType() : QPixmapData::PixmapType); + if (!info.exists()) + return false; + + QString key = QLatin1Literal("qt_pixmap") + % info.absoluteFilePath() + % HexString<uint>(info.lastModified().toTime_t()) + % HexString<quint64>(info.size()) + % HexString<uint>(data ? data->pixelType() : QPixmapData::PixmapType); if (QPixmapCache::find(key, *this)) return true; diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 6caa7ee..72e5c58 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -185,8 +185,10 @@ QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::T directPainters = 0; #endif +#ifndef QT_NO_GESTURES gestureManager = 0; gestureWidget = 0; +#endif // QT_NO_GESTURES #if defined(Q_WS_X11) || defined(Q_WS_WIN) move_cursor = 0; @@ -3711,6 +3713,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) #endif // !QT_NO_WHEELEVENT || !QT_NO_TABLETEVENT } +#ifndef QT_NO_GESTURES // walk through parents and check for gestures if (d->gestureManager) { switch (e->type()) { @@ -3755,7 +3758,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) } } } - +#endif // QT_NO_GESTURES // User input and window activation makes tooltips sleep switch (e->type()) { @@ -4260,6 +4263,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) res = d->notify_helper(receiver, e); break; +#ifndef QT_NO_GESTURES case QEvent::NativeGesture: { // only propagate the first gesture event (after the GID_BEGIN) @@ -4338,6 +4342,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) } break; } +#endif // QT_NO_GESTURES default: res = d->notify_helper(receiver, e); break; @@ -5770,6 +5775,7 @@ Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window, QApplicationPrivate::translateRawTouchEvent(window, deviceType, touchPoints); } +#ifndef QT_NO_GESTURES QGestureManager* QGestureManager::instance() { QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); @@ -5777,6 +5783,7 @@ QGestureManager* QGestureManager::instance() qAppPriv->gestureManager = new QGestureManager(qApp); return qAppPriv->gestureManager; } +#endif // QT_NO_GESTURES // These pixmaps approximate the images in the Windows User Interface Guidelines. diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index f93f24a..3613f95 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -399,7 +399,9 @@ private: friend class QDirectPainter; friend class QDirectPainterPrivate; #endif +#ifndef QT_NO_GESTURES friend class QGestureManager; +#endif #if defined(Q_WS_MAC) || defined(Q_WS_X11) Q_PRIVATE_SLOT(d_func(), void _q_alertTimeOut()) diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 9a5714b..97ceea9 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -84,7 +84,9 @@ class QInputContext; class QObject; class QWidget; class QSocketNotifier; +#ifndef QT_NO_GESTURES class QGestureManager; +#endif extern bool qt_is_gui_used; #ifndef QT_NO_CLIPBOARD @@ -200,6 +202,7 @@ typedef BOOL (WINAPI *PtrRegisterTouchWindow)(HWND, ULONG); typedef BOOL (WINAPI *PtrGetTouchInputInfo)(HANDLE, UINT, PVOID, int); typedef BOOL (WINAPI *PtrCloseTouchInputHandle)(HANDLE); +#ifndef QT_NO_GESTURES typedef BOOL (WINAPI *PtrGetGestureInfo)(HANDLE, PVOID); typedef BOOL (WINAPI *PtrGetGestureExtraArgs)(HANDLE, UINT, PBYTE); typedef BOOL (WINAPI *PtrCloseGestureInfoHandle)(HANDLE); @@ -263,6 +266,8 @@ typedef struct tagGESTURECONFIG #define GID_ROLLOVER 0xf003 #endif +#endif // QT_NO_GESTURES + #endif // Q_WS_WIN class QScopedLoopLevelCounter @@ -517,6 +522,7 @@ public: void sendSyntheticEnterLeave(QWidget *widget); #endif +#ifndef QT_NO_GESTURES QGestureManager *gestureManager; QWidget *gestureWidget; #if defined(Q_WS_X11) || defined(Q_WS_WIN) @@ -524,6 +530,7 @@ public: QPixmap *copy_cursor; QPixmap *link_cursor; #endif +#endif #if defined(Q_WS_WIN) QPixmap *ignore_cursor; #endif @@ -552,6 +559,7 @@ public: QHash<DWORD, int> touchInputIDToTouchPointID; bool translateTouchEvent(const MSG &msg); +#ifndef QT_NO_GESTURES PtrGetGestureInfo GetGestureInfo; PtrGetGestureExtraArgs GetGestureExtraArgs; PtrCloseGestureInfoHandle CloseGestureInfoHandle; @@ -560,6 +568,7 @@ public: PtrBeginPanningFeedback BeginPanningFeedback; PtrUpdatePanningFeedback UpdatePanningFeedback; PtrEndPanningFeedback EndPanningFeedback; +#endif // QT_NO_GESTURES #endif #ifdef QT_RX71_MULTITOUCH diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 82c3545..9f47112 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1032,6 +1032,9 @@ void QSymbianControl::SizeChanged() qwidget->d_func()->syncBackingStore(); if (!slowResize && tlwExtra) tlwExtra->inTopLevelResize = false; + } else { + QResizeEvent *e = new QResizeEvent(newSize, oldSize); + QApplication::postEvent(qwidget, e); } } @@ -1800,19 +1803,27 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent return 1; const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged(); QWidget *w = QWidgetPrivate::mapper->value(control); - if (!w->d_func()->maybeTopData()) + QWidget *const window = w->window(); + if (!window->d_func()->maybeTopData()) break; + QRefCountedWidgetBackingStore &backingStore = window->d_func()->maybeTopData()->backingStore; if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) { - delete w->d_func()->topData()->backingStore; - w->d_func()->topData()->backingStore = 0; + // Decrement backing store reference count + backingStore.deref(); // In order to ensure that any resources used by the window surface // are immediately freed, we flush the WSERV command buffer. S60->wsSession().Flush(); - } else if ((visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible) - && !w->d_func()->maybeBackingStore()) { - w->d_func()->topData()->backingStore = new QWidgetBackingStore(w); - w->d_func()->invalidateBuffer(w->rect()); - w->repaint(); + } else if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible) { + if (backingStore.data()) { + // Increment backing store reference count + backingStore.ref(); + } else { + // Create backing store with an initial reference count of 1 + backingStore.create(window); + backingStore.ref(); + w->d_func()->invalidateBuffer(w->rect()); + w->repaint(); + } } return 1; } diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index d2ce5ff..e10a6b0 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -52,9 +52,11 @@ extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.c #include <windowsm.h> #include <tpcshell.h> #ifdef QT_WINCE_GESTURES +#ifndef QT_NO_GESTURES #include <gesture.h> #endif #endif +#endif #include "qapplication.h" #include "qdesktopwidget.h" @@ -198,6 +200,7 @@ struct SHRGINFO { #define SPI_SETSIPINFO 224 #endif +#ifndef QT_NO_GESTURES typedef DWORD (API *AygRecognizeGesture)(SHRGINFO*); static AygRecognizeGesture ptrRecognizeGesture = 0; static bool aygResolved = false; @@ -209,6 +212,7 @@ static void resolveAygLibs() ptrRecognizeGesture = (AygRecognizeGesture) ayglib.resolve("SHRecognizeGesture"); } } +#endif // QT_NO_GESTURES #endif @@ -461,7 +465,9 @@ public: bool translateConfigEvent(const MSG &msg); bool translateCloseEvent(const MSG &msg); bool translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, int numPackets); +#ifndef QT_NO_GESTURES bool translateGestureEvent(const MSG &msg, const GESTUREINFO &gi); +#endif void repolishStyle(QStyle &style); inline void showChildren(bool spontaneous) { d_func()->showChildren(spontaneous); } inline void hideChildren(bool spontaneous) { d_func()->hideChildren(spontaneous); } @@ -841,6 +847,7 @@ void qt_init(QApplicationPrivate *priv, int) ptrSetProcessDPIAware(); #endif +#ifndef QT_NO_GESTURES priv->GetGestureInfo = 0; priv->GetGestureExtraArgs = 0; priv->CloseGestureInfoHandle = 0; @@ -881,6 +888,7 @@ void qt_init(QApplicationPrivate *priv, int) (PtrEndPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), "EndPanningFeedback"); #endif +#endif // QT_NO_GESTURES } /***************************************************************************** @@ -1540,7 +1548,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa case WM_SETTINGCHANGE: #ifdef Q_WS_WINCE // CE SIP hide/show - if (wParam == SPI_SETSIPINFO) { + if (qt_desktopWidget && wParam == SPI_SETSIPINFO) { QResizeEvent re(QSize(0, 0), QSize(0, 0)); // Calculated by QDesktopWidget QApplication::sendEvent(qt_desktopWidget, &re); break; @@ -1665,12 +1673,14 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa shrg.ptDown.y = GET_Y_LPARAM(lParam); shrg.dwFlags = SHRG_RETURNCMD | SHRG_NOANIMATION; resolveAygLibs(); +#ifndef QT_NO_GESTURES if (ptrRecognizeGesture && (ptrRecognizeGesture(&shrg) == GN_CONTEXTMENU)) { if (QApplication::activePopupWidget()) QApplication::activePopupWidget()->close(); QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos); result = qt_sendSpontaneousEvent(alienWidget, &e); } +#endif // QT_NO_GESTURES } } } @@ -2554,6 +2564,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa } result = false; break; +#ifndef QT_NO_GESTURES #if !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES) case WM_GESTURE: { GESTUREINFO gi; @@ -2588,6 +2599,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa break; } #endif // !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES) +#endif // QT_NO_GESTURES #ifndef QT_NO_CURSOR case WM_SETCURSOR: { QCursor *ovr = QApplication::overrideCursor(); @@ -3821,6 +3833,7 @@ bool QETWidget::translateCloseEvent(const MSG &) return d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent); } +#ifndef QT_NO_GESTURES bool QETWidget::translateGestureEvent(const MSG &, const GESTUREINFO &gi) { const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); @@ -3859,7 +3872,7 @@ bool QETWidget::translateGestureEvent(const MSG &, const GESTUREINFO &gi) qt_sendSpontaneousEvent(widget, &event); return true; } - +#endif // QT_NO_GESTURES void QApplication::setCursorFlashTime(int msecs) { diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index b2dc638..9d5a7c0 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -5264,7 +5264,7 @@ bool QETWidget::translateConfigEvent(const XEvent *event) if (isVisible() && data->crect.size() != oldSize) { Q_ASSERT(d->extra->topextra); - QWidgetBackingStore *bs = d->extra->topextra->backingStore; + QWidgetBackingStore *bs = d->extra->topextra->backingStore.data(); const bool hasStaticContents = bs && bs->hasStaticContents(); // If we have a backing store with static contents, we have to disable the top-level // resize optimization in order to get invalidated regions for resized widgets. diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 86c4025..772016a 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -952,12 +952,14 @@ static int qCocoaViewCount = 0; if (!QApplicationPrivate::tryModalHelper(qwidget, 0)) return; +#ifndef QT_NO_GESTURES QNativeGestureEvent qNGEvent; qNGEvent.gestureType = QNativeGestureEvent::Zoom; NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]]; qNGEvent.position = flipPoint(p).toPoint(); qNGEvent.percentage = [event magnification]; qt_sendSpontaneousEvent(qwidget, &qNGEvent); +#endif // QT_NO_GESTURES } - (void)rotateWithEvent:(NSEvent *)event; @@ -965,12 +967,14 @@ static int qCocoaViewCount = 0; if (!QApplicationPrivate::tryModalHelper(qwidget, 0)) return; +#ifndef QT_NO_GESTURES QNativeGestureEvent qNGEvent; qNGEvent.gestureType = QNativeGestureEvent::Rotate; NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]]; qNGEvent.position = flipPoint(p).toPoint(); qNGEvent.percentage = -[event rotation]; qt_sendSpontaneousEvent(qwidget, &qNGEvent); +#endif // QT_NO_GESTURES } - (void)swipeWithEvent:(NSEvent *)event; @@ -978,6 +982,7 @@ static int qCocoaViewCount = 0; if (!QApplicationPrivate::tryModalHelper(qwidget, 0)) return; +#ifndef QT_NO_GESTURES QNativeGestureEvent qNGEvent; qNGEvent.gestureType = QNativeGestureEvent::Swipe; NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]]; @@ -991,6 +996,7 @@ static int qCocoaViewCount = 0; else if ([event deltaY] == -1) qNGEvent.angle = 270.0f; qt_sendSpontaneousEvent(qwidget, &qNGEvent); +#endif // QT_NO_GESTURES } - (void)beginGestureWithEvent:(NSEvent *)event; @@ -998,11 +1004,13 @@ static int qCocoaViewCount = 0; if (!QApplicationPrivate::tryModalHelper(qwidget, 0)) return; +#ifndef QT_NO_GESTURES QNativeGestureEvent qNGEvent; qNGEvent.gestureType = QNativeGestureEvent::GestureBegin; NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]]; qNGEvent.position = flipPoint(p).toPoint(); qt_sendSpontaneousEvent(qwidget, &qNGEvent); +#endif // QT_NO_GESTURES } - (void)endGestureWithEvent:(NSEvent *)event; @@ -1010,11 +1018,13 @@ static int qCocoaViewCount = 0; if (!QApplicationPrivate::tryModalHelper(qwidget, 0)) return; +#ifndef QT_NO_GESTURES QNativeGestureEvent qNGEvent; qNGEvent.gestureType = QNativeGestureEvent::GestureEnd; NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]]; qNGEvent.position = flipPoint(p).toPoint(); qt_sendSpontaneousEvent(qwidget, &qNGEvent); +#endif // QT_NO_GESTURES } - (void)frameDidChange:(NSNotification *)note diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 055c127..f75495a 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3421,9 +3421,11 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { case QEvent::ChildRemoved: n = n ? n : "ChildRemoved"; dbg.nospace() << "QChildEvent(" << n << ", " << (static_cast<const QChildEvent*>(e))->child(); return dbg.space(); +#ifndef QT_NO_GESTURES case QEvent::Gesture: n = "Gesture"; break; +#endif default: dbg.nospace() << "QEvent(" << (const void *)e << ", type = " << e->type() << ')'; return dbg.space(); @@ -4254,6 +4256,7 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T return *this; } +#ifndef QT_NO_GESTURES /*! \class QGestureEvent \since 4.6 @@ -4558,4 +4561,6 @@ const QGestureEventPrivate *QGestureEvent::d_func() const */ #endif +#endif // QT_NO_GESTURES + QT_END_NAMESPACE diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 90242fe..9c70c02 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -62,7 +62,9 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) class QAction; +#ifndef QT_NO_GESTURES class QGesture; +#endif class Q_GUI_EXPORT QInputEvent : public QEvent { @@ -824,6 +826,7 @@ protected: friend class QApplicationPrivate; }; +#ifndef QT_NO_GESTURES class QGesture; class QGestureEventPrivate; class Q_GUI_EXPORT QGestureEvent : public QEvent @@ -875,6 +878,7 @@ private: friend class QApplication; friend class QGestureManager; }; +#endif // QT_NO_GESTURES QT_END_NAMESPACE diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index 5c94a23..e323aa9 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -120,6 +120,7 @@ public: qreal pressure; }; +#ifndef QT_NO_GESTURES class QNativeGestureEvent : public QEvent { public: @@ -164,7 +165,7 @@ public: QMap<Qt::GestureType, bool> accepted; QMap<Qt::GestureType, QWidget *> targetWidgets; }; - +#endif // QT_NO_GESTURES class QFileOpenEventPrivate { diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm index 0d93b9f..e26fbde 100644 --- a/src/gui/kernel/qeventdispatcher_mac.mm +++ b/src/gui/kernel/qeventdispatcher_mac.mm @@ -492,6 +492,7 @@ static bool IsMouseOrKeyEvent( NSEvent* event ) case NSOtherMouseDown: case NSOtherMouseUp: case NSOtherMouseDragged: +#ifndef QT_NO_GESTURES #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 case NSEventTypeGesture: // touch events case NSEventTypeMagnify: @@ -500,6 +501,7 @@ static bool IsMouseOrKeyEvent( NSEvent* event ) case NSEventTypeBeginGesture: case NSEventTypeEndGesture: #endif +#endif // QT_NO_GESTURES result = true; break; diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index 49bdea7..f5688f4 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -42,6 +42,8 @@ #include "qgesture.h" #include "private/qgesture_p.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE /*! @@ -725,3 +727,5 @@ void QTapAndHoldGesture::setPosition(const QPointF &value) } QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index c9bdce6..8c10895 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -49,6 +49,8 @@ #include <QtCore/qrect.h> #include <QtCore/qmetatype.h> +#ifndef QT_NO_GESTURES + QT_BEGIN_HEADER Q_DECLARE_METATYPE(Qt::GestureState) @@ -258,4 +260,6 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(QGesture::GestureCancelPolicy) QT_END_HEADER +#endif // QT_NO_GESTURES + #endif // QGESTURE_H diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index bf60f97..f5474c1 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -59,6 +59,8 @@ #include "qelapsedtimer.h" #include "private/qobject_p.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE class QGesturePrivate : public QObjectPrivate @@ -179,4 +181,6 @@ public: QT_END_NAMESPACE +#endif // QT_NO_GESTURES + #endif // QGESTURE_P_H diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 43facef..2af031b 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -66,6 +66,8 @@ # define DEBUG qDebug #endif +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE QGestureManager::QGestureManager(QObject *parent) @@ -684,6 +686,7 @@ void QGestureManager::recycle(QGesture *gesture) if (recognizer) { gesture->setGestureCancelPolicy(QGesture::CancelNone); recognizer->reset(gesture); + m_activeGestures.remove(gesture); } else { cleanupGesturesForRemovedRecognizer(gesture); } @@ -691,4 +694,6 @@ void QGestureManager::recycle(QGesture *gesture) QT_END_NAMESPACE +#endif // QT_NO_GESTURES + #include "moc_qgesturemanager_p.cpp" diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h index c452f49..747cb1a 100644 --- a/src/gui/kernel/qgesturemanager_p.h +++ b/src/gui/kernel/qgesturemanager_p.h @@ -58,6 +58,8 @@ #include "private/qwidget_p.h" #include "qgesturerecognizer.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE class QBasicTimer; @@ -143,4 +145,6 @@ private: QT_END_NAMESPACE +#endif // QT_NO_GESTURES + #endif // QGESTUREMANAGER_P_H diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp index 9dcca17..3e23bbf 100644 --- a/src/gui/kernel/qgesturerecognizer.cpp +++ b/src/gui/kernel/qgesturerecognizer.cpp @@ -44,6 +44,8 @@ #include "private/qgesture_p.h" #include "private/qgesturemanager_p.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE /*! @@ -231,3 +233,5 @@ void QGestureRecognizer::unregisterRecognizer(Qt::GestureType type) } QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qgesturerecognizer.h b/src/gui/kernel/qgesturerecognizer.h index 3e17c99..5afb43f 100644 --- a/src/gui/kernel/qgesturerecognizer.h +++ b/src/gui/kernel/qgesturerecognizer.h @@ -45,6 +45,8 @@ #include <QtCore/qglobal.h> #include <QtCore/qnamespace.h> +#ifndef QT_NO_GESTURES + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -95,4 +97,6 @@ QT_END_NAMESPACE QT_END_HEADER +#endif // QT_NO_GESTURES + #endif // QGESTURERECOGNIZER_H diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index b038fde..562227a 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -439,6 +439,10 @@ static const struct { { Qt::Key_MediaPrevious, QT_TRANSLATE_NOOP("QShortcut", "Media Previous") }, { Qt::Key_MediaNext, QT_TRANSLATE_NOOP("QShortcut", "Media Next") }, { Qt::Key_MediaRecord, QT_TRANSLATE_NOOP("QShortcut", "Media Record") }, + //: Media player pause button + { Qt::Key_MediaPause, QT_TRANSLATE_NOOP("QShortcut", "Media Pause") }, + //: Media player button to toggle between playing and paused + { Qt::Key_MediaTogglePlayPause, QT_TRANSLATE_NOOP("QShortcut", "Toggle Media Play/Pause") }, { Qt::Key_HomePage, QT_TRANSLATE_NOOP("QShortcut", "Home Page") }, { Qt::Key_Favorites, QT_TRANSLATE_NOOP("QShortcut", "Favorites") }, { Qt::Key_Search, QT_TRANSLATE_NOOP("QShortcut", "Search") }, @@ -575,13 +579,25 @@ static const struct { // -------------------------------------------------------------- // Device keys - { Qt::Key_Context1, QT_TRANSLATE_NOOP("QShortcut", "Context1") }, - { Qt::Key_Context2, QT_TRANSLATE_NOOP("QShortcut", "Context2") }, - { Qt::Key_Context3, QT_TRANSLATE_NOOP("QShortcut", "Context3") }, - { Qt::Key_Context4, QT_TRANSLATE_NOOP("QShortcut", "Context4") }, - { Qt::Key_Call, QT_TRANSLATE_NOOP("QShortcut", "Call") }, - { Qt::Key_Hangup, QT_TRANSLATE_NOOP("QShortcut", "Hangup") }, - { Qt::Key_Flip, QT_TRANSLATE_NOOP("QShortcut", "Flip") }, + { Qt::Key_Context1, QT_TRANSLATE_NOOP("QShortcut", "Context1") }, + { Qt::Key_Context2, QT_TRANSLATE_NOOP("QShortcut", "Context2") }, + { Qt::Key_Context3, QT_TRANSLATE_NOOP("QShortcut", "Context3") }, + { Qt::Key_Context4, QT_TRANSLATE_NOOP("QShortcut", "Context4") }, + //: Button to start a call (note: a separate button is used to end the call) + { Qt::Key_Call, QT_TRANSLATE_NOOP("QShortcut", "Call") }, + //: Button to end a call (note: a separate button is used to start the call) + { Qt::Key_Hangup, QT_TRANSLATE_NOOP("QShortcut", "Hangup") }, + //: Button that will hang up if we're in call, or make a call if we're not. + { Qt::Key_ToggleCallHangup, QT_TRANSLATE_NOOP("QShortcut", "Toggle Call/Hangup") }, + { Qt::Key_Flip, QT_TRANSLATE_NOOP("QShortcut", "Flip") }, + //: Button to trigger voice dialling + { Qt::Key_VoiceDial, QT_TRANSLATE_NOOP("QShortcut", "Voice Dial") }, + //: Button to redial the last number called + { Qt::Key_LastNumberRedial, QT_TRANSLATE_NOOP("QShortcut", "Last Number Redial") }, + //: Button to trigger the camera shutter (take a picture) + { Qt::Key_Camera, QT_TRANSLATE_NOOP("QShortcut", "Camera Shutter") }, + //: Button to focus the camera + { Qt::Key_CameraFocus, QT_TRANSLATE_NOOP("QShortcut", "Camera Focus") }, // -------------------------------------------------------------- // Japanese keyboard support diff --git a/src/gui/kernel/qmacgesturerecognizer_mac.mm b/src/gui/kernel/qmacgesturerecognizer_mac.mm index fba839b..0ccbb52 100644 --- a/src/gui/kernel/qmacgesturerecognizer_mac.mm +++ b/src/gui/kernel/qmacgesturerecognizer_mac.mm @@ -47,6 +47,8 @@ #include "qwidget.h" #include "qdebug.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE QMacSwipeGestureRecognizer::QMacSwipeGestureRecognizer() @@ -260,3 +262,5 @@ void QMacPanGestureRecognizer::reset(QGesture *gesture) #endif // QT_MAC_USE_COCOA QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qmacgesturerecognizer_mac_p.h b/src/gui/kernel/qmacgesturerecognizer_mac_p.h index dd8a150..f48c160 100644 --- a/src/gui/kernel/qmacgesturerecognizer_mac_p.h +++ b/src/gui/kernel/qmacgesturerecognizer_mac_p.h @@ -57,6 +57,8 @@ #include "qpoint.h" #include "qgesturerecognizer.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE class QMacSwipeGestureRecognizer : public QGestureRecognizer @@ -99,4 +101,6 @@ private: QT_END_NAMESPACE +#endif // QT_NO_GESTURES + #endif // QMACSWIPEGESTURERECOGNIZER_MAC_P_H diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index a575717..6960838 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -47,6 +47,8 @@ #include "qabstractscrollarea.h" #include "qdebug.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE QPanGestureRecognizer::QPanGestureRecognizer() @@ -563,3 +565,5 @@ void QTapAndHoldGestureRecognizer::reset(QGesture *state) } QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index 64505d8..da73b85 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -56,6 +56,8 @@ #include "qgesturerecognizer.h" #include "private/qgesture_p.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE class QPanGestureRecognizer : public QGestureRecognizer @@ -110,4 +112,6 @@ public: QT_END_NAMESPACE +#endif // QT_NO_GESTURES + #endif // QSTANDARDGESTURES_P_H diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index a891be0..77d416b 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -161,6 +161,51 @@ static inline bool hasBackingStoreSupport() extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp + +QRefCountedWidgetBackingStore::QRefCountedWidgetBackingStore() + : m_ptr(0) + , m_count(0) +{ + +} + +QRefCountedWidgetBackingStore::~QRefCountedWidgetBackingStore() +{ + delete m_ptr; +} + +void QRefCountedWidgetBackingStore::create(QWidget *widget) +{ + destroy(); + m_ptr = new QWidgetBackingStore(widget); + m_count = 0; +} + +void QRefCountedWidgetBackingStore::destroy() +{ + delete m_ptr; + m_ptr = 0; + m_count = 0; +} + +void QRefCountedWidgetBackingStore::ref() +{ + Q_ASSERT(m_ptr); + ++m_count; +} + +void QRefCountedWidgetBackingStore::deref() +{ + if (m_count) { + Q_ASSERT(m_ptr); + if (0 == --m_count) { + delete m_ptr; + m_ptr = 0; + } + } +} + + QWidgetPrivate::QWidgetPrivate(int version) : QObjectPrivate(version) , extra(0) @@ -202,7 +247,9 @@ QWidgetPrivate::QWidgetPrivate(int version) , picture(0) #elif defined(Q_WS_WIN) , noPaintOnScreen(0) + #ifndef QT_NO_GESTURES , nativeGesturePanEnabled(0) + #endif #elif defined(Q_WS_MAC) , needWindowChange(0) , hasAlienChildren(0) @@ -1348,11 +1395,9 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) // a real toplevel window needs a backing store if (isWindow() && windowType() != Qt::Desktop) { - delete d->topData()->backingStore; - // QWidgetBackingStore will check this variable, hence it must be 0 - d->topData()->backingStore = 0; + d->topData()->backingStore.destroy(); if (hasBackingStoreSupport()) - d->topData()->backingStore = new QWidgetBackingStore(this); + d->topData()->backingStore.create(this); } d->setModal_sys(); @@ -1397,8 +1442,10 @@ QWidget::~QWidget() qWarning("QWidget: %s (%s) deleted while being painted", className(), name()); #endif +#ifndef QT_NO_GESTURES foreach (Qt::GestureType type, d->gestureContext.keys()) ungrabGesture(type); +#endif // force acceptDrops false before winId is destroyed. d->registerDropSite(false); @@ -1478,8 +1525,7 @@ QWidget::~QWidget() // the backing store will delete its window surface, which may or may // not have a reference to this widget that will be used later to // notify the window it no longer has a surface. - delete d->extra->topextra->backingStore; - d->extra->topextra->backingStore = 0; + d->extra->topextra->backingStore.destroy(); } #endif if (QWidgetBackingStore *bs = d->maybeBackingStore()) { @@ -1577,7 +1623,6 @@ void QWidgetPrivate::createTLExtra() QTLWExtra* x = extra->topextra = new QTLWExtra; x->icon = 0; x->iconPixmap = 0; - x->backingStore = 0; x->windowSurface = 0; x->sharedPainter = 0; x->incw = x->inch = 0; @@ -1661,7 +1706,7 @@ void QWidgetPrivate::deleteExtra() #endif if (extra->topextra) { deleteTLSysExtra(); - delete extra->topextra->backingStore; + extra->topextra->backingStore.destroy(); delete extra->topextra->icon; delete extra->topextra->iconPixmap; #if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) @@ -8540,9 +8585,11 @@ bool QWidget::event(QEvent *event) #endif // Q_WS_MAC break; } +#ifndef QT_NO_GESTURES case QEvent::Gesture: event->ignore(); break; +#endif #ifndef QT_NO_PROPERTIES case QEvent::DynamicPropertyChange: { const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName(); @@ -11975,6 +12022,7 @@ QGraphicsProxyWidget *QWidget::graphicsProxyWidget() const Synonym for QList<QWidget *>. */ +#ifndef QT_NO_GESTURES /*! Subscribes the widget to a given \a gesture with specific \a flags. @@ -12002,7 +12050,7 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) manager->cleanupCachedGestures(this, gesture); } } - +#endif // QT_NO_GESTURES /*! \typedef WId diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index e12148b..941bd68 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -360,8 +360,10 @@ public: void setGraphicsEffect(QGraphicsEffect *effect); #endif //QT_NO_GRAPHICSEFFECT +#ifndef QT_NO_GESTURES void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags()); void ungrabGesture(Qt::GestureType type); +#endif public Q_SLOTS: void setWindowTitle(const QString &); @@ -742,8 +744,10 @@ private: friend class QGraphicsProxyWidgetPrivate; friend class QStyleSheetStyle; friend struct QWidgetExceptionCleaner; +#ifndef QT_NO_GESTURES friend class QGestureManager; friend class QWinNativePanGestureRecognizer; +#endif // QT_NO_GESTURES friend class QWidgetEffectSourcePrivate; #ifdef Q_WS_MAC diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 6df9c3b..56e72af 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -757,6 +757,7 @@ static OSWindowRef qt_mac_create_window(QWidget *, WindowClass wclass, WindowAtt return window; } +#ifndef QT_NO_GESTURES #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 /* We build the release package against the 10.4 SDK. So, to enable gestures for applications running on @@ -773,6 +774,7 @@ enum { kEventParamMagnificationAmount = 'magn' }; #endif +#endif // QT_NO_GESTURES // window events static EventTypeSpec window_events[] = { @@ -1081,6 +1083,7 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, handled_event = false; break; } +#ifndef QT_NO_GESTURES case kEventClassGesture: { // First, find the widget that was under // the mouse when the gesture happened: @@ -1147,6 +1150,7 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, QApplication::sendSpontaneousEvent(widget, &qNGEvent); break; } +#endif // QT_NO_GESTURES default: handled_event = false; diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 412705a..d432263 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -110,13 +110,53 @@ class QWidgetItemV2; class QStyle; +class Q_AUTOTEST_EXPORT QRefCountedWidgetBackingStore +{ +public: + QRefCountedWidgetBackingStore(); + ~QRefCountedWidgetBackingStore(); + + void create(QWidget *tlw); + void destroy(); + + void ref(); + void deref(); + + inline QWidgetBackingStore* data() + { + return m_ptr; + } + + inline QWidgetBackingStore* operator->() + { + return m_ptr; + } + + inline QWidgetBackingStore& operator*() + { + return *m_ptr; + } + + inline operator bool() const + { + return (0 != m_ptr); + } + +private: + Q_DISABLE_COPY(QRefCountedWidgetBackingStore) + +private: + QWidgetBackingStore* m_ptr; + int m_count; +}; + struct QTLWExtra { // *************************** Cross-platform variables ***************************** // Regular pointers (keep them together to avoid gaps on 64 bits architectures). QIcon *icon; // widget icon QPixmap *iconPixmap; - QWidgetBackingStore *backingStore; + QRefCountedWidgetBackingStore backingStore; QWindowSurface *windowSurface; QPainter *sharedPainter; @@ -686,7 +726,9 @@ public: #ifndef QT_NO_ACTION QList<QAction*> actions; #endif +#ifndef QT_NO_GESTURES QMap<Qt::GestureType, Qt::GestureFlags> gestureContext; +#endif // Bit fields. uint high_attributes[4]; // the low ones are in QWidget::widget_attributes @@ -715,8 +757,9 @@ public: void updateX11AcceptFocus(); #elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine() +#ifndef QT_NO_GESTURES uint nativeGesturePanEnabled : 1; - +#endif bool shouldShowMaximizeButton(); void winUpdateIsOpaque(); void reparentChildren(); @@ -930,7 +973,7 @@ inline QWidgetBackingStore *QWidgetPrivate::maybeBackingStore() const { Q_Q(const QWidget); QTLWExtra *x = q->window()->d_func()->maybeTopData(); - return x ? x->backingStore : 0; + return x ? x->backingStore.data() : 0; } QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 02e7cb8..86b858d 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -433,6 +433,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de // Request mouse move events. drawableWindow->PointerFilter(EPointerFilterEnterExit | EPointerFilterMove | EPointerFilterDrag, 0); + drawableWindow->EnableVisibilityChangeEvents(); if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) { activateSymbianWindow(control.data()); @@ -487,11 +488,8 @@ void QWidgetPrivate::show_sys() && !S60->buttonGroupContainer() && !S60->statusPane()) { bool isFullscreen = q->windowState() & Qt::WindowFullScreen; - bool cbaRequested = q->windowFlags() & Qt::WindowSoftkeysVisibleHint; - // If the window is fullscreen and has not explicitly requested that the CBA be visible - // we delay the creation even more. - if ((!isFullscreen || cbaRequested) && !q->testAttribute(Qt::WA_DontShowOnScreen)) { + if (!q->testAttribute(Qt::WA_DontShowOnScreen)) { // Create the status pane and CBA here CEikAppUi *ui = static_cast<CEikAppUi *>(S60->appUi()); @@ -911,14 +909,12 @@ void QWidgetPrivate::registerDropSite(bool /* on */) void QWidgetPrivate::createTLSysExtra() { - extra->topextra->backingStore = 0; extra->topextra->inExpose = 0; } void QWidgetPrivate::deleteTLSysExtra() { - delete extra->topextra->backingStore; - extra->topextra->backingStore = 0; + extra->topextra->backingStore.destroy(); } void QWidgetPrivate::createSysExtra() diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index 5482da3..a7e66bf 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -2075,7 +2075,7 @@ void QWidgetPrivate::registerTouchWindow() void QWidgetPrivate::winSetupGestures() { -#if !defined(QT_NO_NATIVE_GESTURES) +#if !defined(QT_NO_GESTURES) && !defined(QT_NO_NATIVE_GESTURES) Q_Q(QWidget); if (!q || !q->isVisible() || !nativeGesturePanEnabled) return; diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp index 0bddbf6..780de5d 100644 --- a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp +++ b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp @@ -50,6 +50,8 @@ #include "private/qapplication_p.h" #include "private/qwidget_p.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE #if !defined(QT_NO_NATIVE_GESTURES) @@ -127,3 +129,5 @@ void QWinNativePanGestureRecognizer::reset(QGesture *state) #endif // QT_NO_NATIVE_GESTURES QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h index 146b067..64addeb 100644 --- a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h +++ b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h @@ -54,6 +54,7 @@ // #include <QGestureRecognizer> + #include <objbase.h> class IInkRectangle; @@ -87,6 +88,8 @@ DECLARE_INTERFACE_(IInkTablets, IDispatch) STDMETHOD(IsPacketPropertySupported)(THIS_ BSTR packetPropertyName, VARIANT_BOOL *Supported) PURE; }; +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE #if !defined(QT_NO_NATIVE_GESTURES) @@ -105,4 +108,6 @@ public: QT_END_NAMESPACE +#endif // QT_NO_GESTURES + #endif // QWINNATIVEPANGESTURERECOGNIZER_WIN_P_H diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index f9cd59b..83751ed 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -909,7 +909,7 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) QWidgetPrivate *pd = pw->d_func(); QRect clipR(pd->clipRect()); #ifdef Q_WS_QWS - QWidgetBackingStore *wbs = x->backingStore; + QWidgetBackingStore *wbs = x->backingStore.data(); QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(wbs->windowSurface); clipR = clipR.intersected(surface->clipRegion().translated(-toplevelOffset).boundingRect()); #endif @@ -939,7 +939,7 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) invalidateBuffer((newRect & clipR).translated(-data.crect.topLeft())); } else { - QWidgetBackingStore *wbs = x->backingStore; + QWidgetBackingStore *wbs = x->backingStore.data(); QRegion childExpose(newRect & clipR); if (sourceRect.isValid() && wbs->bltRect(sourceRect, dx, dy, pw)) @@ -982,7 +982,7 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) if (x->inTopLevelResize) return; - QWidgetBackingStore *wbs = x->backingStore; + QWidgetBackingStore *wbs = x->backingStore.data(); if (!wbs) return; diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index b468b11..d3061d8 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -48,6 +48,7 @@ #include "qline.h" #include "qdebug.h" #include <QtCore/qcoreapplication.h> +#include "private/qstylehelper_p.h" QT_BEGIN_NAMESPACE @@ -96,9 +97,11 @@ const uchar *qt_patternForBrush(int brushStyle, bool invert) QPixmap qt_pixmapForBrush(int brushStyle, bool invert) { + QPixmap pm; - QString key = QLatin1String("$qt-brush$") + QString::number(brushStyle) - + QString::number((int)invert); + QString key = QLatin1Literal("$qt-brush$") + % HexString<uint>(brushStyle) + % QLatin1Char(invert ? '1' : '0'); if (!QPixmapCache::find(key, pm)) { pm = QBitmap::fromData(QSize(8, 8), qt_patternForBrush(brushStyle, invert), QImage::Format_MonoLSB); diff --git a/src/gui/painting/qdrawutil.cpp b/src/gui/painting/qdrawutil.cpp index 3ce95ef..11ea6d5 100644 --- a/src/gui/painting/qdrawutil.cpp +++ b/src/gui/painting/qdrawutil.cpp @@ -48,6 +48,7 @@ #include <private/qpaintengineex_p.h> #include <qvarlengtharray.h> #include <qmath.h> +#include <private/qstylehelper_p.h> QT_BEGIN_NAMESPACE @@ -1018,7 +1019,9 @@ void qDrawItem(QPainter *p, Qt::GUIStyle gs, ; #ifndef QT_NO_IMAGE_HEURISTIC_MASK } else { // color pixmap, no mask - QString k = QString::fromLatin1("$qt-drawitem-%1").arg(pm.cacheKey()); + QString k = QLatin1Literal("$qt-drawitem") + % HexString<qint64>(pm.cacheKey()); + if (!QPixmapCache::find(k, pm)) { pm = pm.createHeuristicMask(); pm.setMask((QBitmap&)pm); diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index aef8b80..b8ad9b3 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -79,6 +79,8 @@ #include <private/qtessellator_p.h> #endif +#include <private/qstylehelper_p.h> + QT_BEGIN_NAMESPACE extern Drawable qt_x11Handle(const QPaintDevice *pd); @@ -224,7 +226,10 @@ static const uchar base_dither_matrix[DITHER_SIZE][DITHER_SIZE] = { static QPixmap qt_patternForAlpha(uchar alpha, int screen) { QPixmap pm; - QString key = QLatin1String("$qt-alpha-brush$") + QString::number(alpha) + QString::number(screen); + QString key = QLatin1Literal("$qt-alpha-brush$") + % HexString<uchar>(alpha) + % HexString<int>(screen); + if (!QPixmapCache::find(key, pm)) { // #### why not use a mono image here???? QImage pattern(DITHER_SIZE, DITHER_SIZE, QImage::Format_ARGB32); diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index cb56ac8..312cc95 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -74,6 +74,7 @@ #include <private/qmath_p.h> #include <private/qstatictext_p.h> #include <private/qglyphs_p.h> +#include <private/qstylehelper_p.h> QT_BEGIN_NAMESPACE @@ -5883,14 +5884,24 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText return; } + if (d->extended->type() == QPaintEngine::OpenGL2 && !staticText_d->untransformedCoordinates) { + staticText_d->untransformedCoordinates = true; + staticText_d->needsRelayout = true; + } else if (d->extended->type() != QPaintEngine::OpenGL2 && staticText_d->untransformedCoordinates) { + staticText_d->untransformedCoordinates = false; + staticText_d->needsRelayout = true; + } + // Don't recalculate entire layout because of translation, rather add the dx and dy // into the position to move each text item the correct distance. - QPointF transformedPosition = topLeftPosition * d->state->matrix; - QTransform matrix = d->state->matrix; + QPointF transformedPosition = topLeftPosition; + if (!staticText_d->untransformedCoordinates) + transformedPosition = transformedPosition * d->state->matrix; + QTransform oldMatrix; // The translation has been applied to transformedPosition. Remove translation // component from matrix. - if (d->state->matrix.isTranslating()) { + if (d->state->matrix.isTranslating() && !staticText_d->untransformedCoordinates) { qreal m11 = d->state->matrix.m11(); qreal m12 = d->state->matrix.m12(); qreal m13 = d->state->matrix.m13(); @@ -5899,6 +5910,7 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText qreal m23 = d->state->matrix.m23(); qreal m33 = d->state->matrix.m33(); + oldMatrix = d->state->matrix; d->state->matrix.setMatrix(m11, m12, m13, m21, m22, m23, 0.0, 0.0, m33); @@ -5907,7 +5919,7 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText // If the transform is not identical to the text transform, // we have to relayout the text (for other transformations than plain translation) bool staticTextNeedsReinit = staticText_d->needsRelayout; - if (staticText_d->matrix != d->state->matrix) { + if (!staticText_d->untransformedCoordinates && staticText_d->matrix != d->state->matrix) { staticText_d->matrix = d->state->matrix; staticTextNeedsReinit = true; } @@ -5946,8 +5958,8 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText if (currentColor != oldPen.color()) setPen(oldPen); - if (matrix.isTranslating()) - d->state->matrix = matrix; + if (!staticText_d->untransformedCoordinates && oldMatrix.isTranslating()) + d->state->matrix = oldMatrix; } /*! @@ -5965,6 +5977,23 @@ void QPainter::drawText(const QPointF &p, const QString &str, int tf, int justif if (!d->engine || str.isEmpty() || pen().style() == Qt::NoPen) return; + if (tf & Qt::TextBypassShaping) { + // Skip harfbuzz complex shaping, shape using glyph advances only + int len = str.length(); + int numGlyphs = len; + QVarLengthGlyphLayoutArray glyphs(len); + QFontEngine *fontEngine = d->state->font.d->engineForScript(QUnicodeTables::Common); + if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) { + glyphs.resize(numGlyphs); + if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) + Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice"); + } + + QTextItemInt gf(glyphs, &d->state->font, fontEngine); + drawTextItem(p, gf); + return; + } + QStackTextEngine engine(str, d->state->font); engine.option.setTextDirection(d->state->layoutDirection); if (tf & (Qt::TextForceLeftToRight|Qt::TextForceRightToLeft)) { @@ -6245,10 +6274,9 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) { const qreal radiusBase = qMax(qreal(1), maxRadius); - QString key = QLatin1String("WaveUnderline-"); - key += pen.color().name(); - key += QLatin1Char('-'); - key += QString::number(radiusBase); + QString key = QLatin1Literal("WaveUnderline-") + % pen.color().name() + % HexString<qreal>(radiusBase); QPixmap pixmap; if (QPixmapCache::find(key, pixmap)) diff --git a/src/gui/statemachine/qguistatemachine.cpp b/src/gui/statemachine/qguistatemachine.cpp index 63ad94e..2b4c9c2 100644 --- a/src/gui/statemachine/qguistatemachine.cpp +++ b/src/gui/statemachine/qguistatemachine.cpp @@ -474,9 +474,11 @@ static QEvent *cloneEvent(QEvent *e) case QEvent::TouchEnd: return new QTouchEvent(*static_cast<QTouchEvent*>(e)); +#ifndef QT_NO_GESTURES case QEvent::NativeGesture: Q_ASSERT_X(false, "cloneEvent()", "not implemented"); break; +#endif case QEvent::RequestSoftwareInputPanel: case QEvent::CloseSoftwareInputPanel: diff --git a/src/gui/styles/qgtkpainter.cpp b/src/gui/styles/qgtkpainter.cpp index 79c53e9..0217a39 100644 --- a/src/gui/styles/qgtkpainter.cpp +++ b/src/gui/styles/qgtkpainter.cpp @@ -241,8 +241,10 @@ void QGtkPainter::paintBoxGap(GtkWidget *gtkWidget, const gchar* part, if (rect.height() > maxHeight && (gap_side == GTK_POS_TOP || gap_side == GTK_POS_BOTTOM)) rect.setHeight(2 * border + 1); - QString gapExtras = QString(QLS("s %0 w %1 g %2")).arg(gap_side).arg(width).arg(x); - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) + gapExtras; + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) + % HexString<uchar>(gap_side) + % HexString<gint>(width) + % HexString<gint>(x); if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_box_gap (style, @@ -307,7 +309,7 @@ void QGtkPainter::paintBox(GtkWidget *gtkWidget, const gchar* part, rect.setHeight(2 * border + 1); QString pixmapName = uniqueName(QLS(part), state, shadow, - rect.size(), gtkWidget) + pmKey; + rect.size(), gtkWidget) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_box (style, @@ -357,9 +359,11 @@ void QGtkPainter::paintHline(GtkWidget *gtkWidget, const gchar* part, return; QPixmap cache; - QString hLineExtras = QString(QLS("%0 %1 %2")).arg(x1).arg(x2).arg(y); QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) - + hLineExtras + pmKey; + % HexString<int>(x1) + % HexString<int>(x2) + % HexString<int>(y) + % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_hline (style, pixmap, @@ -384,9 +388,12 @@ void QGtkPainter::paintVline(GtkWidget *gtkWidget, const gchar* part, return; QPixmap cache; - QString vLineExtras = QString(QLS("%0 %1 %2")).arg(y1).arg(y2).arg(x); - QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), - gtkWidget) + vLineExtras +pmKey; + QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) + % HexString<int>(y1) + % HexString<int>(y2) + % HexString<int>(x) + % pmKey; + if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_vline (style, pixmap, @@ -412,8 +419,10 @@ void QGtkPainter::paintExpander(GtkWidget *gtkWidget, return; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), - gtkWidget) + QString::number(expander_state) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) + % HexString<uchar>(expander_state) + % pmKey; + if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_expander (style, pixmap, state, NULL, @@ -436,7 +445,7 @@ void QGtkPainter::paintFocus(GtkWidget *gtkWidget, const gchar* part, return; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_focus (style, pixmap, state, NULL, gtkWidget, @@ -461,7 +470,7 @@ void QGtkPainter::paintResizeGrip(GtkWidget *gtkWidget, const gchar* part, return; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_resize_grip (style, pixmap, state, NULL, gtkWidget, @@ -486,8 +495,9 @@ void QGtkPainter::paintArrow(GtkWidget *gtkWidget, const gchar* part, return; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) + - QString::number((int)arrow_type) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) + % HexString<uchar>(arrow_type) + % pmKey; GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()}; int xOffset = m_cliprect.isValid() ? arrowrect.x() - m_cliprect.x() : 0; @@ -518,7 +528,8 @@ void QGtkPainter::paintHandle(GtkWidget *gtkWidget, const gchar* part, const QRe QPixmap cache; QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) - + QString::number(orientation); + % HexString<uchar>(orientation); + if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_handle (style, pixmap, @@ -546,7 +557,7 @@ void QGtkPainter::paintSlider(GtkWidget *gtkWidget, const gchar* part, const QRe return; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_slider (style, pixmap, @@ -577,7 +588,7 @@ void QGtkPainter::paintShadow(GtkWidget *gtkWidget, const gchar* part, QRect r = rect; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_shadow(style, pixmap, state, shadow, NULL, gtkWidget, part, 0, 0, rect.width(), rect.height())); @@ -596,7 +607,7 @@ void QGtkPainter::paintFlatBox(GtkWidget *gtkWidget, const gchar* part, return; QRect r = rect; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_flat_box (style, pixmap, @@ -623,8 +634,8 @@ void QGtkPainter::paintExtention(GtkWidget *gtkWidget, QRect r = rect; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget); - pixmapName += QString::number(gap_pos); + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) + % HexString<uchar>(gap_pos); if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_extension (style, pixmap, state, shadow, diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 9d6dc9a..b59a033 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -67,6 +67,7 @@ #include <QtGui/QRadioButton> #include <QtGui/QCheckBox> #include <QtGui/QTreeView> +#include <QtGui/QStyledItemDelegate> #include <qpixmapcache.h> #undef signals // Collides with GTK stymbols #include <private/qgtkpainter_p.h> @@ -692,7 +693,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, // thin rectangular images const int pmSize = 64; const int border = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget); - const QString pmKey = QString(QLS("windowframe %0")).arg(option->state); + const QString pmKey = QLatin1Literal("windowframe") % HexString<uint>(option->state); QPixmap pixmap; QRect pmRect(QPoint(0,0), QSize(pmSize, pmSize)); @@ -817,24 +818,49 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, option->state & State_Open ? openState : closedState , gtkTreeView->style); } break; + + case PE_PanelItemViewRow: + // This primitive is only used to draw selection behind selected expander arrows. + // We try not to decorate the tree branch background unless you inherit from StyledItemDelegate + // The reason for this is that a lot of code that relies on custom item delegates will look odd having + // a gradient on the branch but a flat shaded color on the item itself. + QCommonStyle::drawPrimitive(element, option, painter, widget); + if (!option->state & State_Selected) { + break; + } else { + if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(widget)) { + if (!qobject_cast<QStyledItemDelegate*>(view->itemDelegate())) + break; + } + } // fall through + case PE_PanelItemViewItem: if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) { - if (vopt->state & State_Selected) { - QLinearGradient gradient; - gradient.setStart(option->rect.left(), option->rect.top()); - gradient.setFinalStop(option->rect.left(), option->rect.bottom()); - gradient.setColorAt(0, option->palette.highlight().color().lighter(105)); - gradient.setColorAt(0.5, option->palette.highlight().color().lighter(101)); - gradient.setColorAt(0.51, option->palette.highlight().color().darker(101)); - gradient.setColorAt(1, option->palette.highlight().color().darker(105)); - painter->fillRect(option->rect, gradient); - } else { - if (vopt->backgroundBrush.style() != Qt::NoBrush) { - QPointF oldBO = painter->brushOrigin(); - painter->setBrushOrigin(vopt->rect.topLeft()); - painter->fillRect(vopt->rect, vopt->backgroundBrush); - painter->setBrushOrigin(oldBO); + if (vopt->backgroundBrush.style() != Qt::NoBrush) { + QPointF oldBO = painter->brushOrigin(); + painter->setBrushOrigin(vopt->rect.topLeft()); + painter->fillRect(vopt->rect, vopt->backgroundBrush); + painter->setBrushOrigin(oldBO); + if (!(option->state & State_Selected)) + break; + } + if (GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView")) { + const char *detail = "cell_even_ruled"; + if (vopt && vopt->features & QStyleOptionViewItemV2::Alternate) + detail = "cell_odd_ruled"; + bool isActive = option->state & State_Active; + QString key; + if (isActive ) { + // Required for active/non-active window appearance + key = QLS("a"); + GTK_WIDGET_SET_FLAGS(gtkTreeView, GTK_HAS_FOCUS); } + gtkPainter.paintFlatBox(gtkTreeView, detail, option->rect, + option->state & State_Selected ? GTK_STATE_SELECTED : + option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, + GTK_SHADOW_OUT, gtkTreeView->style, key); + if (isActive ) + GTK_WIDGET_UNSET_FLAGS(gtkTreeView, GTK_HAS_FOCUS); } } break; diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index c8711f6..20d9bd9 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -488,7 +488,9 @@ static void qBrushSetAlphaF(QBrush *brush, qreal alpha) // Modify the texture - ridiculously expensive. QPixmap texture = brush->texture(); QPixmap pixmap; - QString name = QString::fromLatin1("qbrushtexture-alpha-%1-%2").arg(alpha).arg(texture.cacheKey()); + QString name = QLatin1Literal("qbrushtexture-alpha") + % HexString<qreal>(alpha) + % HexString<qint64>(texture.cacheKey()); if (!QPixmapCache::find(name, pixmap)) { QImage image = texture.toImage(); QRgb *rgb = reinterpret_cast<QRgb *>(image.bits()); @@ -549,7 +551,10 @@ static QBrush qBrushLight(QBrush brush, int light) // Modify the texture - ridiculously expensive. QPixmap texture = brush.texture(); QPixmap pixmap; - QString name = QString::fromLatin1("qbrushtexture-light-%1-%2").arg(light).arg(texture.cacheKey()); + QString name = QLatin1Literal("qbrushtexture-light") + % HexString<int>(light) + % HexString<qint64>(texture.cacheKey()); + if (!QPixmapCache::find(name, pixmap)) { QImage image = texture.toImage(); QRgb *rgb = reinterpret_cast<QRgb *>(image.bits()); @@ -608,7 +613,10 @@ static QBrush qBrushDark(QBrush brush, int dark) // Modify the texture - ridiculously expensive. QPixmap texture = brush.texture(); QPixmap pixmap; - QString name = QString::fromLatin1("qbrushtexture-dark-%1-%2").arg(dark).arg(brush.texture().cacheKey()); + QString name = QLatin1Literal("qbrushtexture-dark") + % HexString<int>(dark) + % HexString<qint64>(texture.cacheKey()); + if (!QPixmapCache::find(name, pixmap)) { QImage image = texture.toImage(); QRgb *rgb = reinterpret_cast<QRgb *>(image.bits()); @@ -732,8 +740,12 @@ static QColor mergedColors(const QColor &colorA, const QColor &colorB, int facto static void qt_plastique_draw_gradient(QPainter *painter, const QRect &rect, const QColor &gradientStart, const QColor &gradientStop) { - QString gradientName; - gradientName.sprintf("%dx%d-%x-%x", rect.width(), rect.height(), gradientStart.rgba(), gradientStop.rgba()); + QString gradientName = QLatin1Literal("qplastique-g") + % HexString<int>(rect.width()) + % HexString<int>(rect.height()) + % HexString<QRgb>(gradientStart.rgba()) + % HexString<QRgb>(gradientStop.rgba()); + QPixmap cache; QPainter *p = painter; QRect r = rect; @@ -1092,14 +1104,6 @@ void QPlastiqueStyle::drawPrimitive(PrimitiveElement element, const QStyleOption Q_ASSERT(option); QColor borderColor = option->palette.background().color().darker(178); - QColor gradientStartColor = option->palette.button().color().lighter(104); - QColor gradientStopColor = option->palette.button().color().darker(105); - QColor highlightedGradientStartColor = option->palette.button().color().lighter(101); - QColor highlightedGradientStopColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 85); - QColor highlightedBaseGradientStartColor = option->palette.base().color(); - QColor highlightedBaseGradientStopColor = mergedColors(option->palette.base().color().darker(105), option->palette.highlight().color(), 70); - QColor highlightedDarkInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 35); - QColor highlightedLightInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 58); QColor alphaCornerColor; if (widget) { // ### backgroundrole/foregroundrole should be part of the style option @@ -1107,13 +1111,7 @@ void QPlastiqueStyle::drawPrimitive(PrimitiveElement element, const QStyleOption } else { alphaCornerColor = mergedColors(option->palette.background().color(), borderColor); } - QColor alphaInnerColor = mergedColors(highlightedLightInnerBorderColor, gradientStartColor); - QColor alphaInnerColorNoHover = mergedColors(borderColor, gradientStartColor); QColor alphaTextColor = mergedColors(option->palette.background().color(), option->palette.text().color()); - QColor alphaLightTextColor = mergedColors(option->palette.background().color().lighter(250), option->palette.text().color().lighter(250)); - QColor lightShadow = option->palette.button().color().lighter(105); - QColor shadowGradientStartColor = option->palette.button().color().darker(115); - QColor shadow = shadowGradientStartColor; switch (element) { case PE_IndicatorButtonDropDown: @@ -2057,7 +2055,6 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op bool reverse = (tab->direction == Qt::RightToLeft); int lowerTop = selected ? 0 : 3; // to make the selected tab bigger than the rest - QRect adjustedRect; bool atEnd = (tab->position == QStyleOptionTab::End) || onlyTab; bool atBeginning = ((tab->position == QStyleOptionTab::Beginning) || onlyTab) && !leftCornerWidget; diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index 515b6c7..43fa4b9 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -3190,7 +3190,7 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC subRule2.drawRule(p, r); } - handleSubRule.drawRule(p, grooveSubRule.boxRect(hr, Margin)); + handleSubRule.drawRule(p, handleSubRule.boxRect(hr, Margin)); } if (slider->subControls & SC_SliderTickmarks) { diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 0314c6f..579dd0b 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -1388,8 +1388,9 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QRect r = opt->rect; int size = qMin(r.height(), r.width()); QPixmap pixmap; - QString pixmapName = QStyleHelper::uniqueName(QLatin1String("$qt_ia-") + QLatin1String(metaObject()->className()), opt, QSize(size, size)) - + QLatin1Char('-') + QString::number(pe); + QString pixmapName = QStyleHelper::uniqueName(QLatin1String("$qt_ia-") + % QLatin1String(metaObject()->className()), opt, QSize(size, size)) + % HexString<uint>(pe); if (!QPixmapCache::find(pixmapName, pixmap)) { int border = size/5; int sqsize = 2*(size/2); diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 489b70b..943df7f 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -49,12 +49,12 @@ #include <private/qt_s60_p.h> #include "qendian.h" #include <private/qcore_symbian_p.h> -#if defined(QT_NO_FREETYPE) +#ifdef QT_NO_FREETYPE #include <openfont.h> #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS #include <graphics/openfontrasterizer.h> // COpenFontRasterizer has moved to a new header file #endif // SYMBIAN_ENABLE_SPLIT_HEADERS -#endif +#endif // QT_NO_FREETYPE QT_BEGIN_NAMESPACE @@ -91,7 +91,7 @@ QFileInfoList alternativeFilePaths(const QString &path, const QStringList &nameF return result; } -#if defined(QT_NO_FREETYPE) +#ifdef QT_NO_FREETYPE class QSymbianFontDatabaseExtrasImplementation : public QSymbianFontDatabaseExtras { public: @@ -100,16 +100,41 @@ public: const QSymbianTypeFaceExtras *extras(const QString &typeface, bool bold, bool italic) const; +#ifndef Q_SYMBIAN_HAS_FONTTABLE_API + struct CFontFromFontStoreReleaser { + static inline void cleanup(CFont *font) + { + if (!font) + return; + const QSymbianFontDatabaseExtrasImplementation *dbExtras = + static_cast<const QSymbianFontDatabaseExtrasImplementation*>(privateDb()->symbianExtras); + dbExtras->m_store->ReleaseFont(font); + } + }; +#endif // !Q_SYMBIAN_HAS_FONTTABLE_API + + struct CFontFromScreenDeviceReleaser { + static inline void cleanup(CFont *font) + { + if (!font) + return; + QS60Data::screenDevice()->ReleaseFont(font); + } + }; + private: +#ifndef Q_SYMBIAN_HAS_FONTTABLE_API RHeap* m_heap; CFontStore *m_store; COpenFontRasterizer *m_rasterizer; mutable QList<const QSymbianTypeFaceExtras *> m_extras; +#endif // !Q_SYMBIAN_HAS_FONTTABLE_API mutable QHash<QString, const QSymbianTypeFaceExtras *> m_extrasHash; }; QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementation() { +#ifndef Q_SYMBIAN_HAS_FONTTABLE_API QStringList filters; filters.append(QLatin1String("*.ttf")); filters.append(QLatin1String("*.ccc")); @@ -131,10 +156,14 @@ QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementati TPtrC fontFilePtr(qt_QString2TPtrC(fontFile)); QT_TRAP_THROWING(m_store->AddFileL(fontFilePtr)); } +#endif // !Q_SYMBIAN_HAS_FONTTABLE_API } QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementation() { +#ifdef Q_SYMBIAN_HAS_FONTTABLE_API + qDeleteAll(m_extrasHash); +#else // Q_SYMBIAN_HAS_FONTTABLE_API typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator; for (iterator p = m_extras.begin(); p != m_extras.end(); ++p) { m_store->ReleaseFont((*p)->fontOwner()); @@ -143,6 +172,7 @@ QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementat delete m_store; m_heap->Close(); +#endif // Q_SYMBIAN_HAS_FONTTABLE_API } #ifndef FNTSTORE_H_INLINES_SUPPORT_FMM @@ -167,26 +197,37 @@ const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(c { const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic)); if (!m_extrasHash.contains(searchKey)) { - CFont* font = NULL; TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1); if (bold) searchSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); if (italic) searchSpec.iFontStyle.SetPosture(EPostureItalic); + + CFont* font = NULL; +#ifdef Q_SYMBIAN_HAS_FONTTABLE_API + const TInt err = QS60Data::screenDevice()->GetNearestFontToDesignHeightInPixels(font, searchSpec); + Q_ASSERT(err == KErrNone && font); + QScopedPointer<CFont, CFontFromScreenDeviceReleaser> sFont(font); + QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font); + sFont.take(); + m_extrasHash.insert(searchKey, extras); +#else // Q_SYMBIAN_HAS_FONTTABLE_API const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec); Q_ASSERT(err == KErrNone && font); const CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font); COpenFont *openFont = #ifdef FNTSTORE_H_INLINES_SUPPORT_FMM - bitmapFont->openFont(); -#else + bitmapFont->OpenFont(); +#else // FNTSTORE_H_INLINES_SUPPORT_FMM OpenFontFromBitmapFont(bitmapFont); #endif // FNTSTORE_H_INLINES_SUPPORT_FMM const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib(); const QString foundKey = QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length()); if (!m_extrasHash.contains(foundKey)) { + QScopedPointer<CFont, CFontFromFontStoreReleaser> sFont(font); QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont); + sFont.take(); m_extras.append(extras); m_extrasHash.insert(searchKey, extras); m_extrasHash.insert(foundKey, extras); @@ -194,10 +235,11 @@ const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(c m_store->ReleaseFont(font); m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey)); } +#endif // Q_SYMBIAN_HAS_FONTTABLE_API } return m_extrasHash.value(searchKey); } -#else +#else // QT_NO_FREETYPE class QFontEngineFTS60 : public QFontEngineFT { public: @@ -209,7 +251,7 @@ QFontEngineFTS60::QFontEngineFTS60(const QFontDef &fd) { default_hint_style = HintFull; } -#endif // defined(QT_NO_FREETYPE) +#endif // QT_NO_FREETYPE /* QFontEngineS60::pixelsToPoints, QFontEngineS60::pointsToPixels, QFontEngineMultiS60::QFontEngineMultiS60 @@ -261,12 +303,12 @@ static void initializeDb() if(!db || db->count) return; -#if defined(QT_NO_FREETYPE) +#ifdef QT_NO_FREETYPE if (!db->symbianExtras) db->symbianExtras = new QSymbianFontDatabaseExtrasImplementation; QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); - + const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces(); const QSymbianFontDatabaseExtrasImplementation *dbExtras = static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras); @@ -278,6 +320,7 @@ static void initializeDb() TFontSpec fontSpec(typefaceSupport.iTypeface.iName, 11); if (QS60Data::screenDevice()->GetNearestFontInPixels(font, fontSpec) != KErrNone) continue; + QScopedPointer<CFont, QSymbianFontDatabaseExtrasImplementation::CFontFromScreenDeviceReleaser> sFont(font); if (font->TypeUid() == KCFbsFontUid) { TOpenFontFaceAttrib faceAttrib; const CFbsFont *cfbsFont = static_cast<const CFbsFont *>(font); @@ -318,14 +361,13 @@ static void initializeDb() fontAdded = true; } - QS60Data::screenDevice()->ReleaseFont(font); } Q_ASSERT(fontAdded); - lock.relock(); + lock.relock(); -#else // defined(QT_NO_FREETYPE) +#else // QT_NO_FREETYPE QDir dir(QDesktopServices::storageLocation(QDesktopServices::FontsLocation)); dir.setNameFilters(QStringList() << QLatin1String("*.ttf") << QLatin1String("*.ttc") << QLatin1String("*.pfa") @@ -334,7 +376,7 @@ static void initializeDb() const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i])); db->addTTFile(file); } -#endif // defined(QT_NO_FREETYPE) +#endif // QT_NO_FREETYPE } static inline void load(const QString &family = QString(), int script = -1) @@ -416,13 +458,13 @@ QFontEngine *QFontDatabase::findFont(int script, const QFontPrivate *, const QFo const QString fontFamily = desc.family->name; QFontDef request = req; request.family = fontFamily; -#if defined(QT_NO_FREETYPE) +#ifdef QT_NO_FREETYPE const QSymbianFontDatabaseExtrasImplementation *dbExtras = static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras); const QSymbianTypeFaceExtras *typeFaceExtras = dbExtras->extras(fontFamily, request.weight > QFont::Normal, request.style != QFont::StyleNormal); fe = new QFontEngineS60(request, typeFaceExtras); -#else +#else // QT_NO_FREETYPE QFontEngine::FaceId faceId; const QtFontFamily * const reqQtFontFamily = db->family(fontFamily); faceId.filename = reqQtFontFamily->fontFilename; @@ -433,7 +475,7 @@ QFontEngine *QFontDatabase::findFont(int script, const QFontPrivate *, const QFo fe = fte; else delete fte; -#endif +#endif // QT_NO_FREETYPE Q_ASSERT(fe); if (script == QUnicodeTables::Common diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp index 93f02ff..925b3bf 100644 --- a/src/gui/text/qfontengine_s60.cpp +++ b/src/gui/text/qfontengine_s60.cpp @@ -50,21 +50,73 @@ #include <e32std.h> #include <eikenv.h> #include <gdi.h> +#if defined(Q_SYMBIAN_HAS_FONTTABLE_API) || defined(Q_SYMBIAN_HAS_GLYPHOUTLINE_API) +#include <graphics/gdi/gdiplatapi.h> +#endif // Q_SYMBIAN_HAS_FONTTABLE_API || Q_SYMBIAN_HAS_GLYPHOUTLINE_API QT_BEGIN_NAMESPACE -QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* fontOwner, COpenFont *font) - : m_font(font) - , m_cmap(0) +#ifdef Q_SYMBIAN_HAS_FONTTABLE_API +QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont) + : m_cFont(cFont) , m_symbolCMap(false) - , m_fontOwner(fontOwner) +{ + Q_UNUSED(openFont) +} + +QSymbianTypeFaceExtras::~QSymbianTypeFaceExtras() +{ + QS60Data::screenDevice()->ReleaseFont(m_cFont); +} + +QByteArray QSymbianTypeFaceExtras::getSfntTable(uint tag) const +{ + RFontTable fontTable; + if (fontTable.Open(*m_cFont, tag) != KErrNone) + return QByteArray(); + const QByteArray byteArray(reinterpret_cast<const char *> + (fontTable.TableContent()),fontTable.TableLength()); + fontTable.Close(); + return byteArray; +} + +bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *length) const +{ + RFontTable fontTable; + if (fontTable.Open(*m_cFont, tag) != KErrNone) + return false; + + bool result = true; + const TInt tableByteLength = fontTable.TableLength(); + + if (*length > 0 && *length < tableByteLength) { + result = false; // Caller did not allocate enough memory + } else { + *length = tableByteLength; + if (buffer) + qMemCopy(buffer, fontTable.TableContent(), tableByteLength); + } + + fontTable.Close(); + return result; +} + +#else // Q_SYMBIAN_HAS_FONTTABLE_API +QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont) + : m_cFont(cFont) + , m_symbolCMap(false) + , m_openFont(openFont) { TAny *trueTypeExtension = NULL; - m_font->ExtendedInterface(KUidOpenFontTrueTypeExtension, trueTypeExtension); + m_openFont->ExtendedInterface(KUidOpenFontTrueTypeExtension, trueTypeExtension); m_trueTypeExtension = static_cast<MOpenFontTrueTypeExtension*>(trueTypeExtension); Q_ASSERT(m_trueTypeExtension); } +QSymbianTypeFaceExtras::~QSymbianTypeFaceExtras() +{ +} + QByteArray QSymbianTypeFaceExtras::getSfntTable(uint tag) const { Q_ASSERT(m_trueTypeExtension->HasTrueTypeTable(tag)); @@ -100,23 +152,25 @@ bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *len m_trueTypeExtension->ReleaseTrueTypeTable(table); return result; } +#endif // Q_SYMBIAN_HAS_FONTTABLE_API -const unsigned char *QSymbianTypeFaceExtras::cmap() const +const uchar *QSymbianTypeFaceExtras::cmap() const { - if (!m_cmap) { - m_cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p')); + if (m_cmapTable.isNull()) { + const QByteArray cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p')); int size = 0; - m_cmap = QFontEngineS60::getCMap(reinterpret_cast<const uchar *>(m_cmapTable.constData()), m_cmapTable.size(), &m_symbolCMap, &size); + const uchar *cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *> + (cmapTable.constData()), cmapTable.size(), &m_symbolCMap, &size); + m_cmapTable = QByteArray(reinterpret_cast<const char *>(cmap), size); } - return m_cmap; + return reinterpret_cast<const uchar *>(m_cmapTable.constData()); } CFont *QSymbianTypeFaceExtras::fontOwner() const { - return m_fontOwner; + return m_cFont; } - // duplicated from qfontengine_xyz.cpp static inline unsigned int getChar(const QChar *str, int &i, const int len) { @@ -225,6 +279,35 @@ void QFontEngineS60::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla } } +#ifdef Q_SYMBIAN_HAS_GLYPHOUTLINE_API +static bool parseGlyphPathData(const char *dataStr, const char *dataEnd, QPainterPath &path, + qreal fontPixelSize, const QPointF &offset, bool hinted); +#endif //Q_SYMBIAN_HAS_GLYPHOUTLINE_API + +void QFontEngineS60::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, + int nglyphs, QPainterPath *path, + QTextItem::RenderFlags flags) +{ +#ifdef Q_SYMBIAN_HAS_GLYPHOUTLINE_API + Q_UNUSED(flags) + RGlyphOutlineIterator iterator; + const TInt error = iterator.Open(*m_activeFont, glyphs, nglyphs); + if (KErrNone != error) + return; + const qreal fontSizeInPixels = qreal(m_activeFont->HeightInPixels()); + int count = 0; + do { + const TUint8* outlineUint8 = iterator.Outline(); + const char* const outlineChar = reinterpret_cast<const char*>(outlineUint8); + const char* const outlineEnd = outlineChar + iterator.OutlineLength(); + parseGlyphPathData(outlineChar, outlineEnd, *path, fontSizeInPixels, + positions[count++].toPointF(), false); + } while(KErrNone == iterator.Next() && count <= nglyphs); +#else // Q_SYMBIAN_HAS_GLYPHOUTLINE_API + QFontEngine::addGlyphsToPath(glyphs, positions, nglyphs, path, flags); +#endif //Q_SYMBIAN_HAS_GLYPHOUTLINE_API +} + QImage QFontEngineS60::alphaMapForGlyph(glyph_t glyph) { TOpenFontCharMetrics metrics; @@ -356,4 +439,69 @@ void QFontEngineS60::getCharacterData(glyph_t glyph, TOpenFontCharMetrics& metri } } +#ifdef Q_SYMBIAN_HAS_GLYPHOUTLINE_API +static inline void skipSpacesAndComma(const char* &str, const char* const strEnd) +{ + while (str <= strEnd && (*str == ' ' || *str == ',')) + ++str; +} + +static bool parseGlyphPathData(const char *svgPath, const char *svgPathEnd, QPainterPath &path, + qreal fontPixelSize, const QPointF &offset, bool hinted) +{ + Q_UNUSED(hinted) + QPointF p1, p2, firstSubPathPoint; + qreal *elementValues[] = + {&p1.rx(), &p1.ry(), &p2.rx(), &p2.ry()}; + const int unitsPerEm = 2048; // See: http://en.wikipedia.org/wiki/Em_%28typography%29 + const qreal resizeFactor = fontPixelSize / unitsPerEm; + + while (svgPath < svgPathEnd) { + skipSpacesAndComma(svgPath, svgPathEnd); + const char pathElem = *svgPath++; + skipSpacesAndComma(svgPath, svgPathEnd); + + if (pathElem != 'Z') { + char *endStr = 0; + int elementValuesCount = 0; + for (int i = 0; i < 4; ++i) { // 4 = size of elementValues[] + qreal coordinateValue = strtod(svgPath, &endStr); + if (svgPath == endStr) + break; + if (i % 2) // Flip vertically + coordinateValue = -coordinateValue; + *elementValues[i] = coordinateValue * resizeFactor; + elementValuesCount++; + svgPath = endStr; + skipSpacesAndComma(svgPath, svgPathEnd); + } + p1 += offset; + if (elementValuesCount == 2) + p2 = firstSubPathPoint; + else + p2 += offset; + } + + switch (pathElem) { + case 'M': + firstSubPathPoint = p1; + path.moveTo(p1); + break; + case 'Z': + path.closeSubpath(); + break; + case 'L': + path.lineTo(p1); + break; + case 'Q': + path.quadTo(p1, p2); + break; + default: + return false; + } + } + return true; +} +#endif // Q_SYMBIAN_HAS_GLYPHOUTLINE_API + QT_END_NAMESPACE diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h index 6883730..beeb4cc 100644 --- a/src/gui/text/qfontengine_s60_p.h +++ b/src/gui/text/qfontengine_s60_p.h @@ -58,6 +58,14 @@ #include "qsize.h" #include <openfont.h> +#ifdef SYMBIAN_GDI_GLYPHDATA +#define Q_SYMBIAN_HAS_FONTTABLE_API +#endif + +#ifdef Q_SYMBIAN_HAS_FONTTABLE_API +#define Q_SYMBIAN_HAS_GLYPHOUTLINE_API +#endif // Q_SYMBIAN_HAS_FONTTABLE_API + class CFont; QT_BEGIN_NAMESPACE @@ -66,20 +74,22 @@ QT_BEGIN_NAMESPACE class QSymbianTypeFaceExtras { public: - QSymbianTypeFaceExtras(CFont* fontOwner, COpenFont *font); + QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont = 0); + ~QSymbianTypeFaceExtras(); QByteArray getSfntTable(uint tag) const; bool getSfntTableData(uint tag, uchar *buffer, uint *length) const; - const unsigned char *cmap() const; + const uchar *cmap() const; CFont *fontOwner() const; private: - COpenFont *m_font; - mutable MOpenFontTrueTypeExtension *m_trueTypeExtension; - mutable const unsigned char *m_cmap; + CFont* m_cFont; mutable bool m_symbolCMap; mutable QByteArray m_cmapTable; - CFont* m_fontOwner; +#ifndef Q_SYMBIAN_HAS_FONTTABLE_API + COpenFont *m_openFont; + mutable MOpenFontTrueTypeExtension *m_trueTypeExtension; +#endif // Q_SYMBIAN_HAS_FONTTABLE_API }; class QFontEngineS60 : public QFontEngine @@ -91,6 +101,9 @@ public: bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const; + void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, + QPainterPath *path, QTextItem::RenderFlags flags); + QImage alphaMapForGlyph(glyph_t glyph); glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 5163c94..d02e841 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -526,6 +526,14 @@ int QFontMetrics::rightBearing(QChar ch) const */ int QFontMetrics::width(const QString &text, int len) const { + return width(text, len, 0); +} + +/*! + \internal +*/ +int QFontMetrics::width(const QString &text, int len, int flags) const +{ int pos = text.indexOf(QLatin1Char('\x9c')); if (pos != -1) { len = (len < 0) ? pos : qMin(pos, len); @@ -535,6 +543,23 @@ int QFontMetrics::width(const QString &text, int len) const if (len == 0) return 0; + if (flags & Qt::TextBypassShaping) { + // Skip harfbuzz complex shaping, only use advances + int numGlyphs = len; + QVarLengthGlyphLayoutArray glyphs(numGlyphs); + QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0)) { + glyphs.resize(numGlyphs); + if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0)) + Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice"); + } + + QFixed width; + for (int i = 0; i < numGlyphs; ++i) + width += glyphs.advances_x[i]; + return qRound(width); + } + QStackTextEngine layout(text, d.data()); layout.ignoreBidi = true; return qRound(layout.width(0, len)); diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h index dca4b93..2518b54 100644 --- a/src/gui/text/qfontmetrics.h +++ b/src/gui/text/qfontmetrics.h @@ -89,6 +89,7 @@ public: int leftBearing(QChar) const; int rightBearing(QChar) const; int width(const QString &, int len = -1) const; + int width(const QString &, int len, int flags) const; int width(QChar) const; int charWidth(const QString &str, int pos) const; diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index 84c1d96..10870aa 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -115,10 +115,12 @@ QT_BEGIN_NAMESPACE Qt::RichText. If it's the first time the static text is drawn, or if the static text, or the painter's font - or matrix have been altered since the last time it was drawn, the text's layout has to be - recalculated. This will impose an overhead on the QPainter::drawStaticText() call where the - relayout occurs. To avoid this overhead in the paint event, you can call prepare() ahead of - time to ensure that the layout is calculated. + has been altered since the last time it was drawn, the text's layout has to be + recalculated. On some paint engines, changing the matrix of the painter will also cause the + layout to be recalculated. In particular, this will happen for any engine except for the + OpenGL2 paint engine. Recalculating the layout will impose an overhead on the + QPainter::drawStaticText() call where it occurs. To avoid this overhead in the paint event, you + can call prepare() ahead of time to ensure that the layout is calculated. \sa QPainter::drawText(), QPainter::drawStaticText(), QTextLayout, QTextDocument */ @@ -188,8 +190,9 @@ void QStaticText::detach() When drawStaticText() is called, the layout of the QStaticText will be recalculated if any part of the QStaticText object has changed since the last time it was drawn. It will also be - recalculated if the painter's font or matrix are not the same as when the QStaticText was last - drawn. + recalculated if the painter's font is not the same as when the QStaticText was last drawn, or, + on any other paint engine than the OpenGL2 engine, if the painter's matrix has been altered + since the static text was last drawn. To avoid the overhead of creating the layout the first time you draw the QStaticText after making changes, you can use the prepare() function and pass in the \a matrix and \a font you @@ -364,14 +367,16 @@ QSizeF QStaticText::size() const QStaticTextPrivate::QStaticTextPrivate() : textWidth(-1.0), items(0), itemCount(0), glyphPool(0), positionPool(0), charPool(0), - needsRelayout(true), useBackendOptimizations(false), textFormat(Qt::AutoText) + needsRelayout(true), useBackendOptimizations(false), textFormat(Qt::AutoText), + untransformedCoordinates(false) { } QStaticTextPrivate::QStaticTextPrivate(const QStaticTextPrivate &other) : text(other.text), font(other.font), textWidth(other.textWidth), matrix(other.matrix), items(0), itemCount(0), glyphPool(0), positionPool(0), charPool(0), needsRelayout(true), - useBackendOptimizations(other.useBackendOptimizations), textFormat(other.textFormat) + useBackendOptimizations(other.useBackendOptimizations), textFormat(other.textFormat), + untransformedCoordinates(other.untransformedCoordinates) { } @@ -396,8 +401,9 @@ namespace { class DrawTextItemRecorder: public QPaintEngine { public: - DrawTextItemRecorder(bool useBackendOptimizations, int numChars) - : m_dirtyPen(false), m_useBackendOptimizations(useBackendOptimizations) + DrawTextItemRecorder(bool untransformedCoordinates, bool useBackendOptimizations, int numChars) + : m_dirtyPen(false), m_useBackendOptimizations(useBackendOptimizations), + m_untransformedCoordinates(untransformedCoordinates) { } @@ -423,7 +429,7 @@ namespace { if (m_dirtyPen) currentItem.color = state->pen().color(); - QTransform matrix = state->transform(); + QTransform matrix = m_untransformedCoordinates ? QTransform() : state->transform(); matrix.translate(position.x(), position.y()); QVarLengthArray<glyph_t> glyphs; @@ -486,14 +492,17 @@ namespace { bool m_dirtyPen; bool m_useBackendOptimizations; + bool m_untransformedCoordinates; }; class DrawTextItemDevice: public QPaintDevice { public: - DrawTextItemDevice(bool useBackendOptimizations, int numChars) + DrawTextItemDevice(bool untransformedCoordinates, bool useBackendOptimizations, + int numChars) { - m_paintEngine = new DrawTextItemRecorder(useBackendOptimizations, numChars); + m_paintEngine = new DrawTextItemRecorder(untransformedCoordinates, + useBackendOptimizations, numChars); } ~DrawTextItemDevice() @@ -629,7 +638,7 @@ void QStaticTextPrivate::init() position = QPointF(0, 0); - DrawTextItemDevice device(useBackendOptimizations, text.size()); + DrawTextItemDevice device(untransformedCoordinates, useBackendOptimizations, text.size()); { QPainter painter(&device); painter.setFont(font); diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h index 2ab5579..1a96291 100644 --- a/src/gui/text/qstatictext_p.h +++ b/src/gui/text/qstatictext_p.h @@ -148,9 +148,10 @@ public: QFixedPoint *positionPool; // 4 bytes per text QChar *charPool; // 4 bytes per text - unsigned char needsRelayout : 1; - unsigned char useBackendOptimizations : 1; // 1 byte per text - unsigned char textFormat : 2; + unsigned char needsRelayout : 1; // 1 byte per text + unsigned char useBackendOptimizations : 1; + unsigned char textFormat : 2; + unsigned char untransformedCoordinates : 1; // ================ // 167 bytes per text diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index c91df3c..d6ac3aa 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -64,7 +64,7 @@ enum { QTextCursorPrivate::QTextCursorPrivate(QTextDocumentPrivate *p) : priv(p), x(0), position(0), anchor(0), adjusted_anchor(0), - currentCharFormat(-1), visualNavigation(false) + currentCharFormat(-1), visualNavigation(false), keepPositionOnInsert(false) { priv->addCursor(this); } @@ -79,6 +79,7 @@ QTextCursorPrivate::QTextCursorPrivate(const QTextCursorPrivate &rhs) x = rhs.x; currentCharFormat = rhs.currentCharFormat; visualNavigation = rhs.visualNavigation; + keepPositionOnInsert = rhs.keepPositionOnInsert; priv->addCursor(this); } @@ -95,7 +96,7 @@ QTextCursorPrivate::AdjustResult QTextCursorPrivate::adjustPosition(int position if (position < positionOfChange || (position == positionOfChange && (op == QTextUndoCommand::KeepCursor - || anchor < position) + || keepPositionOnInsert) ) ) { result = CursorUnchanged; @@ -1276,6 +1277,80 @@ void QTextCursor::setVisualNavigation(bool b) d->visualNavigation = b; } + +/*! + \since 4.7 + + Sets the visual x position for vertical cursor movements. + + The vertical movement x position is cleared automatically when the cursor moves horizontally, and kept + unchanged when the cursor moves vertically. The mechanism allows the cursor to move up and down on a + visually straight line with proportional fonts, and to gently "jump" over short lines. + + A value of -1 indicates no predefined x position. It will then be set automatically the next time the + cursor moves up or down. + + \sa verticalMovementX() + */ +void QTextCursor::setVerticalMovementX(int x) +{ + if (d) + d->x = x; +} + +/*! \since 4.7 + + Returns the visual x position for vertical cursor movements. + + A value of -1 indicates no predefined x position. It will then be set automatically the next time the + cursor moves up or down. + + \sa setVerticalMovementX() + */ +int QTextCursor::verticalMovementX() const +{ + return d ? d->x : -1; +} + +/*! + \since 4.7 + + Returns whether the cursor should keep its current position when text gets inserted at the position of the + cursor. + + The default is false; + + \sa setKeepPositionOnInsert() + */ +bool QTextCursor::keepPositionOnInsert() const +{ + return d ? d->keepPositionOnInsert : false; +} + +/*! + \since 4.7 + + Defines whether the cursor should keep its current position when text gets inserted at the current position of the + cursor. + + If \b is true, the cursor keeps its current position when text gets inserted at the positing of the cursor. + If \b is false, the cursor moves along with the inserted text. + + The default is false. + + Note that a cursor always moves when text is inserted before the current position of the cursor, and it + always keeps its position when text is inserted after the current position of the cursor. + + \sa keepPositionOnInsert() + */ +void QTextCursor::setKeepPositionOnInsert(bool b) +{ + if (d) + d->keepPositionOnInsert = b; +} + + + /*! Inserts \a text at the current position, using the current character format. @@ -1408,16 +1483,16 @@ void QTextCursor::deletePreviousChar() { if (!d || !d->priv) return; - + if (d->position != d->anchor) { removeSelectedText(); return; } - + if (d->anchor < 1 || !d->canDelete(d->anchor-1)) return; d->anchor--; - + QTextDocumentPrivate::FragmentIterator fragIt = d->priv->find(d->anchor); const QTextFragmentData * const frag = fragIt.value(); int fpos = fragIt.position(); @@ -1429,7 +1504,7 @@ void QTextCursor::deletePreviousChar() if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) --d->anchor; } - + d->adjusted_anchor = d->anchor; d->remove(); d->setX(); diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index 3e968a3..251cb33 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -132,6 +132,12 @@ public: bool visualNavigation() const; void setVisualNavigation(bool b); + void setVerticalMovementX(int x); + int verticalMovementX() const; + + void setKeepPositionOnInsert(bool b); + bool keepPositionOnInsert() const; + void deleteChar(); void deletePreviousChar(); diff --git a/src/gui/text/qtextcursor_p.h b/src/gui/text/qtextcursor_p.h index 1bdfa78..4e36b95 100644 --- a/src/gui/text/qtextcursor_p.h +++ b/src/gui/text/qtextcursor_p.h @@ -112,7 +112,8 @@ public: int anchor; int adjusted_anchor; int currentCharFormat; - bool visualNavigation; + uint visualNavigation : 1; + uint keepPositionOnInsert : 1; }; QT_END_NAMESPACE diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index f12bf0b..eeb66ce 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -79,7 +79,7 @@ Q_GUI_EXPORT extern int qt_defaultDpi(); // ################ should probably add frameFormatChange notification! -struct QLayoutStruct; +struct QTextLayoutStruct; class QTextFrameData : public QTextFrameLayoutData { @@ -109,7 +109,7 @@ public: QFixed minimumWidth; QFixed maximumWidth; - QLayoutStruct *currentLayoutStruct; + QTextLayoutStruct *currentLayoutStruct; bool sizeDirty; bool layoutDirty; @@ -123,8 +123,8 @@ QTextFrameData::QTextFrameData() { } -struct QLayoutStruct { - QLayoutStruct() : maximumWidth(QFIXED_MAX), fullLayout(false) +struct QTextLayoutStruct { + QTextLayoutStruct() : maximumWidth(QFIXED_MAX), fullLayout(false) {} QTextFrame *frame; QFixed x_left; @@ -477,9 +477,9 @@ public: HitPoint hitTest(QTextTable *table, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; HitPoint hitTest(QTextBlock bl, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; - QLayoutStruct layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, - int layoutFrom, int layoutTo, QTextTableData *tableData, QFixed absoluteTableY, - bool withPageBreaks); + QTextLayoutStruct layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, + int layoutFrom, int layoutTo, QTextTableData *tableData, QFixed absoluteTableY, + bool withPageBreaks); void setCellPosition(QTextTable *t, const QTextTableCell &cell, const QPointF &pos); QRectF layoutTable(QTextTable *t, int layoutFrom, int layoutTo, QFixed parentY); @@ -490,13 +490,13 @@ public: QRectF layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed frameWidth, QFixed frameHeight, QFixed parentY = 0); void layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, - QLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat); - void layoutFlow(QTextFrame::Iterator it, QLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, QFixed width = 0); - void pageBreakInsideTable(QTextTable *table, QLayoutStruct *layoutStruct); + QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat); + void layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, QFixed width = 0); + void pageBreakInsideTable(QTextTable *table, QTextLayoutStruct *layoutStruct); - void floatMargins(const QFixed &y, const QLayoutStruct *layoutStruct, QFixed *left, QFixed *right) const; - QFixed findY(QFixed yFrom, const QLayoutStruct *layoutStruct, QFixed requiredWidth) const; + void floatMargins(const QFixed &y, const QTextLayoutStruct *layoutStruct, QFixed *left, QFixed *right) const; + QFixed findY(QFixed yFrom, const QTextLayoutStruct *layoutStruct, QFixed requiredWidth) const; QVector<QCheckPoint> checkPoints; @@ -1487,12 +1487,12 @@ static QFixed firstChildPos(const QTextFrame *f) return flowPosition(f->begin()); } -QLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, - int layoutFrom, int layoutTo, QTextTableData *td, - QFixed absoluteTableY, bool withPageBreaks) +QTextLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, + int layoutFrom, int layoutTo, QTextTableData *td, + QFixed absoluteTableY, bool withPageBreaks) { LDEBUG << "layoutCell"; - QLayoutStruct layoutStruct; + QTextLayoutStruct layoutStruct; layoutStruct.frame = t; layoutStruct.minimumWidth = 0; layoutStruct.maximumWidth = QFIXED_MAX; @@ -1641,9 +1641,9 @@ recalc_minmax_widths: // to figure out the min and the max width lay out the cell at // maximum width. otherwise the maxwidth calculation sometimes // returns wrong values - QLayoutStruct layoutStruct = layoutCell(table, cell, QFIXED_MAX, layoutFrom, - layoutTo, td, absoluteTableY, - /*withPageBreaks =*/false); + QTextLayoutStruct layoutStruct = layoutCell(table, cell, QFIXED_MAX, layoutFrom, + layoutTo, td, absoluteTableY, + /*withPageBreaks =*/false); // distribute the minimum width over all columns the cell spans QFixed widthToDistribute = layoutStruct.minimumWidth + widthPadding; @@ -1868,10 +1868,10 @@ relayout: ++rowCellCount; const QFixed width = td->cellWidth(c, cspan) - widthPadding; - QLayoutStruct layoutStruct = layoutCell(table, cell, width, - layoutFrom, layoutTo, - td, absoluteTableY, - /*withPageBreaks =*/true); + QTextLayoutStruct layoutStruct = layoutCell(table, cell, width, + layoutFrom, layoutTo, + td, absoluteTableY, + /*withPageBreaks =*/true); const QFixed height = layoutStruct.y + bottomPadding + topPadding; @@ -1976,7 +1976,7 @@ void QTextDocumentLayoutPrivate::positionFloat(QTextFrame *frame, QTextLine *cur QTextFrameData *pd = data(parent); Q_ASSERT(pd && pd->currentLayoutStruct); - QLayoutStruct *layoutStruct = pd->currentLayoutStruct; + QTextLayoutStruct *layoutStruct = pd->currentLayoutStruct; if (!pd->floats.contains(frame)) pd->floats.append(frame); @@ -2116,7 +2116,7 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in // function. fd->contentsWidth = newContentsWidth; - QLayoutStruct layoutStruct; + QTextLayoutStruct layoutStruct; layoutStruct.frame = f; layoutStruct.x_left = fd->leftMargin + fd->border + fd->padding; layoutStruct.x_right = layoutStruct.x_left + newContentsWidth; @@ -2179,7 +2179,7 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in return layoutStruct.updateRect; } -void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QLayoutStruct *layoutStruct, +void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, QFixed width) { LDEBUG << "layoutFlow from=" << layoutFrom << "to=" << layoutTo; @@ -2509,7 +2509,7 @@ void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QLayoutStru } void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, - QLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat) + QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat) { Q_Q(QTextDocumentLayout); @@ -2718,7 +2718,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi } } -void QTextDocumentLayoutPrivate::floatMargins(const QFixed &y, const QLayoutStruct *layoutStruct, +void QTextDocumentLayoutPrivate::floatMargins(const QFixed &y, const QTextLayoutStruct *layoutStruct, QFixed *left, QFixed *right) const { // qDebug() << "floatMargins y=" << y; @@ -2740,7 +2740,7 @@ void QTextDocumentLayoutPrivate::floatMargins(const QFixed &y, const QLayoutStru // qDebug() << "floatMargins: left="<<*left<<"right="<<*right<<"y="<<y; } -QFixed QTextDocumentLayoutPrivate::findY(QFixed yFrom, const QLayoutStruct *layoutStruct, QFixed requiredWidth) const +QFixed QTextDocumentLayoutPrivate::findY(QFixed yFrom, const QTextLayoutStruct *layoutStruct, QFixed requiredWidth) const { QFixed right, left; requiredWidth = qMin(requiredWidth, layoutStruct->x_right - layoutStruct->x_left); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index dc099fc..b25795e 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -885,7 +885,7 @@ void QTextEngine::shapeText(int item) const QFixed letterSpacing = font.d->letterSpacing; QFixed wordSpacing = font.d->wordSpacing; - if (letterSpacingIsAbsolute) + if (letterSpacingIsAbsolute && letterSpacing.value()) letterSpacing *= font.d->dpi / qt_defaultDpiY(); if (letterSpacing != 0) { @@ -2653,6 +2653,12 @@ QTextItemInt::QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFo flags |= QTextItem::StrikeOut; } +QTextItemInt::QTextItemInt(const QGlyphLayout &g, QFont *font, QFontEngine *fe) + : flags(0), justified(false), underlineStyle(QTextCharFormat::NoUnderline), + num_chars(0), chars(0), logClusters(0), f(font), fontEngine(fe), glyphs(g) +{ +} + QTextItemInt QTextItemInt::midItem(QFontEngine *fontEngine, int firstGlyphIndex, int numGlyphs) const { QTextItemInt ti = *this; diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index d92148f..00b1392 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -311,6 +311,7 @@ public: logClusters(0), f(0), fontEngine(0) {} QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFormat &format = QTextCharFormat()); + QTextItemInt(const QGlyphLayout &g, QFont *font, QFontEngine *fe); /// copy the structure items, adjusting the glyphs arrays to the right subarrays. /// the width of the returned QTextItemInt is not adjusted, for speed reasons diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index b581969..8472ec6 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -91,9 +91,9 @@ static QFixed alignLine(QTextEngine *eng, const QScriptLine &line) if (align & Qt::AlignJustify && eng->option.textDirection() == Qt::RightToLeft) align = Qt::AlignRight; if (align & Qt::AlignRight) - x = line.width - (line.textWidth + leadingSpaceWidth(eng, line)); + x = line.width - (line.textAdvance + leadingSpaceWidth(eng, line)); else if (align & Qt::AlignHCenter) - x = (line.width - line.textWidth)/2; + x = (line.width - line.textAdvance)/2; } return x; } diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 8cffebd..30ce23b 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -295,8 +295,10 @@ void QAbstractScrollAreaPrivate::init() q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); layoutChildren(); #ifndef Q_WS_MAC +#ifndef QT_NO_GESTURES viewport->grabGesture(Qt::PanGesture); #endif +#endif } #ifdef Q_WS_WIN @@ -546,8 +548,10 @@ void QAbstractScrollArea::setViewport(QWidget *widget) d->viewport->setFocusProxy(this); d->viewport->installEventFilter(d->viewportFilter.data()); #ifndef Q_WS_MAC +#ifndef QT_NO_GESTURES d->viewport->grabGesture(Qt::PanGesture); #endif +#endif d->layoutChildren(); if (isVisible()) d->viewport->show(); @@ -960,6 +964,7 @@ bool QAbstractScrollArea::event(QEvent *e) case QEvent::TouchUpdate: case QEvent::TouchEnd: return false; +#ifndef QT_NO_GESTURES case QEvent::Gesture: { QGestureEvent *ge = static_cast<QGestureEvent *>(e); @@ -980,6 +985,7 @@ bool QAbstractScrollArea::event(QEvent *e) } return false; } +#endif // QT_NO_GESTURES case QEvent::StyleChange: case QEvent::LayoutDirectionChange: case QEvent::ApplicationLayoutDirectionChange: @@ -1036,9 +1042,11 @@ bool QAbstractScrollArea::viewportEvent(QEvent *e) #endif return QFrame::event(e); case QEvent::LayoutRequest: +#ifndef QT_NO_GESTURES case QEvent::Gesture: case QEvent::GestureOverride: return event(e); +#endif default: break; } diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index 2734fba..21c2635 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -1476,6 +1476,7 @@ bool QPlainTextEdit::event(QEvent *e) d->sendControlEvent(e); } #endif +#ifndef QT_NO_GESTURES else if (e->type() == QEvent::Gesture) { QGestureEvent *ge = static_cast<QGestureEvent *>(e); QPanGesture *g = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture)); @@ -1499,6 +1500,7 @@ bool QPlainTextEdit::event(QEvent *e) } return true; } +#endif // QT_NO_GESTURES return QAbstractScrollArea::event(e); } diff --git a/src/gui/widgets/qprogressbar.h b/src/gui/widgets/qprogressbar.h index b461a21..58bc8b2 100644 --- a/src/gui/widgets/qprogressbar.h +++ b/src/gui/widgets/qprogressbar.h @@ -93,9 +93,11 @@ public: Qt::Orientation orientation() const; void setInvertedAppearance(bool invert); - bool invertedAppearance(); + bool invertedAppearance(); //### Qt5 make const + bool invertedAppearance() const { return const_cast<QProgressBar *>(this)->invertedAppearance(); } void setTextDirection(QProgressBar::Direction textDirection); - QProgressBar::Direction textDirection(); + QProgressBar::Direction textDirection(); //### Qt5 make const + QProgressBar::Direction textDirection() const { return const_cast<QProgressBar *>(this)->textDirection(); } void setFormat(const QString &format); QString format() const; diff --git a/src/gui/widgets/qstackedwidget.cpp b/src/gui/widgets/qstackedwidget.cpp index 6c4061c..57b43b5 100644 --- a/src/gui/widgets/qstackedwidget.cpp +++ b/src/gui/widgets/qstackedwidget.cpp @@ -228,11 +228,11 @@ int QStackedWidget::insertWidget(int index, QWidget *widget) } /*! - Removes the given \a widget from the QStackedWidget. + Removes \a widget from the QStackedWidget. i.e., \a widget is \e + not deleted but simply removed from the stacked layout, causing it + to be hidden. - \bold{Note:} The ownership of \a widget remains the same. - The widget is \e not deleted, but simply removed from the widget's - stacked layout, causing it to be hidden. + \bold{Note:} Ownership of \a widget reverts to the application. \sa addWidget(), insertWidget(), currentWidget() */ |