summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorWarwick Allison <warwick.allison@nokia.com>2009-11-09 07:43:42 (GMT)
committerWarwick Allison <warwick.allison@nokia.com>2009-11-09 07:43:42 (GMT)
commitd2bcb0dfbc79c382dad87d3d2154ca127ae8fc16 (patch)
treec0848d1fc8fd2215fe32d75dcbe86354b0344282 /src/gui
parentdbbe24f0f04e5a0aaf9223b73bee873e208a1fa7 (diff)
parentb8b7f98b01d9ad03fecac7a0f593ac5734d7af1d (diff)
downloadQt-d2bcb0dfbc79c382dad87d3d2154ca127ae8fc16.zip
Qt-d2bcb0dfbc79c382dad87d3d2154ca127ae8fc16.tar.gz
Qt-d2bcb0dfbc79c382dad87d3d2154ca127ae8fc16.tar.bz2
Merge branch '4.6' of git://scm.dev.nokia.troll.no/qt/qt into kinetic-declarativeui
Conflicts: configure.exe src/corelib/animation/qabstractanimation.cpp src/gui/graphicsview/qgraphicsview.cpp src/s60installs/s60installs.pro tools/configure/configureapp.cpp tools/qdoc3/node.h
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/accessible/qaccessible.h7
-rw-r--r--src/gui/accessible/qaccessible2.cpp12
-rw-r--r--src/gui/accessible/qaccessible2.h13
-rw-r--r--src/gui/accessible/qaccessible_mac.mm5
-rw-r--r--src/gui/dialogs/qcolordialog_mac.mm30
-rw-r--r--src/gui/dialogs/qfiledialog.cpp10
-rw-r--r--src/gui/dialogs/qfiledialog_mac.mm12
-rw-r--r--src/gui/effects/qgraphicseffect.cpp95
-rw-r--r--src/gui/effects/qgraphicseffect.h16
-rw-r--r--src/gui/effects/qgraphicseffect_p.h6
-rw-r--r--src/gui/egl/egl.pri10
-rw-r--r--src/gui/graphicsview/qgraph_p.h16
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.cpp21
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.cpp937
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.h198
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp121
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h11
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h20
-rw-r--r--src/gui/graphicsview/qgraphicslinearlayout.cpp3
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp187
-rw-r--r--src/gui/graphicsview/qgraphicsscene.h1
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h12
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp33
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp27
-rw-r--r--src/gui/graphicsview/qgraphicswidget.h4
-rw-r--r--src/gui/graphicsview/qsimplex_p.cpp2
-rw-r--r--src/gui/graphicsview/qsimplex_p.h2
-rw-r--r--src/gui/image/qbitmap.cpp2
-rw-r--r--src/gui/image/qimage.cpp3
-rw-r--r--src/gui/image/qimagepixmapcleanuphooks.cpp18
-rw-r--r--src/gui/image/qimagepixmapcleanuphooks_p.h4
-rw-r--r--src/gui/image/qpixmap.cpp68
-rw-r--r--src/gui/image/qpixmap_mac.cpp15
-rw-r--r--src/gui/image/qpixmap_qws.cpp8
-rw-r--r--src/gui/image/qpixmap_s60.cpp35
-rw-r--r--src/gui/image/qpixmap_win.cpp3
-rw-r--r--src/gui/image/qpixmap_x11.cpp11
-rw-r--r--src/gui/image/qpixmapdata.cpp13
-rw-r--r--src/gui/image/qpixmapdata_p.h5
-rw-r--r--src/gui/image/qpixmapfilter.cpp21
-rw-r--r--src/gui/image/qpixmapfilter_p.h7
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h9
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp43
-rw-r--r--src/gui/itemviews/qabstractitemview.h1
-rw-r--r--src/gui/itemviews/qlistview.cpp10
-rw-r--r--src/gui/itemviews/qtreeview.cpp6
-rw-r--r--src/gui/itemviews/qtreeview_p.h2
-rw-r--r--src/gui/kernel/qapplication.cpp58
-rw-r--r--src/gui/kernel/qapplication.h4
-rw-r--r--src/gui/kernel/qapplication_mac.mm26
-rw-r--r--src/gui/kernel/qapplication_p.h5
-rw-r--r--src/gui/kernel/qapplication_s60.cpp41
-rw-r--r--src/gui/kernel/qapplication_win.cpp36
-rw-r--r--src/gui/kernel/qcocoaapplicationdelegate_mac.mm11
-rw-r--r--src/gui/kernel/qcocoaapplicationdelegate_mac_p.h1
-rw-r--r--src/gui/kernel/qcocoawindowdelegate_mac.mm35
-rw-r--r--src/gui/kernel/qcocoawindowdelegate_mac_p.h3
-rw-r--r--src/gui/kernel/qdesktopwidget_mac.mm13
-rw-r--r--src/gui/kernel/qevent.cpp60
-rw-r--r--src/gui/kernel/qevent.h6
-rw-r--r--src/gui/kernel/qevent_p.h13
-rw-r--r--src/gui/kernel/qgesture.cpp175
-rw-r--r--src/gui/kernel/qgesture.h56
-rw-r--r--src/gui/kernel/qgesture_p.h49
-rw-r--r--src/gui/kernel/qgesturemanager.cpp102
-rw-r--r--src/gui/kernel/qgesturemanager_p.h5
-rw-r--r--src/gui/kernel/qgesturerecognizer.cpp86
-rw-r--r--src/gui/kernel/qgesturerecognizer.h25
-rw-r--r--src/gui/kernel/qmacgesturerecognizer_mac.mm59
-rw-r--r--src/gui/kernel/qmacgesturerecognizer_mac_p.h13
-rw-r--r--src/gui/kernel/qsoftkeymanager.cpp8
-rw-r--r--src/gui/kernel/qsound_s60.cpp94
-rw-r--r--src/gui/kernel/qstandardgestures.cpp520
-rw-r--r--src/gui/kernel/qstandardgestures_p.h43
-rw-r--r--src/gui/kernel/qt_s60_p.h23
-rw-r--r--src/gui/kernel/qwidget.cpp35
-rw-r--r--src/gui/kernel/qwidget.h4
-rw-r--r--src/gui/kernel/qwidget_mac.mm25
-rw-r--r--src/gui/kernel/qwidget_p.h8
-rw-r--r--src/gui/kernel/qwidget_s60.cpp4
-rw-r--r--src/gui/kernel/qwidget_win.cpp15
-rw-r--r--src/gui/kernel/qwinnativepangesturerecognizer_win.cpp29
-rw-r--r--src/gui/kernel/qwinnativepangesturerecognizer_win_p.h5
-rw-r--r--src/gui/math3d/qgenericmatrix.cpp106
-rw-r--r--src/gui/math3d/qgenericmatrix.h37
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp237
-rw-r--r--src/gui/math3d/qmatrix4x4.h51
-rw-r--r--src/gui/math3d/qquaternion.cpp4
-rw-r--r--src/gui/math3d/qquaternion.h2
-rw-r--r--src/gui/painting/qbackingstore.cpp8
-rw-r--r--src/gui/painting/qbackingstore_p.h2
-rw-r--r--src/gui/painting/qblendfunctions.cpp40
-rw-r--r--src/gui/painting/qbrush.cpp24
-rw-r--r--src/gui/painting/qdrawhelper.cpp32
-rw-r--r--src/gui/painting/qpaintbuffer.cpp95
-rw-r--r--src/gui/painting/qpaintbuffer_p.h5
-rw-r--r--src/gui/painting/qpaintengineex.cpp4
-rw-r--r--src/gui/painting/qpainter.cpp34
-rw-r--r--src/gui/painting/qpainterpath.cpp20
-rw-r--r--src/gui/painting/qpainterpath_p.h9
-rw-r--r--src/gui/painting/qpen.cpp33
-rw-r--r--src/gui/painting/qstroker.cpp23
-rw-r--r--src/gui/painting/qtransform.cpp9
-rw-r--r--src/gui/painting/qwindowsurface_x11.cpp6
-rw-r--r--src/gui/s60framework/qs60mainappui.cpp2
-rw-r--r--src/gui/s60framework/s60framework.pri11
-rw-r--r--src/gui/s60framework/s60main.rss85
-rw-r--r--src/gui/statemachine/qbasickeyeventtransition.cpp24
-rw-r--r--src/gui/statemachine/qbasickeyeventtransition_p.h6
-rw-r--r--src/gui/statemachine/qbasicmouseeventtransition.cpp24
-rw-r--r--src/gui/statemachine/qbasicmouseeventtransition_p.h8
-rw-r--r--src/gui/statemachine/qguistatemachine.cpp16
-rw-r--r--src/gui/statemachine/qkeyeventtransition.cpp18
-rw-r--r--src/gui/statemachine/qkeyeventtransition.h6
-rw-r--r--src/gui/statemachine/qmouseeventtransition.cpp30
-rw-r--r--src/gui/statemachine/qmouseeventtransition.h10
-rw-r--r--src/gui/styles/qcommonstyle.cpp183
-rw-r--r--src/gui/styles/qs60style.cpp145
-rw-r--r--src/gui/styles/qs60style_p.h1
-rw-r--r--src/gui/styles/qs60style_s60.cpp28
-rw-r--r--src/gui/styles/qs60style_simulated.cpp2
-rw-r--r--src/gui/styles/qstyleoption.cpp5
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp68
-rw-r--r--src/gui/styles/qstylesheetstyle_default.cpp43
-rw-r--r--src/gui/styles/qwindowsstyle.cpp39
-rw-r--r--src/gui/styles/qwindowsstyle_p.h10
-rw-r--r--src/gui/text/qcssparser.cpp7
-rw-r--r--src/gui/text/qfontdatabase.cpp25
-rw-r--r--src/gui/text/qfontdatabase.h1
-rw-r--r--src/gui/text/qfontdatabase_x11.cpp93
-rw-r--r--src/gui/text/qtextcontrol.cpp31
-rw-r--r--src/gui/text/qtextcontrol_p_p.h4
-rw-r--r--src/gui/text/qtextengine_mac.cpp73
-rw-r--r--src/gui/util/qdesktopservices.cpp11
-rw-r--r--src/gui/util/qdesktopservices_mac.cpp9
-rw-r--r--src/gui/widgets/qabstractscrollarea.cpp55
-rw-r--r--src/gui/widgets/qcombobox.cpp37
-rw-r--r--src/gui/widgets/qcombobox.h1
-rw-r--r--src/gui/widgets/qcombobox_p.h2
-rw-r--r--src/gui/widgets/qlinecontrol.cpp26
-rw-r--r--src/gui/widgets/qmenu.cpp43
-rw-r--r--src/gui/widgets/qmenu_mac.mm2
-rw-r--r--src/gui/widgets/qmenu_p.h2
-rw-r--r--src/gui/widgets/qplaintextedit.cpp53
-rw-r--r--src/gui/widgets/qtextedit.cpp6
-rw-r--r--src/gui/widgets/qwidgetanimator.cpp7
-rw-r--r--src/gui/widgets/qwidgetanimator_p.h1
147 files changed, 3889 insertions, 1935 deletions
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h
index 8f6d9d9..c493054 100644
--- a/src/gui/accessible/qaccessible.h
+++ b/src/gui/accessible/qaccessible.h
@@ -311,7 +311,8 @@ namespace QAccessible2
EditableTextInterface,
ValueInterface,
TableInterface,
- ActionInterface
+ ActionInterface,
+ ImageInterface
};
}
@@ -321,6 +322,7 @@ class QAccessibleEditableTextInterface;
class QAccessibleValueInterface;
class QAccessibleTableInterface;
class QAccessibleActionInterface;
+class QAccessibleImageInterface;
class Q_GUI_EXPORT QAccessibleInterface : public QAccessible
{
@@ -381,6 +383,9 @@ public:
inline QAccessibleActionInterface *actionInterface()
{ return reinterpret_cast<QAccessibleActionInterface *>(cast_helper(QAccessible2::ActionInterface)); }
+ inline QAccessibleImageInterface *imageInterface()
+ { return reinterpret_cast<QAccessibleImageInterface *>(cast_helper(QAccessible2::ImageInterface)); }
+
private:
QAccessible2Interface *cast_helper(QAccessible2::InterfaceType);
};
diff --git a/src/gui/accessible/qaccessible2.cpp b/src/gui/accessible/qaccessible2.cpp
index 0867368..b878cf1 100644
--- a/src/gui/accessible/qaccessible2.cpp
+++ b/src/gui/accessible/qaccessible2.cpp
@@ -120,6 +120,18 @@ QT_BEGIN_NAMESPACE
\link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
*/
+/*!
+ \class QAccessibleImageInterface
+ \ingroup accessibility
+ \internal
+ \preliminary
+
+ \brief The QAccessibleImageInterface class implements support for
+ the IAccessibleImage interface.
+
+ \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink
+*/
+
QAccessibleSimpleEditableTextInterface::QAccessibleSimpleEditableTextInterface(
QAccessibleInterface *accessibleInterface)
: iface(accessibleInterface)
diff --git a/src/gui/accessible/qaccessible2.h b/src/gui/accessible/qaccessible2.h
index 435c640..ba12a7c 100644
--- a/src/gui/accessible/qaccessible2.h
+++ b/src/gui/accessible/qaccessible2.h
@@ -82,6 +82,7 @@ inline QAccessible2Interface *qAccessibleTextCastHelper() { return 0; }
inline QAccessible2Interface *qAccessibleEditableTextCastHelper() { return 0; }
inline QAccessible2Interface *qAccessibleTableCastHelper() { return 0; }
inline QAccessible2Interface *qAccessibleActionCastHelper() { return 0; }
+inline QAccessible2Interface *qAccessibleImageCastHelper() { return 0; }
#define Q_ACCESSIBLE_OBJECT \
public: \
@@ -98,6 +99,8 @@ inline QAccessible2Interface *qAccessibleActionCastHelper() { return 0; }
return qAccessibleTableCastHelper(); \
case QAccessible2::ActionInterface: \
return qAccessibleActionCastHelper(); \
+ case QAccessible2::ImageInterface: \
+ return qAccessibleImageCastHelper(); \
} \
return 0; \
} \
@@ -224,6 +227,16 @@ public:
virtual QStringList keyBindings(int actionIndex) = 0;
};
+class Q_GUI_EXPORT QAccessibleImageInterface : public QAccessible2Interface
+{
+public:
+ inline QAccessible2Interface *qAccessibleImageCastHelper() { return this; }
+
+ virtual QString imageDescription() = 0;
+ virtual QSize imageSize() = 0;
+ virtual QRect imagePosition(QAccessible2::CoordinateType coordType) = 0;
+};
+
#endif // QT_NO_ACCESSIBILITY
QT_END_NAMESPACE
diff --git a/src/gui/accessible/qaccessible_mac.mm b/src/gui/accessible/qaccessible_mac.mm
index 9575ad8..030c1a9 100644
--- a/src/gui/accessible/qaccessible_mac.mm
+++ b/src/gui/accessible/qaccessible_mac.mm
@@ -504,11 +504,6 @@ QAElement::QAElement(const QAElement &element)
}
QAElement::QAElement(HIObjectRef object, int child)
- :elementRef(
-#ifndef QT_MAC_USE_COCOA
- AXUIElementCreateWithHIObjectAndIdentifier(object, child)
-#endif
-)
{
#ifndef QT_MAC_USE_COCOA
if (object == 0) {
diff --git a/src/gui/dialogs/qcolordialog_mac.mm b/src/gui/dialogs/qcolordialog_mac.mm
index 9e4fdd1..5f074c0 100644
--- a/src/gui/dialogs/qcolordialog_mac.mm
+++ b/src/gui/dialogs/qcolordialog_mac.mm
@@ -252,15 +252,20 @@ QT_USE_NAMESPACE
delete mQtColor;
mQtColor = new QColor();
NSColor *color = [mColorPanel color];
- NSString *colorSpace = [color colorSpaceName];
- if (colorSpace == NSDeviceCMYKColorSpace) {
- CGFloat cyan, magenta, yellow, black, alpha;
+ NSString *colorSpaceName = [color colorSpaceName];
+ if (colorSpaceName == NSDeviceCMYKColorSpace) {
+ CGFloat cyan = 0, magenta = 0, yellow = 0, black = 0, alpha = 0;
[color getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha];
mQtColor->setCmykF(cyan, magenta, yellow, black, alpha);
- } else if (colorSpace == NSCalibratedRGBColorSpace || colorSpace == NSDeviceRGBColorSpace) {
- CGFloat red, green, blue, alpha;
+ } else if (colorSpaceName == NSCalibratedRGBColorSpace || colorSpaceName == NSDeviceRGBColorSpace) {
+ CGFloat red = 0, green = 0, blue = 0, alpha = 0;
[color getRed:&red green:&green blue:&blue alpha:&alpha];
mQtColor->setRgbF(red, green, blue, alpha);
+ } else if (colorSpaceName == NSNamedColorSpace) {
+ NSColor *tmpColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
+ CGFloat red = 0, green = 0, blue = 0, alpha = 0;
+ [tmpColor getRed:&red green:&green blue:&blue alpha:&alpha];
+ mQtColor->setRgbF(red, green, blue, alpha);
} else {
NSColorSpace *colorSpace = [color colorSpace];
if ([colorSpace colorSpaceModel] == NSCMYKColorSpaceModel && [color numberOfComponents] == 5){
@@ -269,7 +274,7 @@ QT_USE_NAMESPACE
mQtColor->setCmykF(components[0], components[1], components[2], components[3], components[4]);
} else {
NSColor *tmpColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
- CGFloat red, green, blue, alpha;
+ CGFloat red = 0, green = 0, blue = 0, alpha = 0;
[tmpColor getRed:&red green:&green blue:&blue alpha:&alpha];
mQtColor->setRgbF(red, green, blue, alpha);
}
@@ -319,7 +324,18 @@ QT_USE_NAMESPACE
QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
QMacCocoaAutoReleasePool pool;
mDialogIsExecuting = true;
- [NSApp runModalForWindow:mColorPanel];
+ bool modalEnded = false;
+ while (!modalEnded) {
+ @try {
+ [NSApp runModalForWindow:mColorPanel];
+ modalEnded = true;
+ } @catch (NSException *) {
+ // For some reason, NSColorPanel throws an exception when
+ // clicking on 'SelectedMenuItemColor' from the 'Developer'
+ // palette (tab three).
+ }
+ }
+
QAbstractEventDispatcher::instance()->interrupt();
if (mResultCode == NSCancelButton)
mPriv->colorDialog()->reject();
diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp
index c6b4a77..6bc6b76 100644
--- a/src/gui/dialogs/qfiledialog.cpp
+++ b/src/gui/dialogs/qfiledialog.cpp
@@ -3187,7 +3187,17 @@ void QFileDialogTreeView::keyPressEvent(QKeyEvent *e)
if (!d_ptr->itemViewKeyboardEvent(e)) {
QTreeView::keyPressEvent(e);
}
+#ifdef QT_KEYPAD_NAVIGATION
+ else if ((QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
+ || QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional)
+ && !hasEditFocus()) {
+ e->ignore();
+ } else {
+ e->accept();
+ }
+#else
e->accept();
+#endif
}
QSize QFileDialogTreeView::sizeHint() const
diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm
index d9bec27..b0e6575 100644
--- a/src/gui/dialogs/qfiledialog_mac.mm
+++ b/src/gui/dialogs/qfiledialog_mac.mm
@@ -399,9 +399,13 @@ QT_USE_NAMESPACE
- (void)panelSelectionDidChange:(id)sender
{
Q_UNUSED(sender);
- *mCurrentSelection = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString([mSavePanel filename]));
- if (mPriv)
- mPriv->QNSOpenSavePanelDelegate_selectionChanged(*mCurrentSelection);
+ if (mPriv) {
+ QString selection = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString([mSavePanel filename]));
+ if (selection != mCurrentSelection) {
+ *mCurrentSelection = selection;
+ mPriv->QNSOpenSavePanelDelegate_selectionChanged(selection);
+ }
+ }
}
- (void)openPanelDidEnd:(NSOpenPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo
@@ -826,8 +830,8 @@ void QFileDialogPrivate::qt_mac_filedialog_event_proc(const NavEventCallbackMess
|| mode == QFileDialog::ExistingFiles){
// When changing directory, the current selection is cleared if
// we are supposed to be selecting files only:
- fileDialogPrivate->mCurrentSelectionList.clear();
if (!fileDialogPrivate->mCurrentSelection.isEmpty()){
+ fileDialogPrivate->mCurrentSelectionList.clear();
fileDialogPrivate->mCurrentSelection.clear();
emit fileDialogPrivate->q_func()->currentChanged(fileDialogPrivate->mCurrentSelection);
}
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp
index 3815b60..568ff73 100644
--- a/src/gui/effects/qgraphicseffect.cpp
+++ b/src/gui/effects/qgraphicseffect.cpp
@@ -97,6 +97,8 @@
*/
#include "qgraphicseffect_p.h"
+#include "private/qgraphicsitem_p.h"
+
#include <QtGui/qgraphicsitem.h>
#include <QtGui/qimage.h>
@@ -106,6 +108,7 @@
#include <QtCore/qdebug.h>
#include <private/qdrawhelper_p.h>
+#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_NAMESPACE
/*!
@@ -125,6 +128,19 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum QGraphicsEffectSource::PixmapPadMode
+
+ This enum describes how much of the effect will be rendered to a pixmap
+ created using the pixmap() function.
+
+ \value NoExpandPadMode The pixmap is the size of the widget or graphics item.
+ \value ExpandToTransparentBorderPadMode The pixmap is expanded to include
+ the widget or graphics item plus a transparent border.
+ \value ExpandToEffectRectPadMode The pixmap is expanded to include the widget
+ or graphics item and the effect.
+*/
+
+/*!
\internal
*/
QGraphicsEffectSource::QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent)
@@ -210,7 +226,23 @@ const QStyleOption *QGraphicsEffectSource::styleOption() const
*/
void QGraphicsEffectSource::draw(QPainter *painter)
{
- d_func()->draw(painter);
+ Q_D(const QGraphicsEffectSource);
+
+ QPixmap pm;
+ if (QPixmapCache::find(d->m_cacheKey, &pm)) {
+ QTransform restoreTransform;
+ if (d->m_cachedSystem == Qt::DeviceCoordinates) {
+ restoreTransform = painter->worldTransform();
+ painter->setWorldTransform(QTransform());
+ }
+
+ painter->drawPixmap(d->m_cachedOffset, pm);
+
+ if (d->m_cachedSystem == Qt::DeviceCoordinates)
+ painter->setWorldTransform(restoreTransform);
+ } else {
+ d_func()->draw(painter);
+ }
}
/*!
@@ -245,6 +277,9 @@ bool QGraphicsEffectSource::isPixmap() const
The optional \a offset parameter returns the offset where the pixmap should
be painted at using the current painter.
+ The \a mode determines how much of the effect the pixmap will contain.
+ By default, the pixmap will contain the whole effect.
+
The returned pixmap is bound to the current painter's device rectangle when
\a system is Qt::DeviceCoordinates.
@@ -260,6 +295,12 @@ QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offse
return ((QGraphicsPixmapItem *) item)->pixmap();
}
+ if (system == Qt::DeviceCoordinates && item
+ && !static_cast<const QGraphicsItemEffectSourcePrivate *>(d_func())->info) {
+ qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
+ return QPixmap();
+ }
+
QPixmap pm;
if (d->m_cachedSystem == system && d->m_cachedMode == mode)
QPixmapCache::find(d->m_cacheKey, &pm);
@@ -279,6 +320,18 @@ QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offse
return pm;
}
+QGraphicsEffectSourcePrivate::~QGraphicsEffectSourcePrivate()
+{
+ invalidateCache();
+}
+
+void QGraphicsEffectSourcePrivate::invalidateCache(bool effectRectChanged) const
+{
+ if (effectRectChanged && m_cachedMode != QGraphicsEffectSource::ExpandToEffectRectPadMode)
+ return;
+ QPixmapCache::remove(m_cacheKey);
+}
+
/*!
Constructs a new QGraphicsEffect instance having the
specified \a parent.
@@ -418,7 +471,7 @@ void QGraphicsEffect::updateBoundingRect()
Q_D(QGraphicsEffect);
if (d->source) {
d->source->d_func()->effectBoundingRectChanged();
- d->source->d_func()->invalidateCache();
+ d->source->d_func()->invalidateCache(true);
}
}
@@ -606,6 +659,26 @@ void QGraphicsColorizeEffect::draw(QPainter *painter, QGraphicsEffectSource *sou
*/
/*!
+ \enum QGraphicsBlurEffect::BlurHint
+ \since 4.6
+
+ This enum describes the possible hints that can be used to control how
+ blur effects are applied. The hints might not have an effect in all the
+ paint engines.
+
+ \value QualityHint Indicates that rendering quality is the most important factor,
+ at the potential cost of lower performance.
+
+ \value PerformanceHint Indicates that rendering performance is the most important factor,
+ at the potential cost of lower quality.
+
+ \value AnimationHint Indicates that the blur radius is going to be animated, hinting
+ that the implementation can keep a cache of blurred verisons of the source pixmap.
+ Do not use this hint if the source item is going to be dynamically changing.
+*/
+
+
+/*!
Constructs a new QGraphicsBlurEffect instance.
The \a parent parameter is passed to QGraphicsEffect's constructor.
*/
@@ -613,7 +686,7 @@ QGraphicsBlurEffect::QGraphicsBlurEffect(QObject *parent)
: QGraphicsEffect(*new QGraphicsBlurEffectPrivate, parent)
{
Q_D(QGraphicsBlurEffect);
- d->filter->setBlurHint(Qt::PerformanceHint);
+ d->filter->setBlurHint(QGraphicsBlurEffect::PerformanceHint);
}
/*!
@@ -660,20 +733,19 @@ void QGraphicsBlurEffect::setBlurRadius(qreal radius)
\property QGraphicsBlurEffect::blurHint
\brief the blur hint of the effect.
- Use the Qt::PerformanceHint hint to say that you want a faster blur,
- and the Qt::QualityHint hint to say that you prefer a higher quality blur.
-
- When animating the blur radius it's recommended to use Qt::PerformanceHint.
+ Use the PerformanceHint hint to say that you want a faster blur,
+ the QualityHint hint to say that you prefer a higher quality blur,
+ or the AnimationHint when you want to animate the blur radius.
- By default, the blur hint is Qt::PerformanceHint.
+ By default, the blur hint is PerformanceHint.
*/
-Qt::RenderHint QGraphicsBlurEffect::blurHint() const
+QGraphicsBlurEffect::BlurHint QGraphicsBlurEffect::blurHint() const
{
Q_D(const QGraphicsBlurEffect);
return d->filter->blurHint();
}
-void QGraphicsBlurEffect::setBlurHint(Qt::RenderHint hint)
+void QGraphicsBlurEffect::setBlurHint(QGraphicsBlurEffect::BlurHint hint)
{
Q_D(QGraphicsBlurEffect);
if (d->filter->blurHint() == hint)
@@ -684,7 +756,7 @@ void QGraphicsBlurEffect::setBlurHint(Qt::RenderHint hint)
}
/*!
- \fn void QGraphicsBlurEffect::blurHintChanged(Qt::RenderHint hint)
+ \fn void QGraphicsBlurEffect::blurHintChanged(QGraphicsBlurEffect::BlurHint hint)
This signal is emitted whenever the effect's blur hint changes.
The \a hint parameter holds the effect's new blur hint.
@@ -1078,3 +1150,4 @@ void QGraphicsOpacityEffect::draw(QPainter *painter, QGraphicsEffectSource *sour
QT_END_NAMESPACE
+#endif //QT_NO_GRAPHICSEFFECT
diff --git a/src/gui/effects/qgraphicseffect.h b/src/gui/effects/qgraphicseffect.h
index bf18581..5c73f4b 100644
--- a/src/gui/effects/qgraphicseffect.h
+++ b/src/gui/effects/qgraphicseffect.h
@@ -48,6 +48,7 @@
#include <QtGui/qcolor.h>
#include <QtGui/qbrush.h>
+#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -183,22 +184,28 @@ class Q_GUI_EXPORT QGraphicsBlurEffect: public QGraphicsEffect
{
Q_OBJECT
Q_PROPERTY(qreal blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged)
- Q_PROPERTY(Qt::RenderHint blurHint READ blurHint WRITE setBlurHint NOTIFY blurHintChanged)
+ Q_PROPERTY(BlurHint blurHint READ blurHint WRITE setBlurHint NOTIFY blurHintChanged)
public:
+ enum BlurHint {
+ QualityHint,
+ PerformanceHint,
+ AnimationHint
+ };
+
QGraphicsBlurEffect(QObject *parent = 0);
~QGraphicsBlurEffect();
QRectF boundingRectFor(const QRectF &rect) const;
qreal blurRadius() const;
- Qt::RenderHint blurHint() const;
+ BlurHint blurHint() const;
public Q_SLOTS:
void setBlurRadius(qreal blurRadius);
- void setBlurHint(Qt::RenderHint hint);
+ void setBlurHint(BlurHint hint);
Q_SIGNALS:
void blurRadiusChanged(qreal blurRadius);
- void blurHintChanged(Qt::RenderHint hint);
+ void blurHintChanged(BlurHint hint);
protected:
void draw(QPainter *painter, QGraphicsEffectSource *source);
@@ -296,6 +303,7 @@ private:
QT_END_NAMESPACE
QT_END_HEADER
+#endif //QT_NO_GRAPHICSEFFECT
#endif // QGRAPHICSEFFECT_H
diff --git a/src/gui/effects/qgraphicseffect_p.h b/src/gui/effects/qgraphicseffect_p.h
index 1ed7103..d94d08d 100644
--- a/src/gui/effects/qgraphicseffect_p.h
+++ b/src/gui/effects/qgraphicseffect_p.h
@@ -60,6 +60,7 @@
#include <private/qobject_p.h>
#include <private/qpixmapfilter_p.h>
+#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_NAMESPACE
class QGraphicsEffectSourcePrivate : public QObjectPrivate
@@ -72,7 +73,7 @@ public:
, m_cachedMode(QGraphicsEffectSource::ExpandToTransparentBorderPadMode)
{}
- virtual ~QGraphicsEffectSourcePrivate() { invalidateCache(); }
+ virtual ~QGraphicsEffectSourcePrivate();
virtual void detach() = 0;
virtual QRectF boundingRect(Qt::CoordinateSystem system) const = 0;
virtual QRect deviceRect() const = 0;
@@ -85,7 +86,7 @@ public:
virtual QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset = 0,
QGraphicsEffectSource::PixmapPadMode mode = QGraphicsEffectSource::ExpandToTransparentBorderPadMode) const = 0;
virtual void effectBoundingRectChanged() = 0;
- void invalidateCache() const { QPixmapCache::remove(m_cacheKey); }
+ void invalidateCache(bool effectRectChanged = false) const;
friend class QGraphicsScenePrivate;
friend class QGraphicsItem;
@@ -179,5 +180,6 @@ public:
QT_END_NAMESPACE
+#endif //QT_NO_GRAPHICSEFFECT
#endif // QGRAPHICSEFFECT_P_H
diff --git a/src/gui/egl/egl.pri b/src/gui/egl/egl.pri
index 627d511..669d311 100644
--- a/src/gui/egl/egl.pri
+++ b/src/gui/egl/egl.pri
@@ -1,3 +1,5 @@
+CONFIG += egl
+
HEADERS += \
egl/qegl_p.h \
egl/qeglproperties_p.h
@@ -19,11 +21,3 @@ unix {
}
}
}
-
-for(p, QMAKE_LIBDIR_EGL) {
- exists($$p):LIBS_PRIVATE += -L$$p
-}
-
-!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL
-!isEmpty(QMAKE_LIBS_EGL): LIBS_PRIVATE += $$QMAKE_LIBS_EGL
-!isEmpty(QMAKE_LFLAGS_EGL): LIBS += $$QMAKE_LFLAGS_EGL
diff --git a/src/gui/graphicsview/qgraph_p.h b/src/gui/graphicsview/qgraph_p.h
index f1fa185..0a2bf27 100644
--- a/src/gui/graphicsview/qgraph_p.h
+++ b/src/gui/graphicsview/qgraph_p.h
@@ -201,11 +201,6 @@ public:
return l;
}
- void setRootVertex(Vertex *vertex)
- {
- userVertex = vertex;
- }
-
QSet<Vertex*> vertices() const {
QSet<Vertex *> setOfVertices;
for (const_iterator it = constBegin(); it != constEnd(); ++it) {
@@ -241,7 +236,7 @@ public:
EdgeData *data = edgeData(v, v1);
bool forward = data->from == v;
if (forward) {
- edges += QString::fromAscii("%1->%2 [label=\"[%3,%4,%5]\" dir=both color=\"#000000:#a0a0a0\"] \n")
+ edges += QString::fromAscii("\"%1\"->\"%2\" [label=\"[%3,%4,%5]\" dir=both color=\"#000000:#a0a0a0\"] \n")
.arg(v->toString())
.arg(v1->toString())
.arg(data->minSize)
@@ -250,17 +245,12 @@ public:
;
}
}
- strVertices += QString::fromAscii("%1 [label=\"%2\"]\n").arg(v->toString()).arg(v->toString());
+ strVertices += QString::fromAscii("\"%1\" [label=\"%2\"]\n").arg(v->toString()).arg(v->toString());
}
return QString::fromAscii("%1\n%2\n").arg(strVertices).arg(edges);
}
#endif
- Vertex *rootVertex() const
- {
- return userVertex;
- }
-
protected:
void createDirectedEdge(Vertex *from, Vertex *to, EdgeData *data)
{
@@ -286,8 +276,6 @@ protected:
}
private:
- Vertex *userVertex;
-
QHash<Vertex *, QHash<Vertex *, EdgeData *> *> m_graph;
};
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
index 56d70e1..872ec3c 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
@@ -83,10 +83,8 @@
\clearfloat
\section1 Size Hints and Size Policies in an Anchor Layout
- QGraphicsAnchorLayout respects each item's size hints and size policies. However it does
- not currently respect their stretch factors. This might change in the future, so avoid
- using stretch factors in anchor layouts if you want to avoid any future regressions in
- behavior.
+ QGraphicsAnchorLayout respects each item's size hints and size policies.
+ Note that there are some properties of QSizePolicy that are \l{Known issues}{not respected}.
\section1 Spacing within an Anchor Layout
@@ -101,6 +99,21 @@
If the spacing is negative, the items will overlap to some extent.
+
+ \section1 Known issues
+ There are some features that QGraphicsAnchorLayout currently does not support.
+ This might change in the future, so avoid using these features if you want to
+ avoid any future regressions in behaviour:
+ \list
+
+ \o Stretch factors are not respected.
+
+ \o QSizePolicy::ExpandFlag is not respected.
+
+ \o Height for width is not respected.
+
+ \endlist
+
\sa QGraphicsLinearLayout, QGraphicsGridLayout, QGraphicsLayout
*/
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
index 41aa8aa..182594e 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
@@ -61,6 +61,8 @@ QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(int version)
QGraphicsAnchorPrivate::~QGraphicsAnchorPrivate()
{
+ // ###
+ layoutPrivate->restoreSimplifiedGraph(QGraphicsAnchorLayoutPrivate::Orientation(data->orientation));
layoutPrivate->removeAnchor(data->from, data->to);
}
@@ -105,7 +107,7 @@ qreal QGraphicsAnchorPrivate::spacing() const
static void internalSizeHints(QSizePolicy::Policy policy,
qreal minSizeHint, qreal prefSizeHint, qreal maxSizeHint,
qreal *minSize, qreal *prefSize,
- qreal *expSize, qreal *maxSize)
+ qreal *maxSize)
{
// minSize, prefSize and maxSize are initialized
// with item's preferred Size: this is QSizePolicy::Fixed.
@@ -135,11 +137,6 @@ static void internalSizeHints(QSizePolicy::Policy policy,
*prefSize = *minSize;
else
*prefSize = prefSizeHint;
-
- if (policy & QSizePolicy::ExpandFlag)
- *expSize = *maxSize;
- else
- *expSize = *prefSize;
}
bool AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
@@ -154,7 +151,6 @@ bool AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
if (isLayoutAnchor) {
minSize = 0;
prefSize = 0;
- expSize = 0;
maxSize = QWIDGETSIZE_MAX;
if (isCenterAnchor)
maxSize /= 2;
@@ -205,8 +201,8 @@ bool AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
}
maxSizeHint = QWIDGETSIZE_MAX;
}
- internalSizeHints(policy, minSizeHint, prefSizeHint, maxSizeHint,
- &minSize, &prefSize, &expSize, &maxSize);
+ internalSizeHints(policy, minSizeHint, prefSizeHint, maxSizeHint,
+ &minSize, &prefSize, &maxSize);
// Set the anchor effective sizes to preferred.
//
@@ -217,7 +213,6 @@ bool AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
// recalculate and override the values we set here.
sizeAtMinimum = prefSize;
sizeAtPreferred = prefSize;
- sizeAtExpanding = prefSize;
sizeAtMaximum = prefSize;
return true;
@@ -225,10 +220,20 @@ bool AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
void ParallelAnchorData::updateChildrenSizes()
{
- firstEdge->sizeAtMinimum = secondEdge->sizeAtMinimum = sizeAtMinimum;
- firstEdge->sizeAtPreferred = secondEdge->sizeAtPreferred = sizeAtPreferred;
- firstEdge->sizeAtExpanding = secondEdge->sizeAtExpanding = sizeAtExpanding;
- firstEdge->sizeAtMaximum = secondEdge->sizeAtMaximum = sizeAtMaximum;
+ firstEdge->sizeAtMinimum = sizeAtMinimum;
+ firstEdge->sizeAtPreferred = sizeAtPreferred;
+ firstEdge->sizeAtMaximum = sizeAtMaximum;
+
+ const bool secondFwd = (secondEdge->from == from);
+ if (secondFwd) {
+ secondEdge->sizeAtMinimum = sizeAtMinimum;
+ secondEdge->sizeAtPreferred = sizeAtPreferred;
+ secondEdge->sizeAtMaximum = sizeAtMaximum;
+ } else {
+ secondEdge->sizeAtMinimum = -sizeAtMinimum;
+ secondEdge->sizeAtPreferred = -sizeAtPreferred;
+ secondEdge->sizeAtMaximum = -sizeAtMaximum;
+ }
firstEdge->updateChildrenSizes();
secondEdge->updateChildrenSizes();
@@ -247,8 +252,16 @@ bool ParallelAnchorData::refreshSizeHints_helper(const QLayoutStyleInfo *styleIn
return false;
}
- minSize = qMax(firstEdge->minSize, secondEdge->minSize);
- maxSize = qMin(firstEdge->maxSize, secondEdge->maxSize);
+ // Account for parallel anchors where the second edge is backwards.
+ // We rely on the fact that a forward anchor of sizes min, pref, max is equivalent
+ // to a backwards anchor of size (-max, -pref, -min)
+ const bool secondFwd = (secondEdge->from == from);
+ const qreal secondMin = secondFwd ? secondEdge->minSize : -secondEdge->maxSize;
+ const qreal secondPref = secondFwd ? secondEdge->prefSize : -secondEdge->prefSize;
+ const qreal secondMax = secondFwd ? secondEdge->maxSize : -secondEdge->minSize;
+
+ minSize = qMax(firstEdge->minSize, secondMin);
+ maxSize = qMin(firstEdge->maxSize, secondMax);
// This condition means that the maximum size of one anchor being simplified is smaller than
// the minimum size of the other anchor. The consequence is that there won't be a valid size
@@ -257,16 +270,27 @@ bool ParallelAnchorData::refreshSizeHints_helper(const QLayoutStyleInfo *styleIn
return false;
}
- expSize = qMax(firstEdge->expSize, secondEdge->expSize);
- expSize = qMin(expSize, maxSize);
+ // The equivalent preferred Size of a parallel anchor is calculated as to
+ // reduce the deviation from the original preferred sizes _and_ to avoid shrinking
+ // items below their preferred sizes, unless strictly needed.
- prefSize = qMax(firstEdge->prefSize, secondEdge->prefSize);
- prefSize = qMin(prefSize, expSize);
+ // ### This logic only holds if all anchors in the layout are "well-behaved" in the
+ // following terms:
+ //
+ // - There are no negative-sized anchors
+ // - All sequential anchors are composed of children in the same direction as the
+ // sequential anchor itself
+ //
+ // With these assumptions we can grow a child knowing that no hidden items will
+ // have to shrink as the result of that.
+ // If any of these does not hold, we have a situation where the ParallelAnchor
+ // does not have enough information to calculate its equivalent prefSize.
+ prefSize = qMax(firstEdge->prefSize, secondPref);
+ prefSize = qMin(prefSize, maxSize);
// See comment in AnchorData::refreshSizeHints() about sizeAt* values
sizeAtMinimum = prefSize;
sizeAtPreferred = prefSize;
- sizeAtExpanding = prefSize;
sizeAtMaximum = prefSize;
return true;
@@ -280,8 +304,7 @@ bool ParallelAnchorData::refreshSizeHints_helper(const QLayoutStyleInfo *styleIn
1 is at Maximum
*/
static QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> getFactor(qreal value, qreal min,
- qreal pref, qreal exp,
- qreal max)
+ qreal pref, qreal max)
{
QGraphicsAnchorLayoutPrivate::Interval interval;
qreal lower;
@@ -291,13 +314,9 @@ static QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> getFactor(qreal valu
interval = QGraphicsAnchorLayoutPrivate::MinToPreferred;
lower = min;
upper = pref;
- } else if (value < exp) {
- interval = QGraphicsAnchorLayoutPrivate::PreferredToExpanding;
- lower = pref;
- upper = exp;
} else {
- interval = QGraphicsAnchorLayoutPrivate::ExpandingToMax;
- lower = exp;
+ interval = QGraphicsAnchorLayoutPrivate::PreferredToMax;
+ lower = pref;
upper = max;
}
@@ -313,7 +332,7 @@ static QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> getFactor(qreal valu
static qreal interpolate(const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> &factor,
qreal min, qreal pref,
- qreal exp, qreal max)
+ qreal max)
{
qreal lower;
qreal upper;
@@ -323,12 +342,8 @@ static qreal interpolate(const QPair<QGraphicsAnchorLayoutPrivate::Interval, qre
lower = min;
upper = pref;
break;
- case QGraphicsAnchorLayoutPrivate::PreferredToExpanding:
+ case QGraphicsAnchorLayoutPrivate::PreferredToMax:
lower = pref;
- upper = exp;
- break;
- case QGraphicsAnchorLayoutPrivate::ExpandingToMax:
- lower = exp;
upper = max;
break;
}
@@ -341,34 +356,31 @@ void SequentialAnchorData::updateChildrenSizes()
// ### REMOVE ME
// ### check whether we are guarantee to get those or we need to warn stuff at this
// point.
- Q_ASSERT(sizeAtMinimum > minSize || qFuzzyCompare(sizeAtMinimum, minSize));
- Q_ASSERT(sizeAtMinimum < maxSize || qFuzzyCompare(sizeAtMinimum, maxSize));
- Q_ASSERT(sizeAtPreferred > minSize || qFuzzyCompare(sizeAtPreferred, minSize));
- Q_ASSERT(sizeAtPreferred < maxSize || qFuzzyCompare(sizeAtPreferred, maxSize));
- Q_ASSERT(sizeAtExpanding > minSize || qFuzzyCompare(sizeAtExpanding, minSize));
- Q_ASSERT(sizeAtExpanding < maxSize || qFuzzyCompare(sizeAtExpanding, maxSize));
- Q_ASSERT(sizeAtMaximum > minSize || qFuzzyCompare(sizeAtMaximum, minSize));
- Q_ASSERT(sizeAtMaximum < maxSize || qFuzzyCompare(sizeAtMaximum, maxSize));
+ Q_ASSERT(sizeAtMinimum > minSize || qAbs(sizeAtMinimum - minSize) < 0.00000001);
+ Q_ASSERT(sizeAtPreferred > minSize || qAbs(sizeAtPreferred - minSize) < 0.00000001);
+ Q_ASSERT(sizeAtMaximum > minSize || qAbs(sizeAtMaximum - minSize) < 0.00000001);
+
+ // These may be false if this anchor was in parallel with the layout stucture
+ // Q_ASSERT(sizeAtMinimum < maxSize || qAbs(sizeAtMinimum - maxSize) < 0.00000001);
+ // Q_ASSERT(sizeAtPreferred < maxSize || qAbs(sizeAtPreferred - maxSize) < 0.00000001);
+ // Q_ASSERT(sizeAtMaximum < maxSize || qAbs(sizeAtMaximum - maxSize) < 0.00000001);
// Band here refers if the value is in the Minimum To Preferred
// band (the lower band) or the Preferred To Maximum (the upper band).
const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> minFactor =
- getFactor(sizeAtMinimum, minSize, prefSize, expSize, maxSize);
+ getFactor(sizeAtMinimum, minSize, prefSize, maxSize);
const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> prefFactor =
- getFactor(sizeAtPreferred, minSize, prefSize, expSize, maxSize);
- const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> expFactor =
- getFactor(sizeAtExpanding, minSize, prefSize, expSize, maxSize);
+ getFactor(sizeAtPreferred, minSize, prefSize, maxSize);
const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> maxFactor =
- getFactor(sizeAtMaximum, minSize, prefSize, expSize, maxSize);
+ getFactor(sizeAtMaximum, minSize, prefSize, maxSize);
for (int i = 0; i < m_edges.count(); ++i) {
AnchorData *e = m_edges.at(i);
- e->sizeAtMinimum = interpolate(minFactor, e->minSize, e->prefSize, e->expSize, e->maxSize);
- e->sizeAtPreferred = interpolate(prefFactor, e->minSize, e->prefSize, e->expSize, e->maxSize);
- e->sizeAtExpanding = interpolate(expFactor, e->minSize, e->prefSize, e->expSize, e->maxSize);
- e->sizeAtMaximum = interpolate(maxFactor, e->minSize, e->prefSize, e->expSize, e->maxSize);
+ e->sizeAtMinimum = interpolate(minFactor, e->minSize, e->prefSize, e->maxSize);
+ e->sizeAtPreferred = interpolate(prefFactor, e->minSize, e->prefSize, e->maxSize);
+ e->sizeAtMaximum = interpolate(maxFactor, e->minSize, e->prefSize, e->maxSize);
e->updateChildrenSizes();
}
@@ -384,7 +396,6 @@ bool SequentialAnchorData::refreshSizeHints_helper(const QLayoutStyleInfo *style
{
minSize = 0;
prefSize = 0;
- expSize = 0;
maxSize = 0;
for (int i = 0; i < m_edges.count(); ++i) {
@@ -396,14 +407,12 @@ bool SequentialAnchorData::refreshSizeHints_helper(const QLayoutStyleInfo *style
minSize += edge->minSize;
prefSize += edge->prefSize;
- expSize += edge->expSize;
maxSize += edge->maxSize;
}
// See comment in AnchorData::refreshSizeHints() about sizeAt* values
sizeAtMinimum = prefSize;
sizeAtPreferred = prefSize;
- sizeAtExpanding = prefSize;
sizeAtMaximum = prefSize;
return true;
@@ -478,12 +487,15 @@ QGraphicsAnchorLayoutPrivate::QGraphicsAnchorLayoutPrivate()
for (int j = 0; j < 3; ++j) {
sizeHints[i][j] = -1;
}
- sizeAtExpanding[i] = -1;
interpolationProgress[i] = -1;
spacings[i] = -1;
graphSimplified[i] = false;
graphHasConflicts[i] = false;
+
+ layoutFirstVertex[i] = 0;
+ layoutCentralVertex[i] = 0;
+ layoutLastVertex[i] = 0;
}
}
@@ -526,33 +538,67 @@ inline static qreal checkAdd(qreal a, qreal b)
/*!
\internal
- Adds \a newAnchor to the graph \a g.
+ Adds \a newAnchor to the graph.
Returns the newAnchor itself if it could be added without further changes to the graph. If a
- new parallel anchor had to be created, then returns the new parallel anchor. In case the
- addition is unfeasible -- because a parallel setup is not possible, returns 0.
+ new parallel anchor had to be created, then returns the new parallel anchor. If a parallel anchor
+ had to be created and it results in an unfeasible setup, \a feasible is set to false, otherwise
+ true.
+
+ Note that in the case a new parallel anchor is created, it might also take over some constraints
+ from its children anchors.
*/
-static AnchorData *addAnchorMaybeParallel(Graph<AnchorVertex, AnchorData> *g,
- AnchorData *newAnchor)
+AnchorData *QGraphicsAnchorLayoutPrivate::addAnchorMaybeParallel(AnchorData *newAnchor, bool *feasible)
{
- bool feasible = true;
+ Orientation orientation = Orientation(newAnchor->orientation);
+ Graph<AnchorVertex, AnchorData> &g = graph[orientation];
+ *feasible = true;
// If already exists one anchor where newAnchor is supposed to be, we create a parallel
// anchor.
- if (AnchorData *oldAnchor = g->takeEdge(newAnchor->from, newAnchor->to)) {
+ if (AnchorData *oldAnchor = g.takeEdge(newAnchor->from, newAnchor->to)) {
ParallelAnchorData *parallel = new ParallelAnchorData(oldAnchor, newAnchor);
+ // The parallel anchor will "replace" its children anchors in
+ // every center constraint that they appear.
+
+ // ### If the dependent (center) anchors had reference(s) to their constraints, we
+ // could avoid traversing all the itemCenterConstraints.
+ QList<QSimplexConstraint *> &constraints = itemCenterConstraints[orientation];
+
+ AnchorData *children[2] = { oldAnchor, newAnchor };
+ QList<QSimplexConstraint *> *childrenConstraints[2] = { &parallel->m_firstConstraints,
+ &parallel->m_secondConstraints };
+
+ for (int i = 0; i < 2; ++i) {
+ AnchorData *child = children[i];
+ QList<QSimplexConstraint *> *childConstraints = childrenConstraints[i];
+
+ if (!child->isCenterAnchor)
+ continue;
+
+ parallel->isCenterAnchor = true;
+
+ for (int i = 0; i < constraints.count(); ++i) {
+ QSimplexConstraint *c = constraints[i];
+ if (c->variables.contains(child)) {
+ childConstraints->append(c);
+ qreal v = c->variables.take(child);
+ c->variables.insert(parallel, v);
+ }
+ }
+ }
+
// At this point we can identify that the parallel anchor is not feasible, e.g. one
// anchor minimum size is bigger than the other anchor maximum size.
- feasible = parallel->refreshSizeHints_helper(0, false);
+ *feasible = parallel->refreshSizeHints_helper(0, false);
newAnchor = parallel;
}
- g->createEdge(newAnchor->from, newAnchor->to, newAnchor);
- return feasible ? newAnchor : 0;
+ g.createEdge(newAnchor->from, newAnchor->to, newAnchor);
+ return newAnchor;
}
-
/*!
\internal
@@ -656,30 +702,185 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation)
if (graphSimplified[orientation])
return true;
- graphSimplified[orientation] = true;
#if 0
qDebug("Simplifying Graph for %s",
orientation == Horizontal ? "Horizontal" : "Vertical");
#endif
- if (!graph[orientation].rootVertex())
- return true;
+ // Vertex simplification
+ if (!simplifyVertices(orientation)) {
+ restoreVertices(orientation);
+ return false;
+ }
+ // Anchor simplification
bool dirty;
bool feasible = true;
do {
dirty = simplifyGraphIteration(orientation, &feasible);
} while (dirty && feasible);
- if (!feasible)
- graphSimplified[orientation] = false;
+ // Note that if we are not feasible, we fallback and make sure that the graph is fully restored
+ if (!feasible) {
+ graphSimplified[orientation] = true;
+ restoreSimplifiedGraph(orientation);
+ restoreVertices(orientation);
+ return false;
+ }
+
+ graphSimplified[orientation] = true;
+ return true;
+}
+
+static AnchorVertex *replaceVertex_helper(AnchorData *data, AnchorVertex *oldV, AnchorVertex *newV)
+{
+ AnchorVertex *other;
+ if (data->from == oldV) {
+ data->from = newV;
+ other = data->to;
+ } else {
+ data->to = newV;
+ other = data->from;
+ }
+ return other;
+}
+
+bool QGraphicsAnchorLayoutPrivate::replaceVertex(Orientation orientation, AnchorVertex *oldV,
+ AnchorVertex *newV, const QList<AnchorData *> &edges)
+{
+ Graph<AnchorVertex, AnchorData> &g = graph[orientation];
+ bool feasible = true;
+
+ for (int i = 0; i < edges.count(); ++i) {
+ AnchorData *ad = edges[i];
+ AnchorVertex *otherV = replaceVertex_helper(ad, oldV, newV);
+
+#if defined(QT_DEBUG)
+ ad->name = QString::fromAscii("%1 --to--> %2").arg(ad->from->toString()).arg(ad->to->toString());
+#endif
+
+ bool newFeasible;
+ AnchorData *newAnchor = addAnchorMaybeParallel(ad, &newFeasible);
+ feasible &= newFeasible;
+
+ if (newAnchor != ad) {
+ // A parallel was created, we mark that in the list of anchors created by vertex
+ // simplification. This is needed because we want to restore them in a separate step
+ // from the restoration of anchor simplification.
+ anchorsFromSimplifiedVertices[orientation].append(newAnchor);
+ }
+
+ g.takeEdge(oldV, otherV);
+ }
return feasible;
}
/*!
\internal
+*/
+bool QGraphicsAnchorLayoutPrivate::simplifyVertices(Orientation orientation)
+{
+ Q_Q(QGraphicsAnchorLayout);
+ Graph<AnchorVertex, AnchorData> &g = graph[orientation];
+
+ // We'll walk through vertices
+ QStack<AnchorVertex *> stack;
+ stack.push(layoutFirstVertex[orientation]);
+ QSet<AnchorVertex *> visited;
+
+ while (!stack.isEmpty()) {
+ AnchorVertex *v = stack.pop();
+ visited.insert(v);
+
+ // Each adjacent of 'v' is a possible vertex to be merged. So we traverse all of
+ // them. Since once a merge is made, we might add new adjacents, and we don't want to
+ // pass two times through one adjacent. The 'index' is used to track our position.
+ QList<AnchorVertex *> adjacents = g.adjacentVertices(v);
+ int index = 0;
+
+ while (index < adjacents.count()) {
+ AnchorVertex *next = adjacents.at(index);
+ index++;
+
+ AnchorData *data = g.edgeData(v, next);
+ const bool bothLayoutVertices = v->m_item == q && next->m_item == q;
+ const bool zeroSized = !data->minSize && !data->maxSize;
+
+ if (!bothLayoutVertices && zeroSized) {
+
+ // Create a new vertex pair, note that we keep a list of those vertices so we can
+ // easily process them when restoring the graph.
+ AnchorVertexPair *newV = new AnchorVertexPair(v, next, data);
+ simplifiedVertices[orientation].append(newV);
+
+ // Collect the anchors of both vertices, the new vertex pair will take their place
+ // in those anchors
+ const QList<AnchorVertex *> &vAdjacents = g.adjacentVertices(v);
+ const QList<AnchorVertex *> &nextAdjacents = g.adjacentVertices(next);
+
+ for (int i = 0; i < vAdjacents.count(); ++i) {
+ AnchorVertex *adjacent = vAdjacents.at(i);
+ if (adjacent != next) {
+ AnchorData *ad = g.edgeData(v, adjacent);
+ newV->m_firstAnchors.append(ad);
+ }
+ }
+
+ for (int i = 0; i < nextAdjacents.count(); ++i) {
+ AnchorVertex *adjacent = nextAdjacents.at(i);
+ if (adjacent != v) {
+ AnchorData *ad = g.edgeData(next, adjacent);
+ newV->m_secondAnchors.append(ad);
+
+ // We'll also add new vertices to the adjacent list of the new 'v', to be
+ // created as a vertex pair and replace the current one.
+ if (!adjacents.contains(adjacent))
+ adjacents.append(adjacent);
+ }
+ }
+
+ // ### merge this loop into the ones that calculated m_firstAnchors/m_secondAnchors?
+ // Make newV take the place of v and next
+ bool feasible = replaceVertex(orientation, v, newV, newV->m_firstAnchors);
+ feasible &= replaceVertex(orientation, next, newV, newV->m_secondAnchors);
+
+ // Update the layout vertex information if one of the vertices is a layout vertex.
+ AnchorVertex *layoutVertex = 0;
+ if (v->m_item == q)
+ layoutVertex = v;
+ else if (next->m_item == q)
+ layoutVertex = next;
+
+ if (layoutVertex) {
+ // Layout vertices always have m_item == q...
+ newV->m_item = q;
+ changeLayoutVertex(orientation, layoutVertex, newV);
+ }
+
+ g.takeEdge(v, next);
+
+ // If a non-feasibility is found, we leave early and cancel the simplification
+ if (!feasible)
+ return false;
+
+ v = newV;
+ visited.insert(newV);
+
+ } else if (!visited.contains(next) && !stack.contains(next)) {
+ // If the adjacent is not fit for merge and it wasn't visited by the outermost
+ // loop, we add it to the stack.
+ stack.push(next);
+ }
+ }
+ }
+
+ return true;
+}
+
+/*!
+ \internal
One iteration of the simplification algorithm. Returns true if another iteration is needed.
@@ -700,7 +901,7 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP
QSet<AnchorVertex *> visited;
QStack<QPair<AnchorVertex *, AnchorVertex *> > stack;
- stack.push(qMakePair(static_cast<AnchorVertex *>(0), g.rootVertex()));
+ stack.push(qMakePair(static_cast<AnchorVertex *>(0), layoutFirstVertex[orientation]));
QVector<AnchorVertex*> candidates;
bool candidatesForward;
@@ -719,7 +920,8 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP
// (a) it is a layout vertex, we don't simplify away the layout vertices;
// (b) it does not have exactly 2 adjacents;
// (c) it will change the direction of the sequence;
- // (d) its next adjacent is already visited (a cycle in the graph).
+ // (d) its next adjacent is already visited (a cycle in the graph);
+ // (e) the next anchor is a center anchor.
const QList<AnchorVertex *> &adjacents = g.adjacentVertices(v);
const bool isLayoutVertex = v->m_item == q;
@@ -742,13 +944,14 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP
candidatesForward = (beforeSequence == data->from);
}
- // This is a tricky part. We peek at the next vertex to find out
+ // This is a tricky part. We peek at the next vertex to find out whether
//
- // - whether the edge from this vertex to the next vertex has the same direction;
- // - whether we already visited the next vertex.
+ // - the edge from this vertex to the next vertex has the same direction;
+ // - we already visited the next vertex;
+ // - the next anchor is a center.
//
- // Those are needed to identify (c) and (d). Note that unlike (a) and (b), we preempt
- // the end of sequence by looking into the next vertex.
+ // Those are needed to identify the remaining end of sequence cases. Note that unlike
+ // (a) and (b), we preempt the end of sequence by looking into the next vertex.
// Peek at the next vertex
AnchorVertex *after;
@@ -766,8 +969,8 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP
const bool willChangeDirection = (candidatesForward != (v == data->from));
const bool cycleFound = visited.contains(after);
- // Now cases (c) and (d)...
- endOfSequence = willChangeDirection || cycleFound;
+ // Now cases (c), (d) and (e)...
+ endOfSequence = willChangeDirection || cycleFound || data->isCenterAnchor;
if (endOfSequence) {
if (!willChangeDirection) {
@@ -839,9 +1042,10 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP
// If 'beforeSequence' and 'afterSequence' already had an anchor between them, we'll
// create a parallel anchor between the new sequence and the old anchor.
- AnchorData *newAnchor = addAnchorMaybeParallel(&g, sequence);
+ bool newFeasible;
+ AnchorData *newAnchor = addAnchorMaybeParallel(sequence, &newFeasible);
- if (!newAnchor) {
+ if (!newFeasible) {
*feasible = false;
return false;
}
@@ -861,48 +1065,70 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP
return false;
}
-static void restoreSimplifiedAnchor(Graph<AnchorVertex, AnchorData> &g,
- AnchorData *edge,
- AnchorVertex *before,
- AnchorVertex *after)
+void QGraphicsAnchorLayoutPrivate::restoreSimplifiedAnchor(AnchorData *edge)
{
- Q_ASSERT(edge->type != AnchorData::Normal);
#if 0
static const char *anchortypes[] = {"Normal",
"Sequential",
"Parallel"};
qDebug("Restoring %s edge.", anchortypes[int(edge->type)]);
#endif
- if (edge->type == AnchorData::Sequential) {
- SequentialAnchorData* seqEdge = static_cast<SequentialAnchorData*>(edge);
- // restore the sequential anchor
- AnchorVertex *prev = before;
- AnchorVertex *last = after;
- if (edge->from != prev)
- qSwap(last, prev);
-
- for (int i = 0; i < seqEdge->m_edges.count(); ++i) {
- AnchorVertex *v1 = (i < seqEdge->m_children.count()) ? seqEdge->m_children.at(i) : last;
- AnchorData *data = seqEdge->m_edges.at(i);
- if (data->type != AnchorData::Normal) {
- restoreSimplifiedAnchor(g, data, prev, v1);
- } else {
- g.createEdge(prev, v1, data);
- }
- prev = v1;
+
+ Graph<AnchorVertex, AnchorData> &g = graph[edge->orientation];
+
+ if (edge->type == AnchorData::Normal) {
+ g.createEdge(edge->from, edge->to, edge);
+
+ } else if (edge->type == AnchorData::Sequential) {
+ SequentialAnchorData *sequence = static_cast<SequentialAnchorData *>(edge);
+
+ for (int i = 0; i < sequence->m_edges.count(); ++i) {
+ AnchorData *data = sequence->m_edges.at(i);
+ restoreSimplifiedAnchor(data);
}
+
+ delete sequence;
+
} else if (edge->type == AnchorData::Parallel) {
- ParallelAnchorData* parallelEdge = static_cast<ParallelAnchorData*>(edge);
- AnchorData *parallelEdges[2] = {parallelEdge->firstEdge,
- parallelEdge->secondEdge};
- for (int i = 0; i < 2; ++i) {
- AnchorData *data = parallelEdges[i];
- if (data->type == AnchorData::Normal) {
- g.createEdge(before, after, data);
- } else {
- restoreSimplifiedAnchor(g, data, before, after);
- }
- }
+
+ // Skip parallel anchors that were created by vertex simplification, they will be processed
+ // later, when restoring vertex simplification.
+ // ### we could improve this check bit having a bit inside 'edge'
+ if (anchorsFromSimplifiedVertices[edge->orientation].contains(edge))
+ return;
+
+ ParallelAnchorData* parallel = static_cast<ParallelAnchorData*>(edge);
+ restoreSimplifiedConstraints(parallel);
+
+ // ### Because of the way parallel anchors are created in the anchor simplification
+ // algorithm, we know that one of these will be a sequence, so it'll be safe if the other
+ // anchor create an edge between the same vertices as the parallel.
+ Q_ASSERT(parallel->firstEdge->type == AnchorData::Sequential
+ || parallel->secondEdge->type == AnchorData::Sequential);
+ restoreSimplifiedAnchor(parallel->firstEdge);
+ restoreSimplifiedAnchor(parallel->secondEdge);
+
+ delete parallel;
+ }
+}
+
+void QGraphicsAnchorLayoutPrivate::restoreSimplifiedConstraints(ParallelAnchorData *parallel)
+{
+ if (!parallel->isCenterAnchor)
+ return;
+
+ for (int i = 0; i < parallel->m_firstConstraints.count(); ++i) {
+ QSimplexConstraint *c = parallel->m_firstConstraints.at(i);
+ qreal v = c->variables[parallel];
+ c->variables.remove(parallel);
+ c->variables.insert(parallel->firstEdge, v);
+ }
+
+ for (int i = 0; i < parallel->m_secondConstraints.count(); ++i) {
+ QSimplexConstraint *c = parallel->m_secondConstraints.at(i);
+ qreal v = c->variables[parallel];
+ c->variables.remove(parallel);
+ c->variables.insert(parallel->secondEdge, v);
}
}
@@ -917,19 +1143,93 @@ void QGraphicsAnchorLayoutPrivate::restoreSimplifiedGraph(Orientation orientatio
orientation == Horizontal ? "Horizontal" : "Vertical");
#endif
+ // Restore anchor simplification
Graph<AnchorVertex, AnchorData> &g = graph[orientation];
-
QList<QPair<AnchorVertex*, AnchorVertex*> > connections = g.connections();
for (int i = 0; i < connections.count(); ++i) {
AnchorVertex *v1 = connections.at(i).first;
AnchorVertex *v2 = connections.at(i).second;
AnchorData *edge = g.edgeData(v1, v2);
- if (edge->type != AnchorData::Normal) {
- AnchorData *oldEdge = g.takeEdge(v1, v2);
- restoreSimplifiedAnchor(g, edge, v1, v2);
- delete oldEdge;
+
+ // We restore only sequential anchors and parallels that were not created by
+ // vertex simplification.
+ if (edge->type == AnchorData::Sequential
+ || (edge->type == AnchorData::Parallel &&
+ !anchorsFromSimplifiedVertices[orientation].contains(edge))) {
+
+ g.takeEdge(v1, v2);
+ restoreSimplifiedAnchor(edge);
}
}
+
+ restoreVertices(orientation);
+}
+
+void QGraphicsAnchorLayoutPrivate::restoreVertices(Orientation orientation)
+{
+ Q_Q(QGraphicsAnchorLayout);
+
+ Graph<AnchorVertex, AnchorData> &g = graph[orientation];
+ QList<AnchorVertexPair *> &toRestore = simplifiedVertices[orientation];
+
+ // We will restore the vertices in the inverse order of creation, this way we ensure that
+ // the vertex being restored was not wrapped by another simplification.
+ for (int i = toRestore.count() - 1; i >= 0; --i) {
+ AnchorVertexPair *pair = toRestore.at(i);
+ QList<AnchorVertex *> adjacents = g.adjacentVertices(pair);
+
+ // Restore the removed edge, this will also restore both vertices 'first' and 'second' to
+ // the graph structure.
+ AnchorVertex *first = pair->m_first;
+ AnchorVertex *second = pair->m_second;
+ g.createEdge(first, second, pair->m_removedAnchor);
+
+ // Restore the anchors for the first child vertex
+ for (int j = 0; j < pair->m_firstAnchors.count(); ++j) {
+ AnchorData *ad = pair->m_firstAnchors.at(j);
+ Q_ASSERT(ad->from == pair || ad->to == pair);
+
+ replaceVertex_helper(ad, pair, first);
+ g.createEdge(ad->from, ad->to, ad);
+ }
+
+ // Restore the anchors for the second child vertex
+ for (int j = 0; j < pair->m_secondAnchors.count(); ++j) {
+ AnchorData *ad = pair->m_secondAnchors.at(j);
+ Q_ASSERT(ad->from == pair || ad->to == pair);
+
+ replaceVertex_helper(ad, pair, second);
+ g.createEdge(ad->from, ad->to, ad);
+ }
+
+ for (int j = 0; j < adjacents.count(); ++j) {
+ g.takeEdge(pair, adjacents.at(j));
+ }
+
+ // The pair simplified a layout vertex, so place back the correct vertex in the variable
+ // that track layout vertices
+ if (pair->m_item == q) {
+ AnchorVertex *layoutVertex = first->m_item == q ? first : second;
+ Q_ASSERT(layoutVertex->m_item == q);
+ changeLayoutVertex(orientation, pair, layoutVertex);
+ }
+
+ delete pair;
+ }
+ toRestore.clear();
+
+ // The restoration process for vertex simplification also restored the effect of the
+ // parallel anchors created during vertex simplification, so we just need to restore
+ // the constraints in case of parallels that contain center anchors. For the same
+ // reason as above, order matters here.
+ QList<AnchorData *> &parallelAnchors = anchorsFromSimplifiedVertices[orientation];
+
+ for (int i = parallelAnchors.count() - 1; i >= 0; --i) {
+ ParallelAnchorData *parallel = static_cast<ParallelAnchorData *>(parallelAnchors.at(i));
+ restoreSimplifiedConstraints(parallel);
+ delete parallel;
+ }
+ parallelAnchors.clear();
}
QGraphicsAnchorLayoutPrivate::Orientation
@@ -959,9 +1259,10 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges()
data->maxSize = QWIDGETSIZE_MAX;
data->skipInPreferred = 1;
- // Set the Layout Left edge as the root of the horizontal graph.
- AnchorVertex *v = internalVertex(layout, Qt::AnchorLeft);
- graph[Horizontal].setRootVertex(v);
+ // Save a reference to layout vertices
+ layoutFirstVertex[Horizontal] = internalVertex(layout, Qt::AnchorLeft);
+ layoutCentralVertex[Horizontal] = 0;
+ layoutLastVertex[Horizontal] = internalVertex(layout, Qt::AnchorRight);
// Vertical
data = new AnchorData;
@@ -970,17 +1271,18 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges()
data->maxSize = QWIDGETSIZE_MAX;
data->skipInPreferred = 1;
- // Set the Layout Top edge as the root of the vertical graph.
- v = internalVertex(layout, Qt::AnchorTop);
- graph[Vertical].setRootVertex(v);
+ // Save a reference to layout vertices
+ layoutFirstVertex[Vertical] = internalVertex(layout, Qt::AnchorTop);
+ layoutCentralVertex[Vertical] = 0;
+ layoutLastVertex[Vertical] = internalVertex(layout, Qt::AnchorBottom);
}
void QGraphicsAnchorLayoutPrivate::deleteLayoutEdges()
{
Q_Q(QGraphicsAnchorLayout);
- Q_ASSERT(internalVertex(q, Qt::AnchorHorizontalCenter) == NULL);
- Q_ASSERT(internalVertex(q, Qt::AnchorVerticalCenter) == NULL);
+ Q_ASSERT(!internalVertex(q, Qt::AnchorHorizontalCenter));
+ Q_ASSERT(!internalVertex(q, Qt::AnchorVerticalCenter));
removeAnchor_helper(internalVertex(q, Qt::AnchorLeft),
internalVertex(q, Qt::AnchorRight));
@@ -1019,6 +1321,8 @@ void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item)
void QGraphicsAnchorLayoutPrivate::createCenterAnchors(
QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge)
{
+ Q_Q(QGraphicsAnchorLayout);
+
Orientation orientation;
switch (centerEdge) {
case Qt::AnchorHorizontalCenter:
@@ -1061,24 +1365,32 @@ void QGraphicsAnchorLayoutPrivate::createCenterAnchors(
c->variables.insert(data, 1.0);
addAnchor_helper(item, firstEdge, item, centerEdge, data);
data->isCenterAnchor = true;
+ data->dependency = AnchorData::Master;
data->refreshSizeHints(0);
data = new AnchorData;
c->variables.insert(data, -1.0);
addAnchor_helper(item, centerEdge, item, lastEdge, data);
data->isCenterAnchor = true;
+ data->dependency = AnchorData::Slave;
data->refreshSizeHints(0);
itemCenterConstraints[orientation].append(c);
// Remove old one
removeAnchor_helper(first, last);
+
+ if (item == q) {
+ layoutCentralVertex[orientation] = internalVertex(q, centerEdge);
+ }
}
void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge,
bool substitute)
{
+ Q_Q(QGraphicsAnchorLayout);
+
Orientation orientation;
switch (centerEdge) {
case Qt::AnchorHorizontalCenter:
@@ -1120,7 +1432,7 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
AnchorData *oldData = g.edgeData(first, center);
// Remove center constraint
for (int i = itemCenterConstraints[orientation].count() - 1; i >= 0; --i) {
- if (itemCenterConstraints[orientation][i]->variables.contains(oldData)) {
+ if (itemCenterConstraints[orientation].at(i)->variables.contains(oldData)) {
delete itemCenterConstraints[orientation].takeAt(i);
break;
}
@@ -1151,6 +1463,10 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
// by this time, the center vertex is deleted and merged into a non-centered internal anchor
removeAnchor_helper(first, internalVertex(item, lastEdge));
}
+
+ if (item == q) {
+ layoutCentralVertex[orientation] = 0;
+ }
}
@@ -1180,7 +1496,7 @@ void QGraphicsAnchorLayoutPrivate::removeCenterConstraints(QGraphicsLayoutItem *
// Look for our anchor in all item center constraints, then remove it
for (int i = 0; i < itemCenterConstraints[orientation].size(); ++i) {
- if (itemCenterConstraints[orientation][i]->variables.contains(internalAnchor)) {
+ if (itemCenterConstraints[orientation].at(i)->variables.contains(internalAnchor)) {
delete itemCenterConstraints[orientation].takeAt(i);
break;
}
@@ -1690,7 +2006,7 @@ QList<AnchorData *> getVariables(QList<QSimplexConstraint *> constraints)
{
QSet<AnchorData *> variableSet;
for (int i = 0; i < constraints.count(); ++i) {
- const QSimplexConstraint *c = constraints[i];
+ const QSimplexConstraint *c = constraints.at(i);
foreach (QSimplexVariable *var, c->variables.keys()) {
variableSet += static_cast<AnchorData *>(var);
}
@@ -1724,12 +2040,19 @@ QList<AnchorData *> getVariables(QList<QSimplexConstraint *> constraints)
void QGraphicsAnchorLayoutPrivate::calculateGraphs(
QGraphicsAnchorLayoutPrivate::Orientation orientation)
{
- Q_Q(QGraphicsAnchorLayout);
-
#if defined(QT_DEBUG) || defined(Q_AUTOTEST_EXPORT)
lastCalculationUsedSimplex[orientation] = false;
#endif
+ // ### This is necessary because now we do vertex simplification, we still don't know
+ // differentiate between invalidate()s that doesn't need resimplification and those which
+ // need. For example, when size hint of an item changes, this may cause an anchor to reach 0 or to
+ // leave 0 and get a size. In both cases we need resimplify.
+ //
+ // ### one possible solution would be tracking all the 0-sized anchors, if this set change, we need
+ // resimplify.
+ restoreSimplifiedGraph(orientation);
+
// Reset the nominal sizes of each anchor based on the current item sizes. This function
// works with both simplified and non-simplified graphs, so it'll work when the
// simplification is going to be reused.
@@ -1768,12 +2091,12 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
// Now run the simplex solver to calculate Minimum, Preferred and Maximum sizes
// of the "trunk" set of constraints and variables.
// ### does trunk always exist? empty = trunk is the layout left->center->right
- QList<QSimplexConstraint *> trunkConstraints = parts[0];
+ QList<QSimplexConstraint *> trunkConstraints = parts.at(0);
QList<AnchorData *> trunkVariables = getVariables(trunkConstraints);
// For minimum and maximum, use the path between the two layout sides as the
// objective function.
- AnchorVertex *v = internalVertex(q, pickEdge(Qt::AnchorRight, orientation));
+ AnchorVertex *v = layoutLastVertex[orientation];
GraphPath trunkPath = graphPaths[orientation].value(v);
bool feasible = calculateTrunk(orientation, trunkPath, trunkConstraints, trunkVariables);
@@ -1787,7 +2110,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
if (!feasible)
break;
- QList<QSimplexConstraint *> partConstraints = parts[i];
+ QList<QSimplexConstraint *> partConstraints = parts.at(i);
QList<AnchorData *> partVariables = getVariables(partConstraints);
Q_ASSERT(!partVariables.isEmpty());
feasible &= calculateNonTrunk(partConstraints, partVariables);
@@ -1836,27 +2159,19 @@ bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const
if (feasible) {
solvePreferred(allConstraints, variables);
- // Note that we don't include the sizeHintConstraints, since they
- // have a different logic for solveExpanding().
- solveExpanding(constraints, variables);
-
- // Calculate and set the preferred and expanding sizes for the layout,
+ // Calculate and set the preferred size for the layout,
// from the edge sizes that were calculated above.
qreal pref(0.0);
- qreal expanding(0.0);
foreach (const AnchorData *ad, path.positives) {
pref += ad->sizeAtPreferred;
- expanding += ad->sizeAtExpanding;
}
foreach (const AnchorData *ad, path.negatives) {
pref -= ad->sizeAtPreferred;
- expanding -= ad->sizeAtExpanding;
}
sizeHints[orientation][Qt::MinimumSize] = min;
sizeHints[orientation][Qt::PreferredSize] = pref;
sizeHints[orientation][Qt::MaximumSize] = max;
- sizeAtExpanding[orientation] = expanding;
}
qDeleteAll(sizeHintConstraints);
@@ -1870,13 +2185,11 @@ bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const
AnchorData *ad = path.positives.toList()[0];
ad->sizeAtMinimum = ad->minSize;
ad->sizeAtPreferred = ad->prefSize;
- ad->sizeAtExpanding = ad->expSize;
ad->sizeAtMaximum = ad->maxSize;
sizeHints[orientation][Qt::MinimumSize] = ad->sizeAtMinimum;
sizeHints[orientation][Qt::PreferredSize] = ad->sizeAtPreferred;
sizeHints[orientation][Qt::MaximumSize] = ad->sizeAtMaximum;
- sizeAtExpanding[orientation] = ad->sizeAtExpanding;
}
#if defined(QT_DEBUG) || defined(Q_AUTOTEST_EXPORT)
@@ -1899,10 +2212,9 @@ bool QGraphicsAnchorLayoutPrivate::calculateNonTrunk(const QList<QSimplexConstra
// Propagate size at preferred to other sizes. Semi-floats always will be
// in their sizeAtPreferred.
for (int j = 0; j < variables.count(); ++j) {
- AnchorData *ad = variables[j];
+ AnchorData *ad = variables.at(j);
Q_ASSERT(ad);
ad->sizeAtMinimum = ad->sizeAtPreferred;
- ad->sizeAtExpanding = ad->sizeAtPreferred;
ad->sizeAtMaximum = ad->sizeAtPreferred;
}
}
@@ -1955,7 +2267,7 @@ void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation)
QSet<AnchorData *> visited;
- AnchorVertex *root = graph[orientation].rootVertex();
+ AnchorVertex *root = layoutFirstVertex[orientation];
graphPaths[orientation].insert(root, GraphPath());
@@ -2013,7 +2325,7 @@ void QGraphicsAnchorLayoutPrivate::constraintsFromPaths(Orientation orientation)
QList<GraphPath> pathsToVertex = graphPaths[orientation].values(vertex);
for (int i = 1; i < valueCount; ++i) {
constraints[orientation] += \
- pathsToVertex[0].constraint(pathsToVertex[i]);
+ pathsToVertex[0].constraint(pathsToVertex.at(i));
}
}
}
@@ -2041,9 +2353,37 @@ void QGraphicsAnchorLayoutPrivate::updateAnchorSizes(Orientation orientation)
QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHints(
const QList<AnchorData *> &anchors)
{
+ if (anchors.isEmpty())
+ return QList<QSimplexConstraint *>();
+
+ // Look for the layout edge. That can be either the first half in case the
+ // layout is split in two, or the whole layout anchor.
+ Orientation orient = Orientation(anchors.first()->orientation);
+ AnchorData *layoutEdge = 0;
+ if (layoutCentralVertex[orient]) {
+ layoutEdge = graph[orient].edgeData(layoutFirstVertex[orient], layoutCentralVertex[orient]);
+ } else {
+ layoutEdge = graph[orient].edgeData(layoutFirstVertex[orient], layoutLastVertex[orient]);
+
+ // If maxSize is less then "infinite", that means there are other anchors
+ // grouped together with this one. We can't ignore its maximum value so we
+ // set back the variable to NULL to prevent the continue condition from being
+ // satisfied in the loop below.
+ if (layoutEdge->maxSize < QWIDGETSIZE_MAX)
+ layoutEdge = 0;
+ }
+
+ // For each variable, create constraints based on size hints
QList<QSimplexConstraint *> anchorConstraints;
+ bool unboundedProblem = true;
for (int i = 0; i < anchors.size(); ++i) {
- AnchorData *ad = anchors[i];
+ AnchorData *ad = anchors.at(i);
+
+ // Anchors that have their size directly linked to another one don't need constraints
+ // For exammple, the second half of an item has exactly the same size as the first half
+ // thus constraining the latter is enough.
+ if (ad->dependency == AnchorData::Slave)
+ continue;
if ((ad->minSize == ad->maxSize) || qFuzzyCompare(ad->minSize, ad->maxSize)) {
QSimplexConstraint *c = new QSimplexConstraint;
@@ -2051,6 +2391,7 @@ QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin
c->constant = ad->minSize;
c->ratio = QSimplexConstraint::Equal;
anchorConstraints += c;
+ unboundedProblem = false;
} else {
QSimplexConstraint *c = new QSimplexConstraint;
c->variables.insert(ad, 1.0);
@@ -2058,14 +2399,30 @@ QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin
c->ratio = QSimplexConstraint::MoreOrEqual;
anchorConstraints += c;
+ // We avoid adding restrictions to the layout internal anchors. That's
+ // to prevent unnecessary fair distribution from happening due to this
+ // artificial restriction.
+ if (ad == layoutEdge)
+ continue;
+
c = new QSimplexConstraint;
c->variables.insert(ad, 1.0);
c->constant = ad->maxSize;
c->ratio = QSimplexConstraint::LessOrEqual;
anchorConstraints += c;
+ unboundedProblem = false;
}
}
+ // If no upper boundary restriction was added, add one to avoid unbounded problem
+ if (unboundedProblem) {
+ QSimplexConstraint *c = new QSimplexConstraint;
+ c->variables.insert(layoutEdge, 1.0);
+ c->constant = QWIDGETSIZE_MAX;
+ c->ratio = QSimplexConstraint::LessOrEqual;
+ anchorConstraints += c;
+ }
+
return anchorConstraints;
}
@@ -2075,38 +2432,26 @@ QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin
QList< QList<QSimplexConstraint *> >
QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
{
- Q_Q(QGraphicsAnchorLayout);
+ Q_ASSERT(layoutFirstVertex[orientation] && layoutLastVertex[orientation]);
- // Find layout vertices and edges for the current orientation.
- AnchorVertex *layoutFirstVertex = \
- internalVertex(q, pickEdge(Qt::AnchorLeft, orientation));
-
- AnchorVertex *layoutCentralVertex = \
- internalVertex(q, pickEdge(Qt::AnchorHorizontalCenter, orientation));
-
- AnchorVertex *layoutLastVertex = \
- internalVertex(q, pickEdge(Qt::AnchorRight, orientation));
-
- Q_ASSERT(layoutFirstVertex && layoutLastVertex);
-
- AnchorData *edgeL1 = NULL;
- AnchorData *edgeL2 = NULL;
+ AnchorData *edgeL1 = 0;
+ AnchorData *edgeL2 = 0;
// The layout may have a single anchor between Left and Right or two half anchors
// passing through the center
- if (layoutCentralVertex) {
- edgeL1 = graph[orientation].edgeData(layoutFirstVertex, layoutCentralVertex);
- edgeL2 = graph[orientation].edgeData(layoutCentralVertex, layoutLastVertex);
+ if (layoutCentralVertex[orientation]) {
+ edgeL1 = graph[orientation].edgeData(layoutFirstVertex[orientation], layoutCentralVertex[orientation]);
+ edgeL2 = graph[orientation].edgeData(layoutCentralVertex[orientation], layoutLastVertex[orientation]);
} else {
- edgeL1 = graph[orientation].edgeData(layoutFirstVertex, layoutLastVertex);
+ edgeL1 = graph[orientation].edgeData(layoutFirstVertex[orientation], layoutLastVertex[orientation]);
}
QLinkedList<QSimplexConstraint *> remainingConstraints;
for (int i = 0; i < constraints[orientation].count(); ++i) {
- remainingConstraints += constraints[orientation][i];
+ remainingConstraints += constraints[orientation].at(i);
}
for (int i = 0; i < itemCenterConstraints[orientation].count(); ++i) {
- remainingConstraints += itemCenterConstraints[orientation][i];
+ remainingConstraints += itemCenterConstraints[orientation].at(i);
}
QList<QSimplexConstraint *> trunkConstraints;
@@ -2276,6 +2621,21 @@ void QGraphicsAnchorLayoutPrivate::setItemsGeometries(const QRectF &geom)
}
/*!
+ \internal
+
+ Fill the distance in the vertex and in the sub-vertices if its a combined vertex.
+*/
+static void setVertexDistance(AnchorVertex *v, qreal distance)
+{
+ v->distance = distance;
+ if (v->m_type == AnchorVertex::Pair) {
+ AnchorVertexPair *pair = static_cast<AnchorVertexPair *>(v);
+ setVertexDistance(pair->m_first, distance);
+ setVertexDistance(pair->m_second, distance);
+ }
+}
+
+/*!
\internal
Calculate the position of each vertex based on the paths to each of
@@ -2288,9 +2648,9 @@ void QGraphicsAnchorLayoutPrivate::calculateVertexPositions(
QSet<AnchorVertex *> visited;
// Get root vertex
- AnchorVertex *root = graph[orientation].rootVertex();
+ AnchorVertex *root = layoutFirstVertex[orientation];
- root->distance = 0;
+ setVertexDistance(root, 0);
visited.insert(root);
// Add initial edges to the queue
@@ -2314,7 +2674,7 @@ void QGraphicsAnchorLayoutPrivate::calculateVertexPositions(
continue;
visited.insert(pair.second);
- interpolateEdge(pair.first, edge, orientation);
+ interpolateEdge(pair.first, edge);
QList<AnchorVertex *> adjacents = graph[orientation].adjacentVertices(pair.second);
for (int i = 0; i < adjacents.count(); ++i) {
@@ -2343,7 +2703,6 @@ void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation(
result = getFactor(current,
sizeHints[orientation][Qt::MinimumSize],
sizeHints[orientation][Qt::PreferredSize],
- sizeAtExpanding[orientation],
sizeHints[orientation][Qt::MaximumSize]);
interpolationInterval[orientation] = result.first;
@@ -2358,7 +2717,6 @@ void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation(
- minimum size,
- preferred size,
- - size when all expanding anchors are expanded,
- maximum size.
These three key values are calculated in advance using linear
@@ -2370,36 +2728,32 @@ void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation(
vertices to be initalized, so it calls specialized functions that
will recurse back to interpolateEdge().
*/
-void QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorVertex *base,
- AnchorData *edge,
- Orientation orientation)
+void QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorVertex *base, AnchorData *edge)
{
+ const Orientation orientation = Orientation(edge->orientation);
const QPair<Interval, qreal> factor(interpolationInterval[orientation],
interpolationProgress[orientation]);
qreal edgeDistance = interpolate(factor, edge->sizeAtMinimum, edge->sizeAtPreferred,
- edge->sizeAtExpanding, edge->sizeAtMaximum);
+ edge->sizeAtMaximum);
Q_ASSERT(edge->from == base || edge->to == base);
- if (edge->from == base)
- edge->to->distance = base->distance + edgeDistance;
- else
- edge->from->distance = base->distance - edgeDistance;
+ // Calculate the distance for the vertex opposite to the base
+ if (edge->from == base) {
+ setVertexDistance(edge->to, base->distance + edgeDistance);
+ } else {
+ setVertexDistance(edge->from, base->distance - edgeDistance);
+ }
// Process child anchors
if (edge->type == AnchorData::Sequential)
- interpolateSequentialEdges(edge->from,
- static_cast<SequentialAnchorData *>(edge),
- orientation);
+ interpolateSequentialEdges(static_cast<SequentialAnchorData *>(edge));
else if (edge->type == AnchorData::Parallel)
- interpolateParallelEdges(edge->from,
- static_cast<ParallelAnchorData *>(edge),
- orientation);
+ interpolateParallelEdges(static_cast<ParallelAnchorData *>(edge));
}
-void QGraphicsAnchorLayoutPrivate::interpolateParallelEdges(
- AnchorVertex *base, ParallelAnchorData *data, Orientation orientation)
+void QGraphicsAnchorLayoutPrivate::interpolateParallelEdges(ParallelAnchorData *data)
{
// In parallels the boundary vertices are already calculate, we
// just need to look for sequential groups inside, because only
@@ -2407,46 +2761,44 @@ void QGraphicsAnchorLayoutPrivate::interpolateParallelEdges(
// First edge
if (data->firstEdge->type == AnchorData::Sequential)
- interpolateSequentialEdges(base,
- static_cast<SequentialAnchorData *>(data->firstEdge),
- orientation);
+ interpolateSequentialEdges(static_cast<SequentialAnchorData *>(data->firstEdge));
else if (data->firstEdge->type == AnchorData::Parallel)
- interpolateParallelEdges(base,
- static_cast<ParallelAnchorData *>(data->firstEdge),
- orientation);
+ interpolateParallelEdges(static_cast<ParallelAnchorData *>(data->firstEdge));
// Second edge
if (data->secondEdge->type == AnchorData::Sequential)
- interpolateSequentialEdges(base,
- static_cast<SequentialAnchorData *>(data->secondEdge),
- orientation);
+ interpolateSequentialEdges(static_cast<SequentialAnchorData *>(data->secondEdge));
else if (data->secondEdge->type == AnchorData::Parallel)
- interpolateParallelEdges(base,
- static_cast<ParallelAnchorData *>(data->secondEdge),
- orientation);
+ interpolateParallelEdges(static_cast<ParallelAnchorData *>(data->secondEdge));
}
-void QGraphicsAnchorLayoutPrivate::interpolateSequentialEdges(
- AnchorVertex *base, SequentialAnchorData *data, Orientation orientation)
+void QGraphicsAnchorLayoutPrivate::interpolateSequentialEdges(SequentialAnchorData *data)
{
- AnchorVertex *prev = base;
+ // This method is supposed to handle any sequential anchor, even out-of-order
+ // ones. However, in the current QGAL implementation we should get only the
+ // well behaved ones.
+ Q_ASSERT(data->m_edges.first()->from == data->from);
+ Q_ASSERT(data->m_edges.last()->to == data->to);
- // ### I'm not sure whether this assumption is safe. If not,
- // consider that m_edges.last() could be used instead (so
- // at(0) would be the one to be treated specially).
- Q_ASSERT(base == data->m_edges.at(0)->to || base == data->m_edges.at(0)->from);
+ // At this point, the two outter vertices already have their distance
+ // calculated.
+ // We use the first as the base to calculate the internal ones
+
+ AnchorVertex *prev = data->from;
- // Skip the last
for (int i = 0; i < data->m_edges.count() - 1; ++i) {
- AnchorData *child = data->m_edges.at(i);
- interpolateEdge(prev, child, orientation);
- prev = child->to;
+ AnchorData *edge = data->m_edges.at(i);
+ interpolateEdge(prev, edge);
+
+ // Use the recently calculated vertex as the base for the next one
+ const bool edgeIsForward = (edge->from == prev);
+ prev = edgeIsForward ? edge->to : edge->from;
}
// Treat the last specially, since we already calculated it's end
// vertex, so it's only interesting if it's a complex one
if (data->m_edges.last()->type != AnchorData::Normal)
- interpolateEdge(prev, data->m_edges.last(), orientation);
+ interpolateEdge(prev, data->m_edges.last());
}
bool QGraphicsAnchorLayoutPrivate::solveMinMax(const QList<QSimplexConstraint *> &constraints,
@@ -2472,9 +2824,10 @@ bool QGraphicsAnchorLayoutPrivate::solveMinMax(const QList<QSimplexConstraint *>
// Save sizeAtMinimum results
QList<AnchorData *> variables = getVariables(constraints);
for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = static_cast<AnchorData *>(variables[i]);
- Q_ASSERT(ad->result >= ad->minSize || qFuzzyCompare(ad->result, ad->minSize));
+ AnchorData *ad = static_cast<AnchorData *>(variables.at(i));
ad->sizeAtMinimum = ad->result;
+ Q_ASSERT(ad->sizeAtMinimum >= ad->minSize ||
+ qAbs(ad->sizeAtMinimum - ad->minSize) < 0.00000001);
}
// Calculate maximum values
@@ -2482,9 +2835,10 @@ bool QGraphicsAnchorLayoutPrivate::solveMinMax(const QList<QSimplexConstraint *>
// Save sizeAtMaximum results
for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = static_cast<AnchorData *>(variables[i]);
- Q_ASSERT(ad->result <= ad->maxSize || qFuzzyCompare(ad->result, ad->maxSize));
+ AnchorData *ad = static_cast<AnchorData *>(variables.at(i));
ad->sizeAtMaximum = ad->result;
+ // Q_ASSERT(ad->sizeAtMaximum <= ad->maxSize ||
+ // qAbs(ad->sizeAtMaximum - ad->maxSize) < 0.00000001);
}
}
return feasible;
@@ -2515,7 +2869,7 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint
// A + A_shrinker - A_grower = A_pref
//
for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = variables[i];
+ AnchorData *ad = variables.at(i);
if (ad->skipInPreferred)
continue;
@@ -2546,7 +2900,7 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint
// Save sizeAtPreferred results
for (int i = 0; i < variables.size(); ++i) {
- AnchorData *ad = variables[i];
+ AnchorData *ad = variables.at(i);
ad->sizeAtPreferred = ad->result;
}
@@ -2563,139 +2917,6 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint
/*!
\internal
- Calculate the "expanding" keyframe
-
- This new keyframe sits between the already existing sizeAtPreferred and
- sizeAtMaximum keyframes. Its goal is to modify the interpolation between
- the latter as to respect the "expanding" size policy of some anchors.
-
- Previously all items would be subject to a linear interpolation between
- sizeAtPreferred and sizeAtMaximum values. This will change now, the
- expanding anchors will change their size before the others. To calculate
- this keyframe we use the following logic:
-
- 1) Ask each anchor for their desired expanding size (ad->expSize), this
- value depends on the anchor expanding property in the following way:
-
- - Expanding normal anchors want to grow towards their maximum size
- - Non-expanding normal anchors want to remain at their preferred size.
- - Sequential anchors wants to grow towards a size that is calculated by:
- summarizing it's child anchors, where it will use preferred size for non-expanding anchors
- and maximum size for expanding anchors.
- - Parallel anchors want to grow towards the smallest maximum size of all the expanding anchors.
-
- 2) Clamp their desired values to the value they assume in the neighbour
- keyframes (sizeAtPreferred and sizeAtExpanding)
-
- 3) Run simplex with a setup that ensures the following:
-
- a. Anchors will change their value from their sizeAtPreferred towards
- their sizeAtMaximum as much as required to ensure that ALL anchors
- reach their respective "desired" expanding sizes.
-
- b. No anchors will change their value beyond what is NEEDED to satisfy
- the requirement above.
-
- The final result is that, at the "expanding" keyframe expanding anchors
- will grow and take with them all anchors that are parallel to them.
- However, non-expanding anchors will remain at their preferred size unless
- they are forced to grow by a parallel expanding anchor.
-
- Note: For anchors where the sizeAtPreferred is bigger than sizeAtMaximum,
- the visual effect when the layout grows from its preferred size is
- the following: Expanding anchors will keep their size while non
- expanding ones will shrink. Only after non-expanding anchors have
- shrinked all the way, the expanding anchors will start to shrink too.
-*/
-void QGraphicsAnchorLayoutPrivate::solveExpanding(const QList<QSimplexConstraint *> &constraints,
- const QList<AnchorData *> &variables)
-{
- QList<QSimplexConstraint *> itemConstraints;
- QSimplexConstraint *objective = new QSimplexConstraint;
- bool hasExpanding = false;
-
- // Construct the simplex constraints and objective
- for (int i = 0; i < variables.size(); ++i) {
- // For each anchor
- AnchorData *ad = variables[i];
-
- // Clamp the desired expanding size
- qreal upperBoundary = qMax(ad->sizeAtPreferred, ad->sizeAtMaximum);
- qreal lowerBoundary = qMin(ad->sizeAtPreferred, ad->sizeAtMaximum);
- qreal boundedExpSize = qBound(lowerBoundary, ad->expSize, upperBoundary);
-
- // Expanding anchors are those that want to move from their preferred size
- if (boundedExpSize != ad->sizeAtPreferred)
- hasExpanding = true;
-
- // Lock anchor between boundedExpSize and sizeAtMaximum (ensure 3.a)
- if (boundedExpSize == ad->sizeAtMaximum || qFuzzyCompare(boundedExpSize, ad->sizeAtMaximum)) {
- // The interval has only one possible value, we can use an "Equal"
- // constraint and don't need to add this variable to the objective.
- QSimplexConstraint *itemC = new QSimplexConstraint;
- itemC->ratio = QSimplexConstraint::Equal;
- itemC->variables.insert(ad, 1.0);
- itemC->constant = boundedExpSize;
- itemConstraints << itemC;
- } else {
- // Add MoreOrEqual and LessOrEqual constraints.
- QSimplexConstraint *itemC = new QSimplexConstraint;
- itemC->ratio = QSimplexConstraint::MoreOrEqual;
- itemC->variables.insert(ad, 1.0);
- itemC->constant = qMin(boundedExpSize, ad->sizeAtMaximum);
- itemConstraints << itemC;
-
- itemC = new QSimplexConstraint;
- itemC->ratio = QSimplexConstraint::LessOrEqual;
- itemC->variables.insert(ad, 1.0);
- itemC->constant = qMax(boundedExpSize, ad->sizeAtMaximum);
- itemConstraints << itemC;
-
- // Create objective to avoid the anchors from moving away from
- // the preferred size more than the needed amount. (ensure 3.b)
- // The objective function is the distance between sizeAtPreferred
- // and sizeAtExpanding, it will be minimized.
- if (ad->sizeAtExpanding < ad->sizeAtMaximum) {
- // Try to shrink this variable towards its sizeAtPreferred value
- objective->variables.insert(ad, 1.0);
- } else {
- // Try to grow this variable towards its sizeAtPreferred value
- objective->variables.insert(ad, -1.0);
- }
- }
- }
-
- // Solve
- if (hasExpanding == false) {
- // If no anchors are expanding, we don't need to run the simplex
- // Set all variables to their preferred size
- for (int i = 0; i < variables.size(); ++i) {
- variables[i]->sizeAtExpanding = variables[i]->sizeAtPreferred;
- }
- } else {
- // Run simplex
- QSimplex simplex;
-
- // Satisfy expanding (3.a)
- bool feasible = simplex.setConstraints(constraints + itemConstraints);
- Q_ASSERT(feasible);
-
- // Reduce damage (3.b)
- simplex.setObjective(objective);
- simplex.solveMin();
-
- // Collect results
- for (int i = 0; i < variables.size(); ++i) {
- variables[i]->sizeAtExpanding = variables[i]->result;
- }
- }
-
- delete objective;
- qDeleteAll(itemConstraints);
-}
-
-/*!
- \internal
Returns true if there are no arrangement that satisfies all constraints.
Otherwise returns false.
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
index 7dd0d65..3ef37f9 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
@@ -78,66 +78,30 @@ QT_BEGIN_NAMESPACE
Represents a vertex (anchorage point) in the internal graph
*/
struct AnchorVertex {
+ enum Type {
+ Normal = 0,
+ Pair
+ };
+
AnchorVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge)
- : m_item(item), m_edge(edge) {}
+ : m_item(item), m_edge(edge), m_type(Normal) {}
AnchorVertex()
- : m_item(0), m_edge(Qt::AnchorPoint(0)) {}
+ : m_item(0), m_edge(Qt::AnchorPoint(0)), m_type(Normal) {}
#ifdef QT_DEBUG
inline QString toString() const;
#endif
+
QGraphicsLayoutItem *m_item;
Qt::AnchorPoint m_edge;
+ uint m_type : 1;
// Current distance from this vertex to the layout edge (Left or Top)
// Value is calculated from the current anchors sizes.
qreal distance;
};
-#ifdef QT_DEBUG
-inline QString AnchorVertex::toString() const
-{
- if (!this || !m_item) {
- return QLatin1String("NULL");
- }
- QString edge;
- switch (m_edge) {
- case Qt::AnchorLeft:
- edge = QLatin1String("Left");
- break;
- case Qt::AnchorHorizontalCenter:
- edge = QLatin1String("HorizontalCenter");
- break;
- case Qt::AnchorRight:
- edge = QLatin1String("Right");
- break;
- case Qt::AnchorTop:
- edge = QLatin1String("Top");
- break;
- case Qt::AnchorVerticalCenter:
- edge = QLatin1String("VerticalCenter");
- break;
- case Qt::AnchorBottom:
- edge = QLatin1String("Bottom");
- break;
- default:
- edge = QLatin1String("None");
- break;
- }
- QString itemName;
- if (m_item->isLayout()) {
- itemName = QLatin1String("layout");
- } else {
- if (QGraphicsItem *item = m_item->graphicsItem()) {
- itemName = item->data(0).toString();
- }
- }
- edge.insert(0, QLatin1String("%1_"));
- return edge.arg(itemName);
-}
-#endif
-
/*!
\internal
@@ -150,14 +114,21 @@ struct AnchorData : public QSimplexVariable {
Parallel
};
+ enum Dependency {
+ Independent = 0,
+ Master,
+ Slave
+ };
+
AnchorData()
: QSimplexVariable(), item(0), from(0), to(0),
- minSize(0), prefSize(0), expSize(0), maxSize(0),
+ minSize(0), prefSize(0), maxSize(0),
sizeAtMinimum(0), sizeAtPreferred(0),
- sizeAtExpanding(0), sizeAtMaximum(0),
+ sizeAtMaximum(0),
graphicsAnchor(0), skipInPreferred(0),
type(Normal), hasSize(true), isLayoutAnchor(false),
- isCenterAnchor(false), orientation(0) {}
+ isCenterAnchor(false), orientation(0),
+ dependency(Independent) {}
virtual void updateChildrenSizes() {}
virtual bool refreshSizeHints(const QLayoutStyleInfo *styleInfo);
@@ -194,7 +165,6 @@ struct AnchorData : public QSimplexVariable {
// size.
qreal minSize;
qreal prefSize;
- qreal expSize;
qreal maxSize;
// These attributes define which sizes should that anchor be in when the
@@ -202,7 +172,6 @@ struct AnchorData : public QSimplexVariable {
// calculated by the Simplex solver based on the current layout setup.
qreal sizeAtMinimum;
qreal sizeAtPreferred;
- qreal sizeAtExpanding;
qreal sizeAtMaximum;
QGraphicsAnchor *graphicsAnchor;
@@ -212,6 +181,7 @@ struct AnchorData : public QSimplexVariable {
uint isLayoutAnchor : 1; // if this anchor is an internal layout anchor
uint isCenterAnchor : 1;
uint orientation : 1;
+ uint dependency : 2; // either Independent, Master or Slave
};
#ifdef QT_DEBUG
@@ -250,10 +220,11 @@ struct ParallelAnchorData : public AnchorData
type = AnchorData::Parallel;
orientation = first->orientation;
- // ### Those asserts force that both child anchors have the same direction,
- // but can't we simplify a pair of anchors in opposite directions?
- Q_ASSERT(first->from == second->from);
- Q_ASSERT(first->to == second->to);
+ // This assert whether the child anchors share their vertices
+ Q_ASSERT(((first->from == second->from) && (first->to == second->to)) ||
+ ((first->from == second->to) && (first->to == second->from)));
+
+ // We arbitrarily choose the direction of the first child as "our" direction
from = first->from;
to = first->to;
#ifdef QT_DEBUG
@@ -268,8 +239,73 @@ struct ParallelAnchorData : public AnchorData
AnchorData* firstEdge;
AnchorData* secondEdge;
+
+ QList<QSimplexConstraint *> m_firstConstraints;
+ QList<QSimplexConstraint *> m_secondConstraints;
};
+struct AnchorVertexPair : public AnchorVertex {
+ AnchorVertexPair(AnchorVertex *v1, AnchorVertex *v2, AnchorData *data)
+ : AnchorVertex(), m_first(v1), m_second(v2), m_removedAnchor(data) {
+ m_type = AnchorVertex::Pair;
+ }
+
+ AnchorVertex *m_first;
+ AnchorVertex *m_second;
+
+ AnchorData *m_removedAnchor;
+ QList<AnchorData *> m_firstAnchors;
+ QList<AnchorData *> m_secondAnchors;
+};
+
+#ifdef QT_DEBUG
+inline QString AnchorVertex::toString() const
+{
+ if (!this) {
+ return QLatin1String("NULL");
+ } else if (m_type == Pair) {
+ const AnchorVertexPair *vp = static_cast<const AnchorVertexPair *>(this);
+ return QString::fromAscii("(%1, %2)").arg(vp->m_first->toString()).arg(vp->m_second->toString());
+ } else if (!m_item) {
+ return QString::fromAscii("NULL_%1").arg(int(this));
+ }
+ QString edge;
+ switch (m_edge) {
+ case Qt::AnchorLeft:
+ edge = QLatin1String("Left");
+ break;
+ case Qt::AnchorHorizontalCenter:
+ edge = QLatin1String("HorizontalCenter");
+ break;
+ case Qt::AnchorRight:
+ edge = QLatin1String("Right");
+ break;
+ case Qt::AnchorTop:
+ edge = QLatin1String("Top");
+ break;
+ case Qt::AnchorVerticalCenter:
+ edge = QLatin1String("VerticalCenter");
+ break;
+ case Qt::AnchorBottom:
+ edge = QLatin1String("Bottom");
+ break;
+ default:
+ edge = QLatin1String("None");
+ break;
+ }
+ QString itemName;
+ if (m_item->isLayout()) {
+ itemName = QLatin1String("layout");
+ } else {
+ if (QGraphicsItem *item = m_item->graphicsItem()) {
+ itemName = item->data(0).toString();
+ }
+ }
+ edge.insert(0, QLatin1String("%1_"));
+ return edge.arg(itemName);
+}
+#endif
+
/*!
\internal
@@ -337,8 +373,7 @@ public:
// Interval represents which interpolation interval are we operating in.
enum Interval {
MinToPreferred = 0,
- PreferredToExpanding,
- ExpandingToMax
+ PreferredToMax
};
// Several structures internal to the layout are duplicated to handle
@@ -427,20 +462,33 @@ public:
QLayoutStyleInfo &styleInfo() const;
- // Activation methods
- bool simplifyGraph(Orientation orientation);
- bool simplifyGraphIteration(Orientation orientation, bool *feasible);
- void restoreSimplifiedGraph(Orientation orientation);
+ AnchorData *addAnchorMaybeParallel(AnchorData *newAnchor, bool *feasible);
+ // Activation
void calculateGraphs();
void calculateGraphs(Orientation orientation);
+ // Simplification
+ bool simplifyGraph(Orientation orientation);
+ bool simplifyVertices(Orientation orientation);
+ bool simplifyGraphIteration(Orientation orientation, bool *feasible);
+
+ bool replaceVertex(Orientation orientation, AnchorVertex *oldV,
+ AnchorVertex *newV, const QList<AnchorData *> &edges);
+
+
+ void restoreSimplifiedGraph(Orientation orientation);
+ void restoreSimplifiedAnchor(AnchorData *edge);
+ void restoreSimplifiedConstraints(ParallelAnchorData *parallel);
+ void restoreVertices(Orientation orientation);
+
bool calculateTrunk(Orientation orientation, const GraphPath &trunkPath,
const QList<QSimplexConstraint *> &constraints,
const QList<AnchorData *> &variables);
bool calculateNonTrunk(const QList<QSimplexConstraint *> &constraints,
const QList<AnchorData *> &variables);
+ // Support functions for calculateGraph()
bool refreshAllSizeHints(Orientation orientation);
void findPaths(Orientation orientation);
void constraintsFromPaths(Orientation orientation);
@@ -460,6 +508,17 @@ public:
return internalVertex(qMakePair(const_cast<QGraphicsLayoutItem *>(item), edge));
}
+ inline void changeLayoutVertex(Orientation orientation, AnchorVertex *oldV, AnchorVertex *newV)
+ {
+ if (layoutFirstVertex[orientation] == oldV)
+ layoutFirstVertex[orientation] = newV;
+ else if (layoutCentralVertex[orientation] == oldV)
+ layoutCentralVertex[orientation] = newV;
+ else if (layoutLastVertex[orientation] == oldV)
+ layoutLastVertex[orientation] = newV;
+ }
+
+
AnchorVertex *addInternalVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge);
void removeInternalVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge);
@@ -468,19 +527,15 @@ public:
void calculateVertexPositions(Orientation orientation);
void setupEdgesInterpolation(Orientation orientation);
- void interpolateEdge(AnchorVertex *base, AnchorData *edge, Orientation orientation);
- void interpolateSequentialEdges(AnchorVertex *base, SequentialAnchorData *edge,
- Orientation orientation);
- void interpolateParallelEdges(AnchorVertex *base, ParallelAnchorData *edge,
- Orientation orientation);
+ void interpolateEdge(AnchorVertex *base, AnchorData *edge);
+ void interpolateSequentialEdges(SequentialAnchorData *edge);
+ void interpolateParallelEdges(ParallelAnchorData *edge);
// Linear Programming solver methods
bool solveMinMax(const QList<QSimplexConstraint *> &constraints,
GraphPath path, qreal *min, qreal *max);
bool solvePreferred(const QList<QSimplexConstraint *> &constraints,
const QList<AnchorData *> &variables);
- void solveExpanding(const QList<QSimplexConstraint *> &constraints,
- const QList<AnchorData *> &variables);
bool hasConflicts() const;
#ifdef QT_DEBUG
@@ -491,7 +546,6 @@ public:
qreal spacings[NOrientations];
// Size hints from simplex engine
qreal sizeHints[2][3];
- qreal sizeAtExpanding[2];
// Items
QVector<QGraphicsLayoutItem *> items;
@@ -504,6 +558,14 @@ public:
// Internal graph of anchorage points and anchors, for both orientations
Graph<AnchorVertex, AnchorData> graph[2];
+ AnchorVertex *layoutFirstVertex[2];
+ AnchorVertex *layoutCentralVertex[2];
+ AnchorVertex *layoutLastVertex[2];
+
+ // Combined anchors in order of creation
+ QList<AnchorVertexPair *> simplifiedVertices[2];
+ QList<AnchorData *> anchorsFromSimplifiedVertices[2];
+
// Graph paths and constraints, for both orientations
QMultiHash<AnchorVertex *, GraphPath> graphPaths[2];
QList<QSimplexConstraint *> constraints[2];
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 52d7020..8474e47 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -386,6 +386,12 @@
introduced in Qt 4.6.
\omitvalue ItemIsFocusScope Internal only (for now).
+
+ \value ItemSendsScenePositionChanges The item enables itemChange()
+ notifications for ItemScenePositionHasChanged. For performance reasons,
+ these notifications are disabled by default. You must enable this flag
+ to receive notifications for scene position changes. This flag was
+ introduced in Qt 4.6.
*/
/*!
@@ -562,6 +568,14 @@
\value ItemOpacityHasChanged The item's opacity has changed. The value
argument is the new opacity (i.e., a double). Do not call setOpacity() as
this notification is delivered. The return value is ignored.
+
+ \value ItemScenePositionHasChanged The item's scene position has changed.
+ This notification is sent if the ItemSendsScenePositionChanges flag is
+ enabled, and after the item's scene position has changed (i.e., the
+ position or transformation of the item itself or the position or
+ transformation of any ancestor has changed). The value argument is the
+ new scene position (the same as scenePos()), and QGraphicsItem ignores
+ the return value for this notification (i.e., a read-only notification).
*/
/*!
@@ -990,6 +1004,10 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
if (scene) {
// Deliver the change to the index
scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant);
+
+ // Disable scene pos notifications for old ancestors
+ if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
+ scene->d_func()->setScenePosItemEnabled(q, false);
}
if (subFocusItem && parent) {
@@ -1084,10 +1102,15 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
parent->d_ptr->addChild(q);
parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant);
- if (!implicitUpdate && scene) {
- scene->d_func()->markDirty(q_ptr, QRect(),
- /*invalidateChildren=*/false,
- /*maybeDirtyClipPath=*/true);
+ if (scene) {
+ if (!implicitUpdate)
+ scene->d_func()->markDirty(q_ptr, QRect(),
+ /*invalidateChildren=*/false,
+ /*maybeDirtyClipPath=*/true);
+
+ // Re-enable scene pos notifications for new ancestors
+ if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
+ scene->d_func()->setScenePosItemEnabled(q, true);
}
// Inherit ancestor flags from the new parent.
@@ -1336,7 +1359,9 @@ QGraphicsItem::~QGraphicsItem()
d_ptr->setParentItemHelper(0);
}
+#ifndef QT_NO_GRAPHICSEFFECT
delete d_ptr->graphicsEffect;
+#endif //QT_NO_GRAPHICSEFFECT
if (d_ptr->transformData) {
for(int i = 0; i < d_ptr->transformData->graphicsTransforms.size(); ++i) {
QGraphicsTransform *t = d_ptr->transformData->graphicsTransforms.at(i);
@@ -1746,6 +1771,12 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
}
if (d_ptr->scene) {
+ if ((flags & ItemSendsScenePositionChanges) != (oldFlags & ItemSendsScenePositionChanges)) {
+ if (flags & ItemSendsScenePositionChanges)
+ d_ptr->scene->d_func()->registerScenePosItem(this);
+ else
+ d_ptr->scene->d_func()->unregisterScenePosItem(this);
+ }
d_ptr->scene->d_func()->markDirty(this, QRectF(),
/*invalidateChildren=*/true,
/*maybeDirtyClipPath*/true);
@@ -2506,7 +2537,9 @@ void QGraphicsItem::setOpacity(qreal opacity)
// Update.
if (d_ptr->scene) {
+#ifndef QT_NO_GRAPHICSEFFECT
d_ptr->invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
d_ptr->scene->d_func()->markDirty(this, QRectF(),
/*invalidateChildren=*/true,
/*maybeDirtyClipPath=*/false,
@@ -2523,6 +2556,7 @@ void QGraphicsItem::setOpacity(qreal opacity)
\since 4.6
*/
+#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsEffect *QGraphicsItem::graphicsEffect() const
{
return d_ptr->graphicsEffect;
@@ -2569,6 +2603,7 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
prepareGeometryChange();
}
+#endif //QT_NO_GRAPHICSEFFECT
/*!
\internal
@@ -2582,6 +2617,7 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
*/
QRectF QGraphicsItemPrivate::effectiveBoundingRect() const
{
+#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsEffect *effect = graphicsEffect;
QRectF brect = effect && effect->isEnabled() ? effect->boundingRect() : q_ptr->boundingRect();
if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
@@ -2598,6 +2634,10 @@ QRectF QGraphicsItemPrivate::effectiveBoundingRect() const
}
return brect;
+#else //QT_NO_GRAPHICSEFFECT
+ return q_ptr->boundingRect();
+#endif //QT_NO_GRAPHICSEFFECT
+
}
/*!
@@ -2951,7 +2991,7 @@ bool QGraphicsItem::hasFocus() const
{
if (d_ptr->focusProxy)
return d_ptr->focusProxy->hasFocus();
- return (d_ptr->scene && d_ptr->scene->focusItem() == this);
+ return isActive() && (d_ptr->scene && d_ptr->scene->focusItem() == this);
}
/*!
@@ -3422,6 +3462,7 @@ void QGraphicsItem::setPos(const QPointF &pos)
// Send post-notification.
itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
+ d_ptr->sendScenePosChange();
}
/*!
@@ -4032,6 +4073,7 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
// Send post-notification.
itemChange(ItemTransformHasChanged, newTransformVariant);
+ d_ptr->sendScenePosChange();
}
/*!
@@ -4256,6 +4298,24 @@ void QGraphicsItemPrivate::ensureSequentialSiblingIndex()
}
/*!
+ \internal
+*/
+inline void QGraphicsItemPrivate::sendScenePosChange()
+{
+ Q_Q(QGraphicsItem);
+ if (scene) {
+ if (flags & QGraphicsItem::ItemSendsScenePositionChanges)
+ q->itemChange(QGraphicsItem::ItemScenePositionHasChanged, q->scenePos());
+ if (scenePosDescendants) {
+ foreach (QGraphicsItem *item, scene->d_func()->scenePosItems) {
+ if (q->isAncestorOf(item))
+ item->itemChange(QGraphicsItem::ItemScenePositionHasChanged, item->scenePos());
+ }
+ }
+ }
+}
+
+/*!
\since 4.6
Stacks this item before \a sibling, which must be a sibling item (i.e., the
@@ -4306,6 +4366,12 @@ void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
++index;
}
d_ptr->siblingIndex = siblingIndex;
+ for (int i = 0; i < siblings->size(); ++i) {
+ int &index = siblings->at(i)->d_ptr->siblingIndex;
+ if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
+ siblings->at(i)->d_ptr->siblingOrderChange();
+ }
+ d_ptr->siblingOrderChange();
}
}
@@ -4987,6 +5053,7 @@ int QGraphicsItemPrivate::depth() const
/*!
\internal
*/
+#ifndef QT_NO_GRAPHICSEFFECT
void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively()
{
QGraphicsItemPrivate *itemPrivate = this;
@@ -4999,6 +5066,7 @@ void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively()
}
} while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
}
+#endif //QT_NO_GRAPHICSEFFECT
/*!
\internal
@@ -5303,6 +5371,16 @@ void QGraphicsItemPrivate::subFocusItemChange()
/*!
\internal
+ Subclasses can reimplement this function to be notified when its
+ siblingIndex order is changed.
+*/
+void QGraphicsItemPrivate::siblingOrderChange()
+{
+}
+
+/*!
+ \internal
+
Tells us if it is a proxy widget
*/
bool QGraphicsItemPrivate::isProxyWidget() const
@@ -5334,7 +5412,9 @@ void QGraphicsItem::update(const QRectF &rect)
return;
// Make sure we notify effects about invalidated source.
+#ifndef QT_NO_GRAPHICSEFFECT
d_ptr->invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
if (CacheMode(d_ptr->cacheMode) != NoCache) {
// Invalidate cache.
@@ -7353,19 +7433,32 @@ QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent
}
/*!
- Subscribes the graphics object to the given \a gesture for the specified \a context.
+ Subscribes the graphics object to the given \a gesture with specific \a flags.
- \sa QGestureEvent
+ \sa ungrabGesture(), QGestureEvent
*/
-
-void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureContext context)
+void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
{
QGraphicsItemPrivate * const d = QGraphicsItem::d_func();
- d->gestureContext.insert(gesture, context);
+ d->gestureContext.insert(gesture, flags);
(void)QGestureManager::instance(); // create a gesture manager
}
/*!
+ Unsubscribes the graphics object from the given \a gesture.
+
+ \sa grabGesture(), QGestureEvent
+*/
+void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
+{
+ QGraphicsItemPrivate * const d = QGraphicsItem::d_func();
+ if (d->gestureContext.remove(gesture)) {
+ QGestureManager *manager = QGestureManager::instance();
+ manager->cleanupCachedGestures(this, gesture);
+ }
+}
+
+/*!
\property QGraphicsObject::parent
\brief the parent of the item
@@ -10675,6 +10768,7 @@ int QGraphicsItemGroup::type() const
return Type;
}
+#ifndef QT_NO_GRAPHICSEFFECT
QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
{
const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
@@ -10814,6 +10908,7 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
return pixmap;
}
+#endif //QT_NO_GRAPHICSEFFECT
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, QGraphicsItem *item)
@@ -10937,6 +11032,9 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemChange change)
case QGraphicsItem::ItemOpacityHasChanged:
str = "ItemOpacityHasChanged";
break;
+ case QGraphicsItem::ItemScenePositionHasChanged:
+ str = "ItemScenePositionHasChanged";
+ break;
}
debug << str;
return debug;
@@ -10994,6 +11092,9 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
case QGraphicsItem::ItemIsFocusScope:
str = "ItemIsFocusScope";
break;
+ case QGraphicsItem::ItemSendsScenePositionChanges:
+ str = "ItemSendsScenePositionChanges";
+ break;
}
debug << str;
return debug;
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index f3fe99c..8bbe9f1 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -105,7 +105,8 @@ public:
ItemAcceptsInputMethod = 0x1000,
ItemNegativeZStacksBehindParent = 0x2000,
ItemIsPanel = 0x4000,
- ItemIsFocusScope = 0x8000 // internal
+ ItemIsFocusScope = 0x8000, // internal
+ ItemSendsScenePositionChanges = 0x10000
// NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag.
};
Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag)
@@ -137,7 +138,8 @@ public:
ItemZValueChange,
ItemZValueHasChanged,
ItemOpacityChange,
- ItemOpacityHasChanged
+ ItemOpacityHasChanged,
+ ItemScenePositionHasChanged
};
enum CacheMode {
@@ -225,9 +227,11 @@ public:
qreal effectiveOpacity() const;
void setOpacity(qreal opacity);
+#ifndef QT_NO_GRAPHICSEFFECT
// Effect
QGraphicsEffect *graphicsEffect() const;
void setGraphicsEffect(QGraphicsEffect *effect);
+#endif //QT_NO_GRAPHICSEFFECT
Qt::MouseButtons acceptedMouseButtons() const;
void setAcceptedMouseButtons(Qt::MouseButtons buttons);
@@ -555,7 +559,8 @@ public:
using QObject::children;
#endif
- void grabGesture(Qt::GestureType type, Qt::GestureContext context = Qt::ItemWithChildrenGesture);
+ void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags());
+ void ungrabGesture(Qt::GestureType type);
Q_SIGNALS:
void parentChanged();
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 395376a..54f7515 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -179,6 +179,7 @@ public:
holesInSiblingIndex(0),
sequentialOrdering(1),
updateDueToGraphicsEffect(0),
+ scenePosDescendants(0),
globalStackingOrder(-1),
q_ptr(0)
{
@@ -223,7 +224,9 @@ public:
bool discardUpdateRequest(bool ignoreClipping = false, bool ignoreVisibleBit = false,
bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
int depth() const;
+#ifndef QT_NO_GRAPHICSEFFECT
void invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
void invalidateDepthRecursively();
void resolveDepth();
void addChild(QGraphicsItem *child);
@@ -429,6 +432,8 @@ public:
inline void ensureSortedChildren();
static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b);
void ensureSequentialSiblingIndex();
+ inline void sendScenePosChange();
+ virtual void siblingOrderChange();
QPainterPath cachedClipPath;
QRectF childrenBoundingRect;
@@ -453,7 +458,7 @@ public:
QGraphicsItem *focusScopeItem;
Qt::InputMethodHints imHints;
QGraphicsItem::PanelModality panelModality;
- QMap<Qt::GestureType, Qt::GestureContext> gestureContext;
+ QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
// Packed 32 bits
quint32 acceptedMouseButtons : 5;
@@ -483,7 +488,7 @@ public:
// Packed 32 bits
quint32 fullUpdatePending : 1;
- quint32 flags : 16;
+ quint32 flags : 17;
quint32 dirtyChildrenBoundingRect : 1;
quint32 paintedViewBoundingRectsNeedRepaint : 1;
quint32 dirtySceneTransform : 1;
@@ -498,14 +503,15 @@ public:
quint32 sceneTransformTranslateOnly : 1;
quint32 notifyBoundingRectChanged : 1;
quint32 notifyInvalidated : 1;
- quint32 mouseSetsFocus : 1;
// New 32 bits
+ quint32 mouseSetsFocus : 1;
quint32 explicitActivate : 1;
quint32 wantsActive : 1;
quint32 holesInSiblingIndex : 1;
quint32 sequentialOrdering : 1;
quint32 updateDueToGraphicsEffect : 1;
+ quint32 scenePosDescendants : 1;
// Optional stacking order
int globalStackingOrder;
@@ -577,6 +583,7 @@ struct QGraphicsItemPaintInfo
quint32 drawItem : 1;
};
+#ifndef QT_NO_GRAPHICSEFFECT
class QGraphicsItemEffectSourcePrivate : public QGraphicsEffectSourcePrivate
{
public:
@@ -604,8 +611,9 @@ public:
inline bool isPixmap() const
{
- return (item->type() == QGraphicsPixmapItem::Type);
- //|| (item->d_ptr->isObject && qobject_cast<QmlGraphicsImage *>(q_func()));
+ return item->type() == QGraphicsPixmapItem::Type
+ && !(item->flags() & QGraphicsItem::ItemIsSelectable)
+ && item->d_ptr->children.size() == 0;
}
inline const QStyleOption *styleOption() const
@@ -630,7 +638,7 @@ public:
QGraphicsItemPaintInfo *info;
QTransform lastEffectTransform;
};
-
+#endif //QT_NO_GRAPHICSEFFECT
/*!
Returns true if \a item1 is on top of \a item2.
diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp
index 5684f0e..cb68741 100644
--- a/src/gui/graphicsview/qgraphicslinearlayout.cpp
+++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp
@@ -542,6 +542,9 @@ void QGraphicsLinearLayout::invalidate()
QGraphicsLayout::invalidate();
}
+/*!
+ \internal
+*/
void QGraphicsLinearLayout::dump(int indent) const
{
#ifdef QT_DEBUG
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index f982f4b..d1845c2 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -294,6 +294,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
needSortTopLevelItems(true),
holesInTopLevelSiblingIndex(false),
topLevelSequentialOrdering(true),
+ scenePosDescendantsUpdatePending(false),
stickyFocus(false),
hasFocus(false),
focusItem(0),
@@ -488,6 +489,55 @@ void QGraphicsScenePrivate::_q_processDirtyItems()
/*!
\internal
+*/
+void QGraphicsScenePrivate::setScenePosItemEnabled(QGraphicsItem *item, bool enabled)
+{
+ QGraphicsItem *p = item->d_ptr->parent;
+ while (p) {
+ p->d_ptr->scenePosDescendants = enabled;
+ p = p->d_ptr->parent;
+ }
+ if (!enabled && !scenePosDescendantsUpdatePending) {
+ scenePosDescendantsUpdatePending = true;
+ QMetaObject::invokeMethod(q_func(), "_q_updateScenePosDescendants", Qt::QueuedConnection);
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::registerScenePosItem(QGraphicsItem *item)
+{
+ scenePosItems.insert(item);
+ setScenePosItemEnabled(item, true);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::unregisterScenePosItem(QGraphicsItem *item)
+{
+ scenePosItems.remove(item);
+ setScenePosItemEnabled(item, false);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsScenePrivate::_q_updateScenePosDescendants()
+{
+ foreach (QGraphicsItem *item, scenePosItems) {
+ QGraphicsItem *p = item->d_ptr->parent;
+ while (p) {
+ p->d_ptr->scenePosDescendants = 1;
+ p = p->d_ptr->parent;
+ }
+ }
+ scenePosDescendantsUpdatePending = false;
+}
+
+/*!
+ \internal
Schedules an item for removal. This function leaves some stale indexes
around in the BSP tree if called from the item's destructor; these will
@@ -523,6 +573,9 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
widget->d_func()->fixFocusChainBeforeReparenting(0, 0);
}
+ if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges)
+ unregisterScenePosItem(item);
+
item->d_func()->scene = 0;
//We need to remove all children first because they might use their parent
@@ -1064,9 +1117,8 @@ bool QGraphicsScenePrivate::filterEvent(QGraphicsItem *item, QEvent *event)
bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event)
{
if (QGraphicsObject *object = item->toGraphicsObject()) {
- QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
- if (qAppPriv->gestureManager) {
- if (qAppPriv->gestureManager->filterEvent(object, event))
+ if (qt_gestureManager) {
+ if (qt_gestureManager->filterEvent(object, event))
return true;
}
}
@@ -2294,8 +2346,9 @@ void QGraphicsScene::clear()
// NB! We have to clear the index before deleting items; otherwise the
// index might try to access dangling item pointers.
d->index->clear();
- const QList<QGraphicsItem *> items = d->topLevelItems;
- qDeleteAll(items);
+ // NB! QGraphicsScenePrivate::unregisterTopLevelItem() removes items
+ while (!d->topLevelItems.isEmpty())
+ delete d->topLevelItems.first();
Q_ASSERT(d->topLevelItems.isEmpty());
d->lastItemCount = 0;
d->allItemsIgnoreHoverEvents = true;
@@ -2541,6 +2594,9 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
}
}
+ if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges)
+ d->registerScenePosItem(item);
+
// Ensure that newly added items that have subfocus set, gain
// focus automatically if there isn't a focus item already.
if (!d->focusItem && item != d->lastFocusItem && item->focusItem() == item)
@@ -2827,18 +2883,20 @@ void QGraphicsScene::removeItem(QGraphicsItem *item)
}
/*!
- Returns the scene's current focus item, or 0 if no item currently has
- focus.
+ When the scene is active, this functions returns the scene's current focus
+ item, or 0 if no item currently has focus. When the scene is inactive, this
+ functions returns the item that will gain input focus when the scene becomes
+ active.
The focus item receives keyboard input when the scene receives a
key event.
- \sa setFocusItem(), QGraphicsItem::hasFocus()
+ \sa setFocusItem(), QGraphicsItem::hasFocus(), isActive()
*/
QGraphicsItem *QGraphicsScene::focusItem() const
{
Q_D(const QGraphicsScene);
- return d->focusItem;
+ return isActive() ? d->focusItem : d->lastFocusItem;
}
/*!
@@ -4578,6 +4636,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
if (itemHasChildren && itemClipsChildrenToShape)
ENSURE_TRANSFORM_PTR;
+#ifndef QT_NO_GRAPHICSEFFECT
if (item->d_ptr->graphicsEffect && item->d_ptr->graphicsEffect->isEnabled()) {
ENSURE_TRANSFORM_PTR;
QGraphicsItemPaintInfo info(viewTransform, transformPtr, effectTransform, exposedRegion, widget, &styleOptionTmp,
@@ -4600,7 +4659,9 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
item->d_ptr->graphicsEffect->draw(painter, source);
painter->setWorldTransform(restoreTransform);
sourced->info = 0;
- } else {
+ } else
+#endif //QT_NO_GRAPHICSEFFECT
+ {
draw(item, painter, viewTransform, transformPtr, exposedRegion, widget, opacity,
effectTransform, wasDirtyParentSceneTransform, drawItem);
}
@@ -4769,10 +4830,12 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b
QGraphicsItem *p = item->d_ptr->parent;
while (p) {
p->d_ptr->dirtyChildren = 1;
+#ifndef QT_NO_GRAPHICSEFFECT
if (p->d_ptr->graphicsEffect && p->d_ptr->graphicsEffect->isEnabled()) {
p->d_ptr->dirty = 1;
p->d_ptr->fullUpdatePending = 1;
}
+#endif //QT_NO_GRAPHICSEFFECT
p = p->d_ptr->parent;
}
}
@@ -5765,7 +5828,7 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
QWidget *viewport = event->widget();
if (!viewport)
return;
- QList<QGesture *> allGestures = event->allGestures();
+ QList<QGesture *> allGestures = event->gestures();
DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
<< "Delivering gestures:" << allGestures;
@@ -5904,7 +5967,12 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
QGraphicsItemPrivate *gid = item->QGraphicsItem::d_func();
foreach(QGesture *g, alreadyIgnoredGestures) {
- if (gid->gestureContext.contains(g->gestureType()))
+ QMap<Qt::GestureType, Qt::GestureFlags>::iterator contextit =
+ gid->gestureContext.find(g->gestureType());
+ bool deliver = contextit != gid->gestureContext.end() &&
+ (g->state() == Qt::GestureStarted ||
+ (contextit.value() & Qt::ReceivePartialGestures));
+ if (deliver)
gestures += g;
}
if (gestures.isEmpty())
@@ -5917,8 +5985,12 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
sendEvent(item, &ev);
QSet<QGesture *> ignoredGestures;
foreach (QGesture *g, gestures) {
- if (!ev.isAccepted() && !ev.isAccepted(g))
+ if (!ev.isAccepted() && !ev.isAccepted(g)) {
ignoredGestures.insert(g);
+ } else {
+ if (g->state() == Qt::GestureStarted)
+ gestureTargets[g] = item;
+ }
}
if (!ignoredGestures.isEmpty()) {
// get a list of items under the (current) hotspot of each ignored
@@ -5945,6 +6017,13 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
continue;
}
}
+ foreach (QGesture *g, startedGestures) {
+ if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) {
+ DEBUG() << "lets try to cancel some";
+ // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them
+ cancelGesturesForChildren(g, event->widget());
+ }
+ }
// forget about targets for gestures that have ended
foreach (QGesture *g, allGestures) {
@@ -5959,6 +6038,88 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
}
}
+void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original, QWidget *viewport)
+{
+ Q_ASSERT(original);
+ QGraphicsItem *originalItem = gestureTargets.value(original);
+ Q_ASSERT(originalItem);
+
+ // iterate over all active gestures and for each find the owner
+ // if the owner is part of our sub-hierarchy, cancel it.
+
+ QSet<QGesture *> canceledGestures;
+ QHash<QGesture *, QGraphicsObject *>::Iterator iter = gestureTargets.begin();
+ while (iter != gestureTargets.end()) {
+ QGraphicsObject *item = iter.value();
+ // note that we don't touch the gestures for our originalItem
+ if (item != originalItem && originalItem->isAncestorOf(item)) {
+ DEBUG() << " found a gesture to cancel" << iter.key();
+ iter.key()->d_func()->state = Qt::GestureCanceled;
+ canceledGestures << iter.key();
+ }
+ ++iter;
+ }
+
+ // sort them per target item by cherry picking from almostCanceledGestures and delivering
+ QSet<QGesture *> almostCanceledGestures = canceledGestures;
+ QSet<QGesture *>::Iterator setIter;
+ while (!almostCanceledGestures.isEmpty()) {
+ QGraphicsObject *target = 0;
+ QSet<QGesture*> gestures;
+ setIter = almostCanceledGestures.begin();
+ // sort per target item
+ while (setIter != almostCanceledGestures.end()) {
+ QGraphicsObject *item = gestureTargets.value(*setIter);
+ if (target == 0)
+ target = item;
+ if (target == item) {
+ gestures << *setIter;
+ setIter = almostCanceledGestures.erase(setIter);
+ } else {
+ ++setIter;
+ }
+ }
+ Q_ASSERT(target);
+
+ QList<QGesture *> list = gestures.toList();
+ QGestureEvent ev(list);
+ sendEvent(target, &ev);
+
+ foreach (QGesture *g, list) {
+ if (ev.isAccepted() || ev.isAccepted(g))
+ gestures.remove(g);
+ }
+
+ foreach (QGesture *g, gestures) {
+ if (!g->hasHotSpot())
+ continue;
+
+ QPoint screenPos = g->hotSpot().toPoint();
+ QList<QGraphicsItem *> items = itemsAtPosition(screenPos, QPointF(), viewport);
+ for (int j = 0; j < items.size(); ++j) {
+ QGraphicsObject *item = items.at(j)->toGraphicsObject();
+ if (!item)
+ continue;
+ QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
+ if (d->gestureContext.contains(g->gestureType())) {
+ QList<QGesture *> list;
+ list << g;
+ QGestureEvent ev(list);
+ sendEvent(item, &ev);
+ if (ev.isAccepted() || ev.isAccepted(g))
+ break; // successfully delivered
+ }
+ }
+ }
+ }
+
+ Q_ASSERT(qt_gestureManager); // it would be very odd if we got called without a manager.
+ for (setIter = canceledGestures.begin(); setIter != canceledGestures.end(); ++setIter) {
+ qt_gestureManager->recycle(*setIter);
+ gestureTargets.remove(*setIter);
+ }
+}
+
QT_END_NAMESPACE
#include "moc_qgraphicsscene.cpp"
diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h
index d6d48d7..a47574e 100644
--- a/src/gui/graphicsview/qgraphicsscene.h
+++ b/src/gui/graphicsview/qgraphicsscene.h
@@ -299,6 +299,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_emitUpdated())
Q_PRIVATE_SLOT(d_func(), void _q_polishItems())
Q_PRIVATE_SLOT(d_func(), void _q_processDirtyItems())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateScenePosDescendants())
friend class QGraphicsItem;
friend class QGraphicsItemPrivate;
friend class QGraphicsView;
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index cd20fd0..fdec466 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -122,6 +122,13 @@ public:
void _q_processDirtyItems();
+ QSet<QGraphicsItem *> scenePosItems;
+ bool scenePosDescendantsUpdatePending;
+ void setScenePosItemEnabled(QGraphicsItem *item, bool enabled);
+ void registerScenePosItem(QGraphicsItem *item);
+ void unregisterScenePosItem(QGraphicsItem *item);
+ void _q_updateScenePosDescendants();
+
void removeItemHelper(QGraphicsItem *item);
QBrush backgroundBrush;
@@ -234,6 +241,7 @@ public:
item->d_ptr->fullUpdatePending = 0;
item->d_ptr->ignoreVisible = 0;
item->d_ptr->ignoreOpacity = 0;
+#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsEffect::ChangeFlags flags;
if (item->d_ptr->notifyBoundingRectChanged) {
flags |= QGraphicsEffect::SourceBoundingRectChanged;
@@ -243,12 +251,15 @@ public:
flags |= QGraphicsEffect::SourceInvalidated;
item->d_ptr->notifyInvalidated = 0;
}
+#endif //QT_NO_GRAPHICSEFFECT
if (recursive) {
for (int i = 0; i < item->d_ptr->children.size(); ++i)
resetDirtyItem(item->d_ptr->children.at(i), recursive);
}
+#ifndef QT_NO_GRAPHICSEFFECT
if (flags && item->d_ptr->graphicsEffect)
item->d_ptr->graphicsEffect->sourceChanged(flags);
+#endif //QT_NO_GRAPHICSEFFECT
}
inline void ensureSortedTopLevelItems()
@@ -288,6 +299,7 @@ public:
QMap<Qt::GestureType, QGesture *> *conflictedGestures,
QList<QList<QGraphicsObject *> > *conflictedItems,
QHash<QGesture *, QGraphicsObject *> *normalGestures);
+ void cancelGesturesForChildren(QGesture *original, QWidget *viewport);
void updateInputMethodSensitivityInViews();
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 9856b1a..87585a2 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -281,6 +281,7 @@ static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime <
#include <QtGui/qstyleoption.h>
#include <QtGui/qinputcontext.h>
#ifdef Q_WS_X11
+#include <QtGui/qpaintengine.h>
#include <private/qt_x11_p.h>
#endif
@@ -1511,6 +1512,11 @@ void QGraphicsView::setScene(QGraphicsScene *scene)
this, SLOT(updateSceneRect(QRectF)));
d->scene->d_func()->removeView(this);
d->connectedToScene = false;
+
+ if (isActiveWindow() && isVisible()) {
+ QEvent windowDeactivate(QEvent::WindowDeactivate);
+ QApplication::sendEvent(d->scene, &windowDeactivate);
+ }
}
// Assign the new scene and update the contents (scrollbars, etc.)).
@@ -1532,6 +1538,11 @@ void QGraphicsView::setScene(QGraphicsScene *scene)
// enable touch events if any items is interested in them
if (!d->scene->d_func()->allItemsIgnoreTouchEvents)
d->viewport->setAttribute(Qt::WA_AcceptTouchEvents);
+
+ if (isActiveWindow() && isVisible()) {
+ QEvent windowActivate(QEvent::WindowActivate);
+ QApplication::sendEvent(d->scene, &windowActivate);
+ }
} else {
d->recalculateContentSize();
}
@@ -2637,6 +2648,19 @@ bool QGraphicsView::viewportEvent(QEvent *event)
d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.first());
QApplication::sendEvent(d->scene, event);
break;
+ case QEvent::Show:
+ if (d->scene && isActiveWindow()) {
+ QEvent windowActivate(QEvent::WindowActivate);
+ QApplication::sendEvent(d->scene, &windowActivate);
+ }
+ break;
+ case QEvent::Hide:
+ // spontaneous event will generate a WindowDeactivate.
+ if (!event->spontaneous() && d->scene && isActiveWindow()) {
+ QEvent windowDeactivate(QEvent::WindowDeactivate);
+ QApplication::sendEvent(d->scene, &windowDeactivate);
+ }
+ break;
case QEvent::Leave:
// ### This is a temporary fix for until we get proper mouse grab
// events. activeMouseGrabberItem should be set to 0 if we lose the
@@ -3257,7 +3281,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
// Set up the painter
QPainter painter(viewport());
- painter.setClipRect(exposedSceneRect, Qt::IntersectClip);
+ painter.setClipRect(event->rect(), Qt::IntersectClip);
#ifndef QT_NO_RUBBERBAND
if (d->rubberBanding && !d->rubberBandRect.isEmpty())
painter.save();
@@ -3297,7 +3321,12 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
backgroundPainter.setClipRegion(d->backgroundPixmapExposed, Qt::ReplaceClip);
if (viewTransformed)
backgroundPainter.setTransform(viewTransform);
- backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source);
+#ifdef Q_WS_X11
+#undef X11
+ if (backgroundPainter.paintEngine()->type() != QPaintEngine::X11)
+#define X11 qt_x11Data
+#endif
+ backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source);
drawBackground(&backgroundPainter, exposedSceneRect);
d->backgroundPixmapExposed = QRegion();
}
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index d70a281..d9c65bb 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -318,6 +318,12 @@ void QGraphicsWidget::resize(const QSizeF &size)
*/
/*!
+ \property QGraphicsWidget::sizePolicy
+ \brief the size policy for the widget
+ \sa sizePolicy(), setSizePolicy(), QWidget::sizePolicy()
+*/
+
+/*!
\property QGraphicsWidget::geometry
\brief the geometry of the widget
@@ -410,6 +416,27 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
*/
/*!
+ \property QGraphicsWidget::minimumSize
+ \brief the minimum size of the widget
+
+ \sa setMinimumSize(), minimumSize(), preferredSize, maximumSize
+*/
+
+/*!
+ \property QGraphicsWidget::preferredSize
+ \brief the preferred size of the widget
+
+ \sa setPreferredSize(), preferredSize(), minimumSize, maximumSize
+*/
+
+/*!
+ \property QGraphicsWidget::maximumSize
+ \brief the maximum size of the widget
+
+ \sa setMaximumSize(), maximumSize(), minimumSize, preferredSize
+*/
+
+/*!
Sets the widget's contents margins to \a left, \a top, \a right and \a
bottom.
diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h
index 9c71140..05d3a49 100644
--- a/src/gui/graphicsview/qgraphicswidget.h
+++ b/src/gui/graphicsview/qgraphicswidget.h
@@ -74,6 +74,10 @@ class Q_GUI_EXPORT QGraphicsWidget : public QGraphicsObject, public QGraphicsLay
Q_PROPERTY(QFont font READ font WRITE setFont)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection RESET unsetLayoutDirection)
Q_PROPERTY(QSizeF size READ size WRITE resize)
+ Q_PROPERTY(QSizeF minimumSize READ minimumSize WRITE setMinimumSize)
+ Q_PROPERTY(QSizeF preferredSize READ preferredSize WRITE setPreferredSize)
+ Q_PROPERTY(QSizeF maximumSize READ maximumSize WRITE setMaximumSize)
+ Q_PROPERTY(QSizePolicy sizePolicy READ sizePolicy WRITE setSizePolicy)
Q_PROPERTY(Qt::FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy)
Q_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags)
Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle)
diff --git a/src/gui/graphicsview/qsimplex_p.cpp b/src/gui/graphicsview/qsimplex_p.cpp
index 86b10b4..cd40f9e 100644
--- a/src/gui/graphicsview/qsimplex_p.cpp
+++ b/src/gui/graphicsview/qsimplex_p.cpp
@@ -288,7 +288,7 @@ bool QSimplex::setConstraints(const QList<QSimplexConstraint *> newConstraints)
// original problem.
// Otherwise, we clean up our structures and report there is
// no feasible solution.
- if (valueAt(0, columns - 1) != 0.0) {
+ if ((valueAt(0, columns - 1) != 0.0) && (qAbs(valueAt(0, columns - 1)) > 0.00001)) {
qWarning() << "QSimplex: No feasible solution!";
clearDataStructures();
return false;
diff --git a/src/gui/graphicsview/qsimplex_p.h b/src/gui/graphicsview/qsimplex_p.h
index 084ad7f..a5816d1 100644
--- a/src/gui/graphicsview/qsimplex_p.h
+++ b/src/gui/graphicsview/qsimplex_p.h
@@ -107,7 +107,7 @@ struct QSimplexConstraint
Q_ASSERT(constant > 0 || qFuzzyCompare(1, 1 + constant));
- if ((leftHandSide == constant) || qFuzzyCompare(1000 + leftHandSide, 1000 + constant))
+ if ((leftHandSide == constant) || qAbs(leftHandSide - constant) < 0.00000001)
return true;
switch (ratio) {
diff --git a/src/gui/image/qbitmap.cpp b/src/gui/image/qbitmap.cpp
index e081735..4b8d4b8 100644
--- a/src/gui/image/qbitmap.cpp
+++ b/src/gui/image/qbitmap.cpp
@@ -86,7 +86,7 @@ QT_BEGIN_NAMESPACE
object.
Just like the QPixmap class, QBitmap is optimized by the use of
- implicit data sharing. For more information, see the {Implicit
+ implicit data sharing. For more information, see the \l {Implicit
Data Sharing} documentation.
\sa QPixmap, QImage, QImageReader, QImageWriter
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 571ef9d..21ca1e3 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -4083,7 +4083,8 @@ QImage QImage::createAlphaMask(Qt::ImageConversionFlags flags) const
}
QImage mask(d->width, d->height, Format_MonoLSB);
- dither_to_Mono(mask.d, d, flags, true);
+ if (!mask.isNull())
+ dither_to_Mono(mask.d, d, flags, true);
return mask;
}
diff --git a/src/gui/image/qimagepixmapcleanuphooks.cpp b/src/gui/image/qimagepixmapcleanuphooks.cpp
index ac30646..35322e9 100644
--- a/src/gui/image/qimagepixmapcleanuphooks.cpp
+++ b/src/gui/image/qimagepixmapcleanuphooks.cpp
@@ -40,7 +40,8 @@
****************************************************************************/
#include "qimagepixmapcleanuphooks_p.h"
-#include "qpixmapdata_p.h"
+#include "private/qpixmapdata_p.h"
+#include "private/qimage_p.h"
QT_BEGIN_NAMESPACE
@@ -132,4 +133,19 @@ void QImagePixmapCleanupHooks::executeImageHooks(qint64 key)
qt_image_cleanup_hook_64(key);
}
+void QImagePixmapCleanupHooks::enableCleanupHooks(const QPixmap &pixmap)
+{
+ enableCleanupHooks(const_cast<QPixmap &>(pixmap).data_ptr().data());
+}
+
+void QImagePixmapCleanupHooks::enableCleanupHooks(QPixmapData *pixmapData)
+{
+ pixmapData->is_cached = true;
+}
+
+void QImagePixmapCleanupHooks::enableCleanupHooks(const QImage &image)
+{
+ const_cast<QImage &>(image).data_ptr()->is_cached = true;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/image/qimagepixmapcleanuphooks_p.h b/src/gui/image/qimagepixmapcleanuphooks_p.h
index 16c8974..9e490d7 100644
--- a/src/gui/image/qimagepixmapcleanuphooks_p.h
+++ b/src/gui/image/qimagepixmapcleanuphooks_p.h
@@ -70,6 +70,10 @@ public:
static QImagePixmapCleanupHooks *instance();
+ static void enableCleanupHooks(const QImage &image);
+ static void enableCleanupHooks(const QPixmap &pixmap);
+ static void enableCleanupHooks(QPixmapData *pixmapData);
+
// Gets called when a pixmap is about to be modified:
void addPixmapModificationHook(_qt_pixmap_cleanup_hook_pm);
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 45ff5f4..dfeea76 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -113,13 +113,10 @@ void QPixmap::init(int w, int h, Type type)
void QPixmap::init(int w, int h, int type)
{
- QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
- if (gs)
- data = gs->createPixmapData(static_cast<QPixmapData::PixelType>(type));
+ if ((w > 0 && h > 0) || type == QPixmapData::BitmapType)
+ data = QPixmapData::create(w, h, (QPixmapData::PixelType) type);
else
- data = QGraphicsSystem::createDefaultPixmapData(static_cast<QPixmapData::PixelType>(type));
-
- data->resize(w, h);
+ data = 0;
}
/*!
@@ -307,7 +304,7 @@ QPixmap::QPixmap(const char * const xpm[])
QImage image(xpm);
if (!image.isNull()) {
- if (data->pixelType() == QPixmapData::BitmapType)
+ if (data && data->pixelType() == QPixmapData::BitmapType)
*this = QBitmap::fromImage(image);
else
*this = fromImage(image);
@@ -322,8 +319,8 @@ QPixmap::QPixmap(const char * const xpm[])
QPixmap::~QPixmap()
{
- Q_ASSERT(data->ref >= 1); // Catch if ref-counting changes again
- if (data->is_cached && data->ref == 1) // ref will be decrememnted after destructor returns
+ Q_ASSERT(!data || data->ref >= 1); // Catch if ref-counting changes again
+ if (data && data->is_cached && data->ref == 1) // ref will be decrememnted after destructor returns
QImagePixmapCleanupHooks::executePixmapDestructionHooks(this);
}
@@ -544,7 +541,7 @@ bool QPixmap::isQBitmap() const
*/
bool QPixmap::isNull() const
{
- return data->isNull();
+ return !data || data->isNull();
}
/*!
@@ -556,7 +553,7 @@ bool QPixmap::isNull() const
*/
int QPixmap::width() const
{
- return data->width();
+ return data ? data->width() : 0;
}
/*!
@@ -568,7 +565,7 @@ int QPixmap::width() const
*/
int QPixmap::height() const
{
- return data->height();
+ return data ? data->height() : 0;
}
/*!
@@ -581,7 +578,7 @@ int QPixmap::height() const
*/
QSize QPixmap::size() const
{
- return QSize(data->width(), data->height());
+ return data ? QSize(data->width(), data->height()) : QSize();
}
/*!
@@ -593,7 +590,7 @@ QSize QPixmap::size() const
*/
QRect QPixmap::rect() const
{
- return QRect(0, 0, data->width(), data->height());
+ return data ? QRect(0, 0, data->width(), data->height()) : QRect();
}
/*!
@@ -609,7 +606,7 @@ QRect QPixmap::rect() const
*/
int QPixmap::depth() const
{
- return data->depth();
+ return data ? data->depth() : 0;
}
/*!
@@ -639,16 +636,16 @@ void QPixmap::resize_helper(const QSize &s)
return;
// Create new pixmap
- QPixmap pm(QSize(w, h), data->type);
+ QPixmap pm(QSize(w, h), data ? data->type : QPixmapData::PixmapType);
bool uninit = false;
#if defined(Q_WS_X11)
- QX11PixmapData *x11Data = data->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(data.data()) : 0;
+ QX11PixmapData *x11Data = data && data->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(data.data()) : 0;
if (x11Data) {
pm.x11SetScreen(x11Data->xinfo.screen());
uninit = x11Data->flags & QX11PixmapData::Uninitialized;
}
#elif defined(Q_WS_MAC)
- QMacPixmapData *macData = data->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data.data()) : 0;
+ QMacPixmapData *macData = data && data->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data.data()) : 0;
if (macData)
uninit = macData->uninit;
#endif
@@ -728,6 +725,9 @@ void QPixmap::setMask(const QBitmap &mask)
return;
}
+ if (isNull())
+ return;
+
if (static_cast<const QPixmap &>(mask).data == data) // trying to selfmask
return;
@@ -826,11 +826,14 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers
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->pixelType());
+ QString::number(info.size()) + QLatin1Char('_') + QString::number(data ? data->pixelType() : QPixmapData::PixmapType);
if (QPixmapCache::find(key, *this))
return true;
+ if (!data)
+ data = QPixmapData::create(0, 0, QPixmapData::PixmapType);
+
if (data->fromFile(fileName, format, flags)) {
QPixmapCache::insert(key, *this);
return true;
@@ -863,6 +866,9 @@ bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Qt::I
if (len == 0 || buf == 0)
return false;
+ if (!data)
+ data = QPixmapData::create(0, 0, QPixmapData::PixmapType);
+
return data->fromData(buf, len, format, flags);
}
@@ -1008,6 +1014,9 @@ int QPixmap::serialNumber() const
*/
qint64 QPixmap::cacheKey() const
{
+ if (isNull())
+ return 0;
+
int classKey = data->classId();
if (classKey >= 1024)
classKey = -(classKey >> 10);
@@ -1224,7 +1233,7 @@ QPixmap::QPixmap(const QImage& image)
QPixmap &QPixmap::operator=(const QImage &image)
{
- if (data->pixelType() == QPixmapData::BitmapType)
+ if (data && data->pixelType() == QPixmapData::BitmapType)
*this = QBitmap::fromImage(image);
else
*this = fromImage(image);
@@ -1254,7 +1263,7 @@ bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Color
*/
bool QPixmap::convertFromImage(const QImage &image, ColorMode mode)
{
- if (data->pixelType() == QPixmapData::BitmapType)
+ if (data && data->pixelType() == QPixmapData::BitmapType)
*this = QBitmap::fromImage(image, colorModeToFlags(mode));
else
*this = fromImage(image, colorModeToFlags(mode));
@@ -1341,7 +1350,7 @@ Q_GUI_EXPORT void copyBlt(QPixmap *dst, int dx, int dy,
bool QPixmap::isDetached() const
{
- return data->ref == 1;
+ return data && data->ref == 1;
}
/*! \internal
@@ -1753,7 +1762,7 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode)
*/
bool QPixmap::hasAlpha() const
{
- return (data->hasAlphaChannel() || !data->mask().isNull());
+ return data && (data->hasAlphaChannel() || !data->mask().isNull());
}
/*!
@@ -1764,7 +1773,7 @@ bool QPixmap::hasAlpha() const
*/
bool QPixmap::hasAlphaChannel() const
{
- return data->hasAlphaChannel();
+ return data && data->hasAlphaChannel();
}
/*!
@@ -1772,7 +1781,7 @@ bool QPixmap::hasAlphaChannel() const
*/
int QPixmap::metric(PaintDeviceMetric metric) const
{
- return data->metric(metric);
+ return data ? data->metric(metric) : 0;
}
/*!
@@ -1844,7 +1853,7 @@ void QPixmap::setAlphaChannel(const QPixmap &alphaChannel)
*/
QPixmap QPixmap::alphaChannel() const
{
- return data->alphaChannel();
+ return data ? data->alphaChannel() : QPixmap();
}
/*!
@@ -1852,7 +1861,7 @@ QPixmap QPixmap::alphaChannel() const
*/
QPaintEngine *QPixmap::paintEngine() const
{
- return data->paintEngine();
+ return data ? data->paintEngine() : 0;
}
/*!
@@ -1867,7 +1876,7 @@ QPaintEngine *QPixmap::paintEngine() const
*/
QBitmap QPixmap::mask() const
{
- return data->mask();
+ return data ? data->mask() : QBitmap();
}
/*!
@@ -1916,6 +1925,9 @@ int QPixmap::defaultDepth()
*/
void QPixmap::detach()
{
+ if (!data)
+ return;
+
QPixmapData::ClassId id = data->classId();
if (id == QPixmapData::RasterClass) {
QRasterPixmapData *rasterData = static_cast<QRasterPixmapData*>(data.data());
diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp
index afa6f83..9209d45 100644
--- a/src/gui/image/qpixmap_mac.cpp
+++ b/src/gui/image/qpixmap_mac.cpp
@@ -305,11 +305,15 @@ void QMacPixmapData::fromImage(const QImage &img,
}
break;
}
- case QImage::Format_Indexed8:
- for (int x = 0; x < w; ++x) {
- *(drow+x) = PREMUL(image.color(*(srow + x)));
+ case QImage::Format_Indexed8: {
+ int numColors = image.numColors();
+ if (numColors > 0) {
+ for (int x = 0; x < w; ++x) {
+ int index = *(srow + x);
+ *(drow+x) = PREMUL(image.color(qMin(index, numColors)));
+ }
}
- break;
+ } break;
case QImage::Format_RGB32:
for (int x = 0; x < w; ++x)
*(drow+x) = *(((quint32*)srow) + x) | 0xFF000000;
@@ -965,6 +969,9 @@ Qt::HANDLE QPixmap::macQDAlphaHandle() const
Qt::HANDLE QPixmap::macCGHandle() const
{
+ if (isNull())
+ return 0;
+
if (data->classId() == QPixmapData::MacClass) {
QMacPixmapData *d = static_cast<QMacPixmapData *>(data.data());
if (!d->cg_data)
diff --git a/src/gui/image/qpixmap_qws.cpp b/src/gui/image/qpixmap_qws.cpp
index 6b4283e..a8516a5 100644
--- a/src/gui/image/qpixmap_qws.cpp
+++ b/src/gui/image/qpixmap_qws.cpp
@@ -114,7 +114,7 @@ QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
QRgb* QPixmap::clut() const
{
- if (data->classId() == QPixmapData::RasterClass) {
+ if (data && data->classId() == QPixmapData::RasterClass) {
const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data());
return d->image.colorTable().data();
}
@@ -124,7 +124,7 @@ QRgb* QPixmap::clut() const
int QPixmap::numCols() const
{
- if (data->classId() == QPixmapData::RasterClass) {
+ if (data && data->classId() == QPixmapData::RasterClass) {
const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data());
return d->image.numColors();
}
@@ -134,7 +134,7 @@ int QPixmap::numCols() const
const uchar* QPixmap::qwsBits() const
{
- if (data->classId() == QPixmapData::RasterClass) {
+ if (data && data->classId() == QPixmapData::RasterClass) {
const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data());
return d->image.bits();
}
@@ -144,7 +144,7 @@ const uchar* QPixmap::qwsBits() const
int QPixmap::qwsBytesPerLine() const
{
- if (data->classId() == QPixmapData::RasterClass) {
+ if (data && data->classId() == QPixmapData::RasterClass) {
const QRasterPixmapData *d = static_cast<const QRasterPixmapData*>(data.data());
return d->image.bytesPerLine();
}
diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp
index 7086341..cd8a4d4 100644
--- a/src/gui/image/qpixmap_s60.cpp
+++ b/src/gui/image/qpixmap_s60.cpp
@@ -73,27 +73,27 @@ const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08,
used to lock the global bitmap heap. Only used in
S60 v3.1 and S60 v3.2.
*/
+_LIT(KFBSERVLargeBitmapAccessName,"FbsLargeBitmapAccess");
class QSymbianFbsClient
{
public:
- QSymbianFbsClient() : heapLock(0), heapLocked(false)
+ QSymbianFbsClient() : heapLocked(false)
{
- QT_TRAP_THROWING(heapLock = new(ELeave) CFbsBitmap);
- heapLock->Create(TSize(0,0), S60->screenDevice()->DisplayMode());
+ heapLock.OpenGlobal(KFBSERVLargeBitmapAccessName);
}
~QSymbianFbsClient()
{
- delete heapLock;
+ heapLock.Close();
}
bool lockHeap()
{
bool wasLocked = heapLocked;
- if (heapLock && !heapLocked) {
- heapLock->LockHeap(ETrue);
+ if (heapLock.Handle() && !heapLocked) {
+ heapLock.Wait();
heapLocked = true;
}
@@ -104,8 +104,8 @@ public:
{
bool wasLocked = heapLocked;
- if (heapLock && heapLocked) {
- heapLock->UnlockHeap(ETrue);
+ if (heapLock.Handle() && heapLocked) {
+ heapLock.Signal();
heapLocked = false;
}
@@ -115,7 +115,7 @@ public:
private:
- CFbsBitmap *heapLock;
+ RMutex heapLock;
bool heapLocked;
};
@@ -169,7 +169,7 @@ public:
inline void beginDataAccess(CFbsBitmap *bitmap)
{
- if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3)
+ if (symbianVersion == QSysInfo::SV_9_2)
heapWasLocked = qt_symbianFbsClient()->lockHeap();
else
bitmap->LockHeap(ETrue);
@@ -177,7 +177,7 @@ public:
inline void endDataAccess(CFbsBitmap *bitmap)
{
- if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) {
+ if (symbianVersion == QSysInfo::SV_9_2) {
if (!heapWasLocked)
qt_symbianFbsClient()->unlockHeap();
} else {
@@ -311,7 +311,7 @@ QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h)
CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const
{
QPixmapData *data = pixmapData();
- if (data->isNull())
+ if (!data || data->isNull())
return 0;
return reinterpret_cast<CFbsBitmap*>(data->toNativeType(QPixmapData::FbsBitmap));
@@ -337,8 +337,9 @@ QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap)
if (!bitmap)
return QPixmap();
- QPixmap pixmap;
- pixmap.pixmapData()->fromNativeType(reinterpret_cast<void*>(bitmap), QPixmapData::FbsBitmap);
+ QScopedPointer<QS60PixmapData> data(new QS60PixmapData(QPixmapData::PixmapType));
+ data->fromNativeType(reinterpret_cast<void*>(bitmap), QPixmapData::FbsBitmap);
+ QPixmap pixmap(data.take());
return pixmap;
}
@@ -751,9 +752,9 @@ QPixmap QPixmap::fromSymbianRSgImage(RSgImage *sgImage)
if (!sgImage)
return QPixmap();
- QPixmap pixmap;
- pixmap.pixmapData()->fromNativeType(reinterpret_cast<void*>(sgImage), QPixmapData::SgImage);
-
+ QScopedPointer<QS60PixmapData> data(new QS60PixmapData(QPixmapData::PixmapType));
+ data->fromNativeType(reinterpret_cast<void*>(sgImage), QPixmapData::SgImage);
+ QPixmap pixmap(data.take());
return pixmap;
}
diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp
index 1b61484..04027c1 100644
--- a/src/gui/image/qpixmap_win.cpp
+++ b/src/gui/image/qpixmap_win.cpp
@@ -121,6 +121,9 @@ QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h )
HBITMAP QPixmap::toWinHBITMAP(HBitmapFormat format) const
{
+ if (isNull())
+ return 0;
+
HBITMAP bitmap = 0;
if (data->classId() == QPixmapData::RasterClass) {
QRasterPixmapData* d = static_cast<QRasterPixmapData*>(data.data());
diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp
index ea9eff9..c735031 100644
--- a/src/gui/image/qpixmap_x11.cpp
+++ b/src/gui/image/qpixmap_x11.cpp
@@ -1916,8 +1916,8 @@ QPixmap QX11PixmapData::transformed(const QTransform &transform,
free(dptr);
return bm;
} else { // color pixmap
- QPixmap pm;
- QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(pm.data.data());
+ QX11PixmapData *x11Data = new QX11PixmapData(QPixmapData::PixmapType);
+ QPixmap pm(x11Data);
x11Data->flags &= ~QX11PixmapData::Uninitialized;
x11Data->xinfo = xinfo;
x11Data->d = d;
@@ -1976,6 +1976,9 @@ void QPixmap::x11SetScreen(int screen)
return;
}
+ if (isNull())
+ return;
+
if (data->classId() != QPixmapData::X11Class)
return;
@@ -2078,7 +2081,7 @@ bool QX11PixmapData::hasAlphaChannel() const
const QX11Info &QPixmap::x11Info() const
{
- if (data->classId() == QPixmapData::X11Class)
+ if (data && data->classId() == QPixmapData::X11Class)
return static_cast<QX11PixmapData*>(data.data())->xinfo;
else {
static QX11Info nullX11Info;
@@ -2135,7 +2138,7 @@ QPaintEngine* QX11PixmapData::paintEngine() const
Qt::HANDLE QPixmap::x11PictureHandle() const
{
#ifndef QT_NO_XRENDER
- if (data->classId() == QPixmapData::X11Class)
+ if (data && data->classId() == QPixmapData::X11Class)
return static_cast<const QX11PixmapData*>(data.data())->picture;
else
return 0;
diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp
index 1ad1f02..10194e4 100644
--- a/src/gui/image/qpixmapdata.cpp
+++ b/src/gui/image/qpixmapdata.cpp
@@ -51,6 +51,19 @@ QT_BEGIN_NAMESPACE
const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80 };
+QPixmapData *QPixmapData::create(int w, int h, PixelType type)
+{
+ QPixmapData *data;
+ QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
+ if (gs)
+ data = gs->createPixmapData(static_cast<QPixmapData::PixelType>(type));
+ else
+ data = QGraphicsSystem::createDefaultPixmapData(static_cast<QPixmapData::PixelType>(type));
+ data->resize(w, h);
+ return data;
+}
+
+
QPixmapData::QPixmapData(PixelType pixelType, int objectId)
: w(0),
h(0),
diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h
index 2f4f201..d1bb92a 100644
--- a/src/gui/image/qpixmapdata_p.h
+++ b/src/gui/image/qpixmapdata_p.h
@@ -122,6 +122,8 @@ public:
virtual void fromNativeType(void* pixmap, NativeType type);
#endif
+ static QPixmapData *create(int w, int h, PixelType type);
+
protected:
void setSerialNumber(int serNo);
int w;
@@ -131,12 +133,11 @@ protected:
private:
friend class QPixmap;
- friend class QGLContextPrivate;
friend class QX11PixmapData;
friend class QS60PixmapData;
+ friend class QImagePixmapCleanupHooks; // Needs to set is_cached
friend class QGLTextureCache; //Needs to check the reference count
friend class QExplicitlySharedDataPointer<QPixmapData>;
- friend bool qt_createEGLSurfaceForPixmap(QPixmapData*, bool); // Needs to set is_cached
QAtomicInt ref;
int detach_no;
diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp
index d0de03e..d83ef2c 100644
--- a/src/gui/image/qpixmapfilter.cpp
+++ b/src/gui/image/qpixmapfilter.cpp
@@ -53,6 +53,7 @@
#include "private/qpaintengineex_p.h"
#include "private/qpaintengine_raster_p.h"
+#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_NAMESPACE
class QPixmapFilterPrivate : public QObjectPrivate
@@ -504,10 +505,10 @@ void QPixmapConvolutionFilter::draw(QPainter *painter, const QPointF &p, const Q
class QPixmapBlurFilterPrivate : public QPixmapFilterPrivate
{
public:
- QPixmapBlurFilterPrivate() : radius(5), hint(Qt::PerformanceHint) {}
+ QPixmapBlurFilterPrivate() : radius(5), hint(QGraphicsBlurEffect::PerformanceHint) {}
qreal radius;
- Qt::RenderHint hint;
+ QGraphicsBlurEffect::BlurHint hint;
};
@@ -556,12 +557,18 @@ qreal QPixmapBlurFilter::radius() const
Setting the blur hint to PerformanceHint causes the implementation
to trade off visual quality to blur the image faster. Setting the
blur hint to QualityHint causes the implementation to improve
- visual quality at the expense of speed. The implementation is free
- to ignore this value if it only has a single blur algorithm.
+ visual quality at the expense of speed.
+
+ AnimationHint causes the implementation to optimize for animating
+ the blur radius, possibly by caching blurred versions of the source
+ pixmap.
+
+ The implementation is free to ignore this value if it only has a single
+ blur algorithm.
\internal
*/
-void QPixmapBlurFilter::setBlurHint(Qt::RenderHint hint)
+void QPixmapBlurFilter::setBlurHint(QGraphicsBlurEffect::BlurHint hint)
{
Q_D(QPixmapBlurFilter);
d->hint = hint;
@@ -572,7 +579,7 @@ void QPixmapBlurFilter::setBlurHint(Qt::RenderHint hint)
\internal
*/
-Qt::RenderHint QPixmapBlurFilter::blurHint() const
+QGraphicsBlurEffect::BlurHint QPixmapBlurFilter::blurHint() const
{
Q_D(const QPixmapBlurFilter);
return d->hint;
@@ -1101,3 +1108,5 @@ void QPixmapDropShadowFilter::draw(QPainter *p,
}
QT_END_NAMESPACE
+
+#endif //QT_NO_GRAPHICSEFFECT
diff --git a/src/gui/image/qpixmapfilter_p.h b/src/gui/image/qpixmapfilter_p.h
index fc70795..2573fc7 100644
--- a/src/gui/image/qpixmapfilter_p.h
+++ b/src/gui/image/qpixmapfilter_p.h
@@ -55,7 +55,9 @@
#include <QtCore/qnamespace.h>
#include <QtGui/qpixmap.h>
+#include <QtGui/qgraphicseffect.h>
+#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -130,10 +132,10 @@ public:
~QPixmapBlurFilter();
void setRadius(qreal radius);
- void setBlurHint(Qt::RenderHint hint);
+ void setBlurHint(QGraphicsBlurEffect::BlurHint hint);
qreal radius() const;
- Qt::RenderHint blurHint() const;
+ QGraphicsBlurEffect::BlurHint blurHint() const;
QRectF boundingRectFor(const QRectF &rect) const;
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
@@ -190,4 +192,5 @@ QT_END_NAMESPACE
QT_END_HEADER
+#endif //QT_NO_GRAPHICSEFFECT
#endif // QPIXMAPFILTER_H
diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
index 1531036..452aa75 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
@@ -65,10 +65,10 @@
QT_BEGIN_NAMESPACE
-class Q_GUI_EXPORT QCoeFepInputContext : public QInputContext,
- public MCoeFepAwareTextEditor,
- public MCoeFepAwareTextEditor_Extension1,
- public MObjectProvider
+class QCoeFepInputContext : public QInputContext,
+ public MCoeFepAwareTextEditor,
+ public MCoeFepAwareTextEditor_Extension1,
+ public MObjectProvider
{
Q_OBJECT
@@ -97,6 +97,7 @@ private:
void applyHints(Qt::InputMethodHints hints);
void applyFormat(QList<QInputMethodEvent::Attribute> *attributes);
void queueInputCapabilitiesChanged();
+ bool needsInputPanel();
private Q_SLOTS:
void ensureInputCapabilitiesChanged();
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index 3f21bc3..25b2313 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -47,6 +47,7 @@
#include <private/qcore_symbian_p.h>
#include <fepitfr.h>
+#include <hal.h>
#include <limits.h>
// You only find these enumerations on SDK 5 onwards, so we need to provide our own
@@ -153,6 +154,44 @@ QString QCoeFepInputContext::language()
}
}
+bool QCoeFepInputContext::needsInputPanel()
+{
+ switch (QSysInfo::s60Version()) {
+ case QSysInfo::SV_S60_3_1:
+ case QSysInfo::SV_S60_3_2:
+ // There are no touch phones for pre-5.0 SDKs.
+ return false;
+#ifdef Q_CC_NOKIAX86
+ default:
+ // For emulator we assume that we need an input panel, since we can't
+ // separate between phone types.
+ return true;
+#else
+ case QSysInfo::SV_S60_5_0: {
+ // For SDK == 5.0, we need phone specific detection, since the HAL API
+ // is no good on most phones. However, all phones at the time of writing use the
+ // input panel, except N97 in landscape mode, but in this mode it refuses to bring
+ // up the panel anyway, so we don't have to care.
+ return true;
+ }
+ default:
+ // For unknown/newer types, we try to use the HAL API.
+ int keyboardEnabled;
+ int keyboardType;
+ int err[2];
+ err[0] = HAL::Get(HAL::EKeyboard, keyboardType);
+ err[1] = HAL::Get(HAL::EKeyboardState, keyboardEnabled);
+ if (err[0] == KErrNone && err[1] == KErrNone
+ && keyboardType != 0 && keyboardEnabled)
+ // Means that we have some sort of keyboard.
+ return false;
+
+ // Fall back to using the input panel.
+ return true;
+#endif // !Q_CC_NOKIAX86
+ }
+}
+
bool QCoeFepInputContext::filterEvent(const QEvent *event)
{
// The CloseSoftwareInputPanel event is not handled here, because the VK will automatically
@@ -174,10 +213,8 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
}
}
- // For pre-5.0 SDKs, we don't launch the keyboard.
- if (QSysInfo::s60Version() != QSysInfo::SV_S60_5_0) {
+ if (!needsInputPanel())
return false;
- }
if (event->type() == QEvent::RequestSoftwareInputPanel) {
// Notify S60 that we want the virtual keyboard to show up.
diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h
index 7a0509b..ea5d259 100644
--- a/src/gui/itemviews/qabstractitemview.h
+++ b/src/gui/itemviews/qabstractitemview.h
@@ -363,6 +363,7 @@ private:
friend class QTreeViewPrivate; // needed to compile with MSVC
friend class QAccessibleItemRow;
friend class QListModeViewBase;
+ friend class QListViewPrivate; // needed to compile for Symbian emulator
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractItemView::EditTriggers)
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
index d680af8..15db9a6 100644
--- a/src/gui/itemviews/qlistview.cpp
+++ b/src/gui/itemviews/qlistview.cpp
@@ -357,7 +357,7 @@ QListView::LayoutMode QListView::layoutMode() const
/*!
\property QListView::spacing
- \brief the space between items in the layout
+ \brief the space around the items in the layout
This property is the size of the empty space that is padded around
an item in the layout.
@@ -972,9 +972,9 @@ void QListView::paintEvent(QPaintEvent *e)
option.rect = visualRect(*it);
if (flow() == TopToBottom)
- option.rect.setWidth(qMin(viewport()->size().width(), option.rect.width()));
+ option.rect.setWidth(qMin(viewport()->size().width() - 2 * d->spacing(), option.rect.width()));
else
- option.rect.setHeight(qMin(viewport()->size().height(), option.rect.height()));
+ option.rect.setHeight(qMin(viewport()->size().height() - 2 * d->spacing(), option.rect.height()));
option.state = state;
if (selections && selections->isSelected(*it))
@@ -1837,14 +1837,14 @@ void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
{
horizontalScrollBar()->setSingleStep(step.width() + spacing());
horizontalScrollBar()->setPageStep(viewport()->width());
- horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width());
+ horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width() - 2 * spacing());
}
void QCommonListViewBase::updateVerticalScrollBar(const QSize &step)
{
verticalScrollBar()->setSingleStep(step.height() + spacing());
verticalScrollBar()->setPageStep(viewport()->height());
- verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height());
+ verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height() - 2 * spacing());
}
void QCommonListViewBase::scrollContentsBy(int dx, int dy, bool /*scrollElasticBand*/)
diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp
index 3856293..a3cbc0d 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/gui/itemviews/qtreeview.cpp
@@ -2113,6 +2113,12 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
if (vi < 0)
vi = qMax(0, d->viewIndex(current));
+ if (isRightToLeft()) {
+ if (cursorAction == MoveRight)
+ cursorAction = MoveLeft;
+ else if (cursorAction == MoveLeft)
+ cursorAction = MoveRight;
+ }
switch (cursorAction) {
case MoveNext:
case MoveDown:
diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h
index aad5837..d58dea3 100644
--- a/src/gui/itemviews/qtreeview_p.h
+++ b/src/gui/itemviews/qtreeview_p.h
@@ -105,7 +105,7 @@ public:
int top() const { return startValue().toInt(); }
QRect rect() const { QRect rect = viewport->rect(); rect.moveTop(top()); return rect; }
void updateCurrentValue(const QVariant &) { viewport->update(rect()); }
- void updateState(State, State state) { if (state == Stopped) before = after = QPixmap(); }
+ void updateState(State state, State) { if (state == Stopped) before = after = QPixmap(); }
} animatedOperation;
void prepareAnimatedOperation(int item, QVariantAnimation::Direction d);
void beginAnimatedOperation();
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 1694434..987aa26 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -154,14 +154,6 @@ bool QApplicationPrivate::autoSipEnabled = false;
bool QApplicationPrivate::autoSipEnabled = true;
#endif
-QGestureManager* QGestureManager::instance()
-{
- QApplicationPrivate *d = qApp->d_func();
- if (!d->gestureManager)
- d->gestureManager = new QGestureManager(qApp);
- return d->gestureManager;
-}
-
QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type)
: QCoreApplicationPrivate(argc, argv)
{
@@ -185,7 +177,7 @@ QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::T
directPainters = 0;
#endif
- gestureManager = 0;
+ gestureWidget = 0;
if (!self)
self = this;
@@ -3634,12 +3626,12 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
}
// walk through parents and check for gestures
- if (d->gestureManager) {
+ if (qt_gestureManager) {
if (receiver->isWidgetType()) {
- if (d->gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
+ if (qt_gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
return true;
} else if (QGesture *gesture = qobject_cast<QGesture *>(receiver)) {
- if (d->gestureManager->filterEvent(gesture, e))
+ if (qt_gestureManager->filterEvent(gesture, e))
return true;
}
}
@@ -4152,7 +4144,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
if (receiver->isWidgetType()) {
QWidget *w = static_cast<QWidget *>(receiver);
QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(e);
- QList<QGesture *> allGestures = gestureEvent->allGestures();
+ QList<QGesture *> allGestures = gestureEvent->gestures();
bool eventAccepted = gestureEvent->isAccepted();
bool wasAccepted = eventAccepted;
@@ -4163,7 +4155,12 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
for (int i = 0; i < allGestures.size();) {
QGesture *g = allGestures.at(i);
Qt::GestureType type = g->gestureType();
- if (wd->gestureContext.contains(type)) {
+ QMap<Qt::GestureType, Qt::GestureFlags>::iterator contextit =
+ wd->gestureContext.find(type);
+ bool deliver = contextit != wd->gestureContext.end() &&
+ (g->state() == Qt::GestureStarted || w == receiver ||
+ (contextit.value() & Qt::ReceivePartialGestures));
+ if (deliver) {
allGestures.removeAt(i);
gestures.append(g);
} else {
@@ -5613,39 +5610,6 @@ Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window,
QApplicationPrivate::translateRawTouchEvent(window, deviceType, touchPoints);
}
-/*!
- \since 4.6
-
- Registers the given \a recognizer in the gesture framework and returns a gesture ID
- for it.
-
- The application takes ownership of the \a recognizer and returns the gesture type
- ID associated with it. For gesture recognizers which handle custom QGesture
- objects (i.e., those which return Qt::CustomGesture in a QGesture::gestureType()
- function) the return value is a gesture ID between Qt::CustomGesture and
- Qt::LastGestureType, inclusive.
-
- \sa unregisterGestureRecognizer(), QGestureRecognizer::createGesture(), QGesture
-*/
-Qt::GestureType QApplication::registerGestureRecognizer(QGestureRecognizer *recognizer)
-{
- return QGestureManager::instance()->registerGestureRecognizer(recognizer);
-}
-
-/*!
- \since 4.6
-
- Unregisters all gesture recognizers of the specified \a type.
-
- \sa registerGestureRecognizer()
-*/
-void QApplication::unregisterGestureRecognizer(Qt::GestureType type)
-{
- QApplicationPrivate *d = qApp->d_func();
- if (d->gestureManager)
- d->gestureManager->unregisterGestureRecognizer(type);
-}
-
QT_END_NAMESPACE
#include "moc_qapplication.cpp"
diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h
index 5877ba4..e8c1281 100644
--- a/src/gui/kernel/qapplication.h
+++ b/src/gui/kernel/qapplication.h
@@ -86,7 +86,6 @@ class QSymbianEvent;
class QApplication;
class QApplicationPrivate;
-class QGestureRecognizer;
#if defined(qApp)
#undef qApp
#endif
@@ -288,9 +287,6 @@ public:
static Qt::NavigationMode navigationMode();
#endif
- static Qt::GestureType registerGestureRecognizer(QGestureRecognizer *recognizer);
- static void unregisterGestureRecognizer(Qt::GestureType type);
-
Q_SIGNALS:
void lastWindowClosed();
void focusChanged(QWidget *old, QWidget *now);
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index 84e0d50..84da56e 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -104,6 +104,7 @@
#include "qdir.h"
#include "qdebug.h"
#include "qtimer.h"
+#include "qurl.h"
#include "private/qmacinputcontext_p.h"
#include "private/qpaintengine_mac_p.h"
#include "private/qcursor_p.h"
@@ -966,7 +967,8 @@ struct QMacAppleEventTypeSpec {
AEEventID mac_id;
} app_apple_events[] = {
{ kCoreEventClass, kAEQuitApplication },
- { kCoreEventClass, kAEOpenDocuments }
+ { kCoreEventClass, kAEOpenDocuments },
+ { kInternetEventClass, kAEGetURL },
};
#ifndef QT_MAC_USE_COCOA
@@ -1201,7 +1203,7 @@ void qt_init(QApplicationPrivate *priv, int)
app_proc_ae_handlerUPP = AEEventHandlerUPP(QApplicationPrivate::globalAppleEventProcessor);
for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i)
AEInstallEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
- app_proc_ae_handlerUPP, SRefCon(qApp), true);
+ app_proc_ae_handlerUPP, SRefCon(qApp), false);
}
if (QApplicationPrivate::app_style) {
@@ -1237,6 +1239,10 @@ void qt_init(QApplicationPrivate *priv, int)
[cocoaApp setMenu:[qtMenuLoader menu]];
[newDelegate setMenuLoader:qtMenuLoader];
[qtMenuLoader release];
+
+ NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
+ [eventManager setEventHandler:newDelegate andSelector:@selector(getUrl:withReplyEvent:)
+ forEventClass:kInternetEventClass andEventID:kAEGetURL];
}
#endif
// Register for Carbon tablet proximity events on the event monitor target.
@@ -2477,6 +2483,22 @@ OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, Ap
default:
break;
}
+ } else if (aeClass == kInternetEventClass) {
+ switch (aeID) {
+ case kAEGetURL: {
+ char urlData[1024];
+ Size actualSize;
+ if (AEGetParamPtr(ae, keyDirectObject, typeChar, 0, urlData,
+ sizeof(urlData) - 1, &actualSize) == noErr) {
+ urlData[actualSize] = 0;
+ QFileOpenEvent ev(QUrl(QString::fromUtf8(urlData)));
+ QApplication::sendSpontaneousEvent(app, &ev);
+ }
+ break;
+ }
+ default:
+ break;
+ }
}
#ifdef DEBUG_EVENTS
qDebug("Qt: internal: %shandled Apple event! %c%c%c%c %c%c%c%c", handled_event ? "(*)" : "",
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index 0fa7269..992e4be 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -72,7 +72,7 @@
#include <private/qgraphicssystem_qws_p.h>
#endif
#ifdef Q_OS_SYMBIAN
-#include <w32std.h>
+#include <w32std.h>
#endif
QT_BEGIN_NAMESPACE
@@ -84,7 +84,6 @@ class QInputContext;
class QObject;
class QWidget;
class QSocketNotifier;
-class QGestureManager;
extern bool qt_is_gui_used;
#ifndef QT_NO_CLIPBOARD
@@ -510,7 +509,7 @@ public:
void sendSyntheticEnterLeave(QWidget *widget);
#endif
- QGestureManager *gestureManager;
+ QWidget *gestureWidget;
QMap<int, QWidget *> widgetForTouchPointId;
QMap<int, QTouchEvent::TouchPoint> appCurrentTouchPoints;
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 30bf99a..5578a72 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -357,6 +357,9 @@ QSymbianControl::~QSymbianControl()
setFocusSafely(false);
S60->appUi()->RemoveFromStack(this);
delete m_longTapDetector;
+
+ if(m_previousEventLongTap)
+ QApplicationPrivate::mouse_buttons = QApplicationPrivate::mouse_buttons & ~Qt::RightButton;
}
void QSymbianControl::setWidget(QWidget *w)
@@ -836,7 +839,7 @@ void QSymbianControl::Draw(const TRect& controlRect) const
if (qwidget->d_func()->isOpaque)
gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect);
- }
+ }
} else {
surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint());
}
@@ -866,6 +869,11 @@ void QSymbianControl::SizeChanged()
tlwExtra->inTopLevelResize = false;
}
}
+
+ // CCoeControl::SetExtent calls SizeChanged, but does not call
+ // PositionChanged, so we call it here to ensure that the widget's
+ // position is updated.
+ PositionChanged();
}
void QSymbianControl::PositionChanged()
@@ -910,9 +918,9 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
CEikStatusPane* statusPane = S60->statusPane();
CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
- if (statusPane && (statusPane->IsVisible() == isFullscreen))
+ if (statusPane && (bool)statusPane->IsVisible() == isFullscreen)
statusPane->MakeVisible(!isFullscreen);
- if (buttonGroup && (buttonGroup->IsVisible() == isFullscreen))
+ if (buttonGroup && (bool)buttonGroup->IsVisible() == isFullscreen)
buttonGroup->MakeVisible(!isFullscreen);
#endif
} else if (QApplication::activeWindow() == qwidget->window()) {
@@ -925,6 +933,12 @@ void QSymbianControl::HandleResourceChange(int resourceType)
{
switch (resourceType) {
case KInternalStatusPaneChange:
+ if (qwidget->isFullScreen()) {
+ SetExtentToWholeScreen();
+ } else if (qwidget->isMaximized()) {
+ TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
+ SetExtent(r.iTl, r.Size());
+ }
qwidget->d_func()->setWindowIcon_sys(true);
break;
case KUidValueCoeFontChangeEvent:
@@ -1046,8 +1060,17 @@ void qt_init(QApplicationPrivate * /* priv */, int)
// After this construction, CEikonEnv will be available from CEikonEnv::Static().
// (much like our qApp).
CEikonEnv* coe = new CEikonEnv;
- QT_TRAP_THROWING(coe->ConstructAppFromCommandLineL(factory,*commandLine));
+ //not using QT_TRAP_THROWING, because coe owns the cleanupstack so it can't be pushed there.
+ if(err == KErrNone)
+ TRAP(err, coe->ConstructAppFromCommandLineL(factory,*commandLine));
delete commandLine;
+ if(err != KErrNone) {
+ qWarning() << "qt_init: Eikon application construct failed ("
+ << err
+ << "), maybe missing resource file on S60 3.1?";
+ delete coe;
+ qt_symbian_throwIfError(err);
+ }
S60->s60InstalledTrapHandler = User::SetTrapHandler(origTrapHandler);
@@ -1080,9 +1103,9 @@ void qt_init(QApplicationPrivate * /* priv */, int)
// enable focus events - used to re-enable mouse after focus changed between mouse and non mouse app,
// and for dimming behind modal windows
- S60->windowGroup().EnableFocusChangeEvents();
+ S60->windowGroup().EnableFocusChangeEvents();
- //Check if mouse interaction is supported (either EMouse=1 in the HAL, or EMachineUID is one of the phones known to support this)
+ //Check if mouse interaction is supported (either EMouse=1 in the HAL, or EMachineUID is one of the phones known to support this)
const TInt KMachineUidSamsungI8510 = 0x2000C51E;
// HAL::Get(HALData::EPen, TInt& result) may set 'result' to 1 on some 3.1 systems (e.g. N95).
// But we know that S60 systems below 5.0 did not support touch.
@@ -1240,7 +1263,7 @@ bool QApplicationPrivate::modalState()
void QApplicationPrivate::enterModal_sys(QWidget *widget)
{
if (widget) {
- widget->effectiveWinId()->DrawableWindow()->FadeBehind(ETrue);
+ static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(ETrue);
// Modal partial screen dialogs (like queries) capture pointer events.
// ### FixMe: Add specialized behaviour for fullscreen modal dialogs
widget->effectiveWinId()->SetGloballyCapturing(ETrue);
@@ -1255,7 +1278,7 @@ void QApplicationPrivate::enterModal_sys(QWidget *widget)
void QApplicationPrivate::leaveModal_sys(QWidget *widget)
{
if (widget) {
- widget->effectiveWinId()->DrawableWindow()->FadeBehind(EFalse);
+ static_cast<QSymbianControl *>(widget->effectiveWinId())->FadeBehindPopup(EFalse);
// ### FixMe: Add specialized behaviour for fullscreen modal dialogs
widget->effectiveWinId()->SetGloballyCapturing(EFalse);
widget->effectiveWinId()->SetPointerCapture(EFalse);
@@ -1560,7 +1583,7 @@ int QApplicationPrivate::symbianProcessWsEvent(const TWsEvent *event)
}
#endif
break;
- default:
+ default:
break;
}
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index d98ecbb..387c29b 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -2499,24 +2499,24 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
if (qAppPriv->GetGestureInfo)
bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi);
if (bResult) {
-// if (gi.dwID == GID_BEGIN) {
-// // find the alien widget for the gesture position.
-// // This might not be accurate as the position is the center
-// // point of two fingers for multi-finger gestures.
-// QPoint pt(gi.ptsLocation.x, gi.ptsLocation.y);
-// QWidget *w = widget->childAt(widget->mapFromGlobal(pt));
-// qAppPriv->gestureWidget = w ? w : widget;
-// }
-// if (qAppPriv->gestureWidget)
-// static_cast<QETWidget*>(qAppPriv->gestureWidget)->translateGestureEvent(msg, gi);
-// if (qAppPriv->CloseGestureInfoHandle)
-// qAppPriv->CloseGestureInfoHandle((HANDLE)msg.lParam);
-// if (gi.dwID == GID_END)
-// qAppPriv->gestureWidget = 0;
-// } else {
-// DWORD dwErr = GetLastError();
-// if (dwErr > 0)
-// qWarning() << "translateGestureEvent: error = " << dwErr;
+ if (gi.dwID == GID_BEGIN) {
+ // find the alien widget for the gesture position.
+ // This might not be accurate as the position is the center
+ // point of two fingers for multi-finger gestures.
+ QPoint pt(gi.ptsLocation.x, gi.ptsLocation.y);
+ QWidget *w = widget->childAt(widget->mapFromGlobal(pt));
+ qAppPriv->gestureWidget = w ? w : widget;
+ }
+ if (qAppPriv->gestureWidget)
+ static_cast<QETWidget*>(qAppPriv->gestureWidget)->translateGestureEvent(msg, gi);
+ if (qAppPriv->CloseGestureInfoHandle)
+ qAppPriv->CloseGestureInfoHandle((HANDLE)msg.lParam);
+ if (gi.dwID == GID_END)
+ qAppPriv->gestureWidget = 0;
+ } else {
+ DWORD dwErr = GetLastError();
+ if (dwErr > 0)
+ qWarning() << "translateGestureEvent: error = " << dwErr;
}
result = true;
break;
diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
index d103cbd..37dcc67 100644
--- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
+++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
@@ -83,6 +83,7 @@
#include <private/qt_cocoa_helpers_mac_p.h>
#include <private/qdesktopwidget_mac_p.h>
#include <qevent.h>
+#include <qurl.h>
#include <qapplication.h>
QT_BEGIN_NAMESPACE
@@ -303,5 +304,15 @@ static void cleanupCocoaApplicationDelegate()
[self doesNotRecognizeSelector:invocationSelector];
}
+- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
+{
+ Q_UNUSED(replyEvent);
+
+ NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
+ QUrl url(qt_mac_NSStringToQString(urlString));
+ QFileOpenEvent qtEvent(url);
+ qt_sendSpontaneousEvent(qAppInstance(), &qtEvent);
+}
+
@end
#endif
diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h b/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h
index 80df645..a137744 100644
--- a/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h
+++ b/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h
@@ -123,5 +123,6 @@ QT_FORWARD_DECLARE_CLASS(QApplicationPrivate);
- (void)setMenuLoader:(QT_MANGLE_NAMESPACE(QCocoaMenuLoader)*)menuLoader;
- (QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *)menuLoader;
- (void)setReflectionDelegate:(NSObject <NSApplicationDelegate> *)oldDelegate;
+- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
@end
#endif
diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm
index 95c89e5..9fb674e 100644
--- a/src/gui/kernel/qcocoawindowdelegate_mac.mm
+++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm
@@ -307,6 +307,18 @@ static void cleanupCocoaWindowDelegate()
return m_windowHash->value(window);
}
+- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame
+{
+ Q_UNUSED(newFrame);
+ // saving the current window geometry before the window is maximized
+ QWidget *qwidget = m_windowHash->value(window);
+ if (qwidget->isWindow() && !(qwidget->windowState() & Qt::WindowMaximized)) {
+ QWidgetPrivate *widgetPrivate = qt_widget_private(qwidget);
+ widgetPrivate->topData()->normalGeometry = qwidget->geometry();
+ }
+ return YES;
+}
+
- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)defaultFrame
{
NSRect frameToReturn = defaultFrame;
@@ -346,5 +358,28 @@ static void cleanupCocoaWindowDelegate()
m_drawerHash->remove(drawer);
}
+- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu
+{
+ Q_UNUSED(menu);
+ QWidget *qwidget = m_windowHash->value(window);
+ if (qwidget && !qwidget->windowFilePath().isEmpty()) {
+ return YES;
+ }
+ return NO;
+}
+
+- (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event
+ from:(NSPoint)dragImageLocation
+ withPasteboard:(NSPasteboard *)pasteboard
+{
+ Q_UNUSED(event);
+ Q_UNUSED(dragImageLocation);
+ Q_UNUSED(pasteboard);
+ QWidget *qwidget = m_windowHash->value(window);
+ if (qwidget && !qwidget->windowFilePath().isEmpty()) {
+ return YES;
+ }
+ return NO;
+}
@end
#endif// QT_MAC_USE_COCOA
diff --git a/src/gui/kernel/qcocoawindowdelegate_mac_p.h b/src/gui/kernel/qcocoawindowdelegate_mac_p.h
index a06c516..243ba03 100644
--- a/src/gui/kernel/qcocoawindowdelegate_mac_p.h
+++ b/src/gui/kernel/qcocoawindowdelegate_mac_p.h
@@ -76,6 +76,9 @@ QT_FORWARD_DECLARE_CLASS(QWidgetData)
- (void)windowDidResignMain:(NSNotification*)notification;
- (void)windowDidBecomeKey:(NSNotification*)notification;
- (void)windowDidResignKey:(NSNotification*)notification;
+- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu;
+- (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard;
+- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame;
@end
@protocol NSDrawerDelegate <NSObject>
diff --git a/src/gui/kernel/qdesktopwidget_mac.mm b/src/gui/kernel/qdesktopwidget_mac.mm
index 88dc173..c2d05d7 100644
--- a/src/gui/kernel/qdesktopwidget_mac.mm
+++ b/src/gui/kernel/qdesktopwidget_mac.mm
@@ -136,16 +136,19 @@ void QDesktopWidgetImplementation::onResize()
screenRects.clear();
availableRects.clear();
NSRect primaryRect = [[displays objectAtIndex:0] frame];
- for (int i = 0; i<screenCount; i++) {
- NSRect r = [[displays objectAtIndex:i] frame];
- const int flippedY = - r.origin.y + // account for position offset and
+ for (int i = 0; i<screenCount; i++) {
+ NSRect r = [[displays objectAtIndex:i] frame];
+ int flippedY = - r.origin.y + // account for position offset and
primaryRect.size.height - r.size.height; // height difference.
screenRects.append(QRectF(r.origin.x, flippedY,
r.size.width, r.size.height));
- r = [[displays objectAtIndex:i] visibleFrame];
+
+ r = [[displays objectAtIndex:i] visibleFrame];
+ flippedY = - r.origin.y + // account for position offset and
+ primaryRect.size.height - r.size.height; // height difference.
availableRects.append(QRectF(r.origin.x, flippedY,
r.size.width, r.size.height));
- }
+ }
}
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 55a329c..ff97405 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -2976,13 +2976,13 @@ QShowEvent::~QShowEvent()
/*!
\class QFileOpenEvent
\brief The QFileOpenEvent class provides an event that will be
- sent when there is a request to open a file.
+ sent when there is a request to open a file or a URL.
\ingroup events
File open events will be sent to the QApplication::instance()
- when the operating system requests that a file be opened. This is
- a high-level event that can be caused by different user actions
+ when the operating system requests that a file or URL should be opened.
+ This is a high-level event that can be caused by different user actions
depending on the user's desktop environment; for example, double
clicking on an file icon in the Finder on Mac OS X.
@@ -2999,12 +2999,27 @@ QShowEvent::~QShowEvent()
*/
QFileOpenEvent::QFileOpenEvent(const QString &file)
: QEvent(FileOpen), f(file)
-{}
+{
+ d = reinterpret_cast<QEventPrivate *>(new QFileOpenEventPrivate(QUrl::fromLocalFile(file)));
+}
+
+/*!
+ \internal
+
+ Constructs a file open event for the given \a url.
+*/
+QFileOpenEvent::QFileOpenEvent(const QUrl &url)
+ : QEvent(FileOpen)
+{
+ d = reinterpret_cast<QEventPrivate *>(new QFileOpenEventPrivate(url));
+ f = url.toLocalFile();
+}
/*! \internal
*/
QFileOpenEvent::~QFileOpenEvent()
{
+ delete reinterpret_cast<QFileOpenEventPrivate *>(d);
}
/*!
@@ -3013,6 +3028,16 @@ QFileOpenEvent::~QFileOpenEvent()
Returns the file that is being opened.
*/
+/*!
+ \fn QUrl QFileOpenEvent::url() const
+
+ Returns the url that is being opened.
+*/
+QUrl QFileOpenEvent::url() const
+{
+ return reinterpret_cast<const QFileOpenEventPrivate *>(d)->url;
+}
+
#ifndef QT_NO_TOOLBAR
/*!
\internal
@@ -4202,7 +4227,7 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T
\brief The QGestureEvent class provides the description of triggered gestures.
The QGestureEvent class contains a list of gestures, which can be obtained using the
- allGestures() function.
+ gestures() function.
The gestures are either active or canceled. A list of those that are currently being
executed can be obtained using the activeGestures() function. A list of those which
@@ -4211,10 +4236,11 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T
focus, for example, or because of a timeout, or for other reasons.
If the event handler does not accept the event by calling the generic
- QEvent::accept() function, all individual QGesture object that were not accepted
- will be propagated up the parent widget chain until a widget accepts them
- individually, by calling QGestureEvent::accept() for each of them, or an event
- filter consumes the event.
+ QEvent::accept() function, all individual QGesture object that were not
+ accepted and in the Qt::GestureStarted state will be propagated up the
+ parent widget chain until a widget accepts them individually, by calling
+ QGestureEvent::accept() for each of them, or an event filter consumes the
+ event.
\sa QGesture, QGestureRecognizer,
QWidget::grabGesture(), QGraphicsObject::grabGesture()
@@ -4240,7 +4266,7 @@ QGestureEvent::~QGestureEvent()
/*!
Returns all gestures that are delivered in the event.
*/
-QList<QGesture *> QGestureEvent::allGestures() const
+QList<QGesture *> QGestureEvent::gestures() const
{
return d_func()->gestures;
}
@@ -4344,8 +4370,9 @@ bool QGestureEvent::isAccepted(QGesture *gesture) const
Sets the accept flag of the given \a gestureType object to the specified
\a value.
- Setting the accept flag indicates that the event receiver wants the \a gesture.
- Unwanted gestures may be propagated to the parent widget.
+ Setting the accept flag indicates that the event receiver wants to receive
+ gestures of the specified type, \a gestureType. Unwanted gestures may be
+ propagated to the parent widget.
By default, gestures in events of type QEvent::Gesture are accepted, and
gestures in QEvent::GestureOverride events are ignored.
@@ -4417,11 +4444,16 @@ QWidget *QGestureEvent::widget() const
#ifndef QT_NO_GRAPHICSVIEW
/*!
- Returns the scene-local coordinates if the \a gesturePoint is inside a graphics view.
+ Returns the scene-local coordinates if the \a gesturePoint is inside a
+ graphics view.
+
+ This functional might be useful when the gesture event is delivered to a
+ QGraphicsObject to translate a point in screen coordinates to scene-local
+ coordinates.
\sa QPointF::isNull().
*/
-QPointF QGestureEvent::mapToScene(const QPointF &gesturePoint) const
+QPointF QGestureEvent::mapToGraphicsScene(const QPointF &gesturePoint) const
{
QWidget *w = widget();
if (w) // we get the viewport as widget, not the graphics view
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 141ccad..9839269 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -638,9 +638,11 @@ class Q_GUI_EXPORT QFileOpenEvent : public QEvent
{
public:
QFileOpenEvent(const QString &file);
+ QFileOpenEvent(const QUrl &url);
~QFileOpenEvent();
inline QString file() const { return f; }
+ QUrl url() const;
private:
QString f;
};
@@ -827,7 +829,7 @@ public:
QGestureEvent(const QList<QGesture *> &gestures);
~QGestureEvent();
- QList<QGesture *> allGestures() const;
+ QList<QGesture *> gestures() const;
QGesture *gesture(Qt::GestureType type) const;
QList<QGesture *> activeGestures() const;
@@ -860,7 +862,7 @@ public:
QWidget *widget() const;
#ifndef QT_NO_GRAPHICSVIEW
- QPointF mapToScene(const QPointF &gesturePoint) const;
+ QPointF mapToGraphicsScene(const QPointF &gesturePoint) const;
#endif
private:
diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h
index 6e6ab01..4aaaa8b 100644
--- a/src/gui/kernel/qevent_p.h
+++ b/src/gui/kernel/qevent_p.h
@@ -43,6 +43,7 @@
#define QEVENT_P_H
#include <QtCore/qglobal.h>
+#include <QtCore/qurl.h>
#include <QtGui/qevent.h>
QT_BEGIN_NAMESPACE
@@ -164,6 +165,18 @@ public:
QMap<Qt::GestureType, QWidget *> targetWidgets;
};
+
+class QFileOpenEventPrivate
+{
+public:
+ inline QFileOpenEventPrivate(const QUrl &url)
+ : url(url)
+ {
+ }
+
+ QUrl url;
+};
+
QT_END_NAMESPACE
#endif // QEVENT_P_H
diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp
index 850f22c..e8c2f8a 100644
--- a/src/gui/kernel/qgesture.cpp
+++ b/src/gui/kernel/qgesture.cpp
@@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
Gesture objects are not constructed directly by developers. They are created by
the QGestureRecognizer object that is registered with the application; see
- QApplication::registerGestureRecognizer().
+ QGestureRecognizer::registerRecognizer().
\section1 Gesture Properties
@@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
destroy particular instances of them and create new ones to replace them.
The registered gesture recognizer monitors the input events for the target
- object via its \l{QGestureRecognizer::}{filterEvent()} function, updating the
+ object via its \l{QGestureRecognizer::}{recognize()} function, updating the
properties of the gesture object as required.
The gesture object may be delivered to the target object in a QGestureEvent if
@@ -90,7 +90,7 @@ QT_BEGIN_NAMESPACE
Constructs a new gesture object with the given \a parent.
QGesture objects are created by gesture recognizers in the
- QGestureRecognizer::createGesture() function.
+ QGestureRecognizer::create() function.
*/
QGesture::QGesture(QObject *parent)
: QObject(*new QGesturePrivate, parent)
@@ -129,7 +129,7 @@ QGesture::~QGesture()
\brief The point that is used to find the receiver for the gesture event.
The hot-spot is a point in the global coordinate system, use
- QWidget::mapFromGlobal() or QGestureEvent::mapToScene() to get a
+ QWidget::mapFromGlobal() or QGestureEvent::mapToGraphicsScene() to get a
local hot-spot.
The hot-spot should be set by the gesture recognizer to allow gesture event
@@ -174,14 +174,26 @@ void QGesture::unsetHotSpot()
}
/*!
+ \property QGesture::gestureCancelPolicy
+ \brief the policy for deciding what happens on accepting a gesture
+
+ On accepting one gesture Qt can automatically cancel other gestures
+ that belong to other targets. The policy is normally set to not cancel
+ any other gestures and can be set to cancel all active gestures in the
+ context. For example for all child widgets.
+*/
+
+/*!
\enum QGesture::GestureCancelPolicy
This enum describes how accepting a gesture can cancel other gestures
automatically.
\value CancelNone On accepting this gesture no other gestures will be affected.
- \value CancelAllInContext On accepting this gesture all gestures that are active
- in the context (Qt::GestureContext) will be cancelled.
+
+ \value CancelAllInContext On accepting this gesture all gestures that are
+ active in the context (respecting the Qt::GestureFlag that were specified
+ when subscribed to the gesture) will be cancelled.
*/
void QGesture::setGestureCancelPolicy(GestureCancelPolicy policy)
@@ -208,25 +220,6 @@ QGesture::GestureCancelPolicy QGesture::gestureCancelPolicy() const
*/
/*!
- \property QPanGesture::totalOffset
- \brief the total offset from the first input position to the current input
- position
-
- The total offset measures the total change in position of the user's input
- covered by the gesture on the input device.
-*/
-
-/*!
- \property QGesture::GestureCancelPolicy
- \brief the policy for deciding what happens on accepting a gesture
-
- On accepting one gesture Qt can automatically cancel other gestures
- that belong to other targets. The policy is normally set to not cancel
- any other gestures and can be set to cancel all active gestures in the
- context. For example for all child widgets.
-*/
-
-/*!
\property QPanGesture::lastOffset
\brief the last offset recorded for this gesture
@@ -241,11 +234,19 @@ QGesture::GestureCancelPolicy QGesture::gestureCancelPolicy() const
/*!
\property QPanGesture::offset
- \brief the offset from the previous input position to the current input
+ \brief the total offset from the first input position to the current input
position
- The offset measures the change in position of the user's input on the
- input device.
+ The offset measures the total change in position of the user's input
+ covered by the gesture on the input device.
+*/
+
+/*!
+ \property QPanGesture::delta
+ \brief the offset from the previous input position to the current input
+
+ This is essentially the same as the difference between offset() and
+ lastOffset().
*/
/*!
@@ -261,10 +262,6 @@ QPanGesture::QPanGesture(QObject *parent)
d_func()->gestureType = Qt::PanGesture;
}
-QPointF QPanGesture::totalOffset() const
-{
- return d_func()->totalOffset;
-}
QPointF QPanGesture::lastOffset() const
{
@@ -276,15 +273,15 @@ QPointF QPanGesture::offset() const
return d_func()->offset;
}
-qreal QPanGesture::acceleration() const
+QPointF QPanGesture::delta() const
{
- return d_func()->acceleration;
+ Q_D(const QPanGesture);
+ return d->offset - d->lastOffset;
}
-
-void QPanGesture::setTotalOffset(const QPointF &value)
+qreal QPanGesture::acceleration() const
{
- d_func()->totalOffset = value;
+ return d_func()->acceleration;
}
void QPanGesture::setLastOffset(const QPointF &value)
@@ -326,7 +323,7 @@ void QPanGesture::setAcceleration(qreal value)
*/
/*!
- \enum QPinchGesture::WhatChange
+ \enum QPinchGesture::ChangeFlag
This enum describes the changes that can occur to the properties of
the gesture object.
@@ -335,19 +332,30 @@ void QPanGesture::setAcceleration(qreal value)
\value RotationAngleChanged The rotation angle held by rotationAngle changed.
\value CenterPointChanged The center point held by centerPoint changed.
- \sa whatChanged
+ \sa changeFlags, totalChangeFlags
*/
/*!
- \property QPinchGesture::whatChanged
- \brief the property of the gesture that has changed
+ \property QPinchGesture::totalChangeFlags
+ \brief the property of the gesture that has change
+
+ This property indicates which of the other properties has changed since the
+ gesture has started. You can use this information to determine which aspect
+ of your user interface needs to be updated.
+
+ \sa changeFlags, scaleFactor, rotationAngle, centerPoint
+*/
+
+/*!
+ \property QPinchGesture::changeFlags
+ \brief the property of the gesture that has changed in the current step
This property indicates which of the other properties has changed since
the previous gesture event included information about this gesture. You
can use this information to determine which aspect of your user interface
needs to be updated.
- \sa scaleFactor, rotationAngle, centerPoint
+ \sa totalChangeFlags, scaleFactor, rotationAngle, centerPoint
*/
/*!
@@ -441,16 +449,25 @@ QPinchGesture::QPinchGesture(QObject *parent)
d_func()->gestureType = Qt::PinchGesture;
}
-QPinchGesture::WhatChanged QPinchGesture::whatChanged() const
+QPinchGesture::ChangeFlags QPinchGesture::totalChangeFlags() const
+{
+ return d_func()->totalChangeFlags;
+}
+
+void QPinchGesture::setTotalChangeFlags(QPinchGesture::ChangeFlags value)
{
- return d_func()->whatChanged;
+ d_func()->totalChangeFlags = value;
}
-void QPinchGesture::setWhatChanged(QPinchGesture::WhatChanged value)
+QPinchGesture::ChangeFlags QPinchGesture::changeFlags() const
{
- d_func()->whatChanged = value;
+ return d_func()->changeFlags;
}
+void QPinchGesture::setChangeFlags(QPinchGesture::ChangeFlags value)
+{
+ d_func()->changeFlags = value;
+}
QPointF QPinchGesture::startCenterPoint() const
{
@@ -641,4 +658,70 @@ void QSwipeGesture::setSwipeAngle(qreal value)
d_func()->swipeAngle = value;
}
+/*!
+ \class QTapGesture
+ \since 4.6
+ \brief The QTapGesture class describes a tap gesture made by the user.
+ \ingroup gestures
+
+ \sa {Gestures Programming}, QPanGesture, QPinchGesture
+*/
+
+/*!
+ \property QTapGesture::position
+ \brief the position of the tap
+*/
+
+/*!
+ \internal
+*/
+QTapGesture::QTapGesture(QObject *parent)
+ : QGesture(*new QTapGesturePrivate, parent)
+{
+ d_func()->gestureType = Qt::TapGesture;
+}
+
+QPointF QTapGesture::position() const
+{
+ return d_func()->position;
+}
+
+void QTapGesture::setPosition(const QPointF &value)
+{
+ d_func()->position = value;
+}
+/*!
+ \class QTapAndHoldGesture
+ \since 4.6
+ \brief The QTapAndHoldGesture class describes a tap-and-hold (aka LongTap)
+ gesture made by the user.
+ \ingroup gestures
+
+ \sa {Gestures Programming}, QPanGesture, QPinchGesture
+*/
+
+/*!
+ \property QTapAndHoldGesture::position
+ \brief the position of the tap
+*/
+
+/*!
+ \internal
+*/
+QTapAndHoldGesture::QTapAndHoldGesture(QObject *parent)
+ : QGesture(*new QTapAndHoldGesturePrivate, parent)
+{
+ d_func()->gestureType = Qt::TapAndHoldGesture;
+}
+
+QPointF QTapAndHoldGesture::position() const
+{
+ return d_func()->position;
+}
+
+void QTapAndHoldGesture::setPosition(const QPointF &value)
+{
+ d_func()->position = value;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h
index 524d26e..f995d7b 100644
--- a/src/gui/kernel/qgesture.h
+++ b/src/gui/kernel/qgesture.h
@@ -97,6 +97,7 @@ private:
friend class QGestureEvent;
friend class QGestureRecognizer;
friend class QGestureManager;
+ friend class QGraphicsScenePrivate;
};
class QPanGesturePrivate;
@@ -105,20 +106,19 @@ class Q_GUI_EXPORT QPanGesture : public QGesture
Q_OBJECT
Q_DECLARE_PRIVATE(QPanGesture)
- Q_PROPERTY(QPointF totalOffset READ totalOffset WRITE setTotalOffset)
Q_PROPERTY(QPointF lastOffset READ lastOffset WRITE setLastOffset)
Q_PROPERTY(QPointF offset READ offset WRITE setOffset)
+ Q_PROPERTY(QPointF delta READ delta STORED false)
Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration)
public:
QPanGesture(QObject *parent = 0);
- QPointF totalOffset() const;
QPointF lastOffset() const;
QPointF offset() const;
+ QPointF delta() const;
qreal acceleration() const;
- void setTotalOffset(const QPointF &value);
void setLastOffset(const QPointF &value);
void setOffset(const QPointF &value);
void setAcceleration(qreal value);
@@ -134,14 +134,15 @@ class Q_GUI_EXPORT QPinchGesture : public QGesture
Q_DECLARE_PRIVATE(QPinchGesture)
public:
- enum WhatChange {
+ enum ChangeFlag {
ScaleFactorChanged = 0x1,
RotationAngleChanged = 0x2,
CenterPointChanged = 0x4
};
- Q_DECLARE_FLAGS(WhatChanged, WhatChange)
+ Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)
- Q_PROPERTY(WhatChanged whatChanged READ whatChanged WRITE setWhatChanged)
+ Q_PROPERTY(ChangeFlags totalChangeFlags READ totalChangeFlags WRITE setTotalChangeFlags)
+ Q_PROPERTY(ChangeFlags changeFlags READ changeFlags WRITE setChangeFlags)
Q_PROPERTY(qreal totalScaleFactor READ totalScaleFactor WRITE setTotalScaleFactor)
Q_PROPERTY(qreal lastScaleFactor READ lastScaleFactor WRITE setLastScaleFactor)
@@ -158,8 +159,11 @@ public:
public:
QPinchGesture(QObject *parent = 0);
- WhatChanged whatChanged() const;
- void setWhatChanged(WhatChanged value);
+ ChangeFlags totalChangeFlags() const;
+ void setTotalChangeFlags(ChangeFlags value);
+
+ ChangeFlags changeFlags() const;
+ void setChangeFlags(ChangeFlags value);
QPointF startCenterPoint() const;
QPointF lastCenterPoint() const;
@@ -187,7 +191,7 @@ public:
QT_END_NAMESPACE
-Q_DECLARE_METATYPE(QPinchGesture::WhatChanged)
+Q_DECLARE_METATYPE(QPinchGesture::ChangeFlags)
QT_BEGIN_NAMESPACE
@@ -215,6 +219,40 @@ public:
friend class QSwipeGestureRecognizer;
};
+class QTapGesturePrivate;
+class Q_GUI_EXPORT QTapGesture : public QGesture
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QTapGesture)
+
+ Q_PROPERTY(QPointF position READ position WRITE setPosition)
+
+public:
+ QTapGesture(QObject *parent = 0);
+
+ QPointF position() const;
+ void setPosition(const QPointF &pos);
+
+ friend class QTapGestureRecognizer;
+};
+
+class QTapAndHoldGesturePrivate;
+class Q_GUI_EXPORT QTapAndHoldGesture : public QGesture
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QTapAndHoldGesture)
+
+ Q_PROPERTY(QPointF position READ position WRITE setPosition)
+
+public:
+ QTapAndHoldGesture(QObject *parent = 0);
+
+ QPointF position() const;
+ void setPosition(const QPointF &pos);
+
+ friend class QTapAndHoldGestureRecognizer;
+};
+
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QGesture::GestureCancelPolicy)
diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h
index 34fbb26..2537f47 100644
--- a/src/gui/kernel/qgesture_p.h
+++ b/src/gui/kernel/qgesture_p.h
@@ -90,10 +90,9 @@ public:
{
}
- QPointF totalOffset;
QPointF lastOffset;
QPointF offset;
- QPoint lastPosition;
+ QPoint startPosition;
qreal acceleration;
};
@@ -103,12 +102,15 @@ class QPinchGesturePrivate : public QGesturePrivate
public:
QPinchGesturePrivate()
- : whatChanged(0), totalScaleFactor(0), lastScaleFactor(0), scaleFactor(0),
- totalRotationAngle(0), lastRotationAngle(0), rotationAngle(0)
+ : totalChangeFlags(0), changeFlags(0),
+ totalScaleFactor(0), lastScaleFactor(0), scaleFactor(0),
+ totalRotationAngle(0), lastRotationAngle(0), rotationAngle(0),
+ isNewSequence(true)
{
}
- QPinchGesture::WhatChanged whatChanged;
+ QPinchGesture::ChangeFlags totalChangeFlags;
+ QPinchGesture::ChangeFlags changeFlags;
QPointF startCenterPoint;
QPointF lastCenterPoint;
@@ -121,6 +123,9 @@ public:
qreal totalRotationAngle;
qreal lastRotationAngle;
qreal rotationAngle;
+
+ bool isNewSequence;
+ QPointF startPosition[2];
};
class QSwipeGesturePrivate : public QGesturePrivate
@@ -131,13 +136,45 @@ public:
QSwipeGesturePrivate()
: horizontalDirection(QSwipeGesture::NoDirection),
verticalDirection(QSwipeGesture::NoDirection),
- swipeAngle(0)
+ swipeAngle(0),
+ started(false), speed(0)
{
}
QSwipeGesture::SwipeDirection horizontalDirection;
QSwipeGesture::SwipeDirection verticalDirection;
qreal swipeAngle;
+
+ QPoint lastPositions[3];
+ bool started;
+ qreal speed;
+ QTime time;
+};
+
+class QTapGesturePrivate : public QGesturePrivate
+{
+ Q_DECLARE_PUBLIC(QTapGesture)
+
+public:
+ QTapGesturePrivate()
+ {
+ }
+
+ QPointF position;
+};
+
+class QTapAndHoldGesturePrivate : public QGesturePrivate
+{
+ Q_DECLARE_PUBLIC(QTapAndHoldGesture)
+
+public:
+ QTapAndHoldGesturePrivate()
+ : timerId(0)
+ {
+ }
+
+ QPointF position;
+ int timerId;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index 0a88a24..abd2128 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -52,6 +52,9 @@
#ifdef Q_WS_MAC
#include "qmacgesturerecognizer_mac_p.h"
#endif
+#if defined(Q_OS_WIN)
+#include "qwinnativepangesturerecognizer_win_p.h"
+#endif
#include "qdebug.h"
@@ -64,6 +67,15 @@
QT_BEGIN_NAMESPACE
+QGestureManager *qt_gestureManager = 0;
+
+QGestureManager* QGestureManager::instance()
+{
+ if (!qt_gestureManager)
+ qt_gestureManager = new QGestureManager(qApp);
+ return qt_gestureManager;
+}
+
QGestureManager::QGestureManager(QObject *parent)
: QObject(parent), state(NotGesture), m_lastCustomGestureId(0)
{
@@ -77,6 +89,14 @@ QGestureManager::QGestureManager(QObject *parent)
#endif
#else
registerGestureRecognizer(new QPanGestureRecognizer);
+ registerGestureRecognizer(new QPinchGestureRecognizer);
+ registerGestureRecognizer(new QSwipeGestureRecognizer);
+ registerGestureRecognizer(new QTapGestureRecognizer);
+#endif
+#if defined(Q_OS_WIN)
+ registerGestureRecognizer(new QWinNativePanGestureRecognizer);
+#else
+ registerGestureRecognizer(new QTapAndHoldGestureRecognizer);
#endif
}
@@ -92,7 +112,7 @@ QGestureManager::~QGestureManager()
Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer)
{
- QGesture *dummy = recognizer->createGesture(0);
+ QGesture *dummy = recognizer->create(0);
if (!dummy) {
qWarning("QGestureManager::registerGestureRecognizer: "
"the recognizer fails to create a gesture object, skipping registration.");
@@ -159,8 +179,10 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni
return 0;
} else if (QGesture *g = qobject_cast<QGesture *>(object)) {
return g;
+#ifndef QT_NO_GRAPHICSVIEW
} else {
Q_ASSERT(qobject_cast<QGraphicsObject *>(object));
+#endif
}
QList<QGesture *> states =
@@ -172,7 +194,7 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni
}
Q_ASSERT(recognizer);
- QGesture *state = recognizer->createGesture(object);
+ QGesture *state = recognizer->create(object);
if (!state)
return 0;
state->setParent(this);
@@ -219,18 +241,19 @@ bool QGestureManager::filterEventThroughContexts(const QMultiHash<QObject *,
QGesture *state = getState(target, recognizer, gestureType);
if (!state)
continue;
- QGestureRecognizer::Result result = recognizer->filterEvent(state, target, event);
+ QGestureRecognizer::Result result = recognizer->recognize(state, target, event);
QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask;
- if (type == QGestureRecognizer::GestureTriggered) {
+ result &= QGestureRecognizer::ResultHint_Mask;
+ if (type == QGestureRecognizer::TriggerGesture) {
DEBUG() << "QGestureManager:Recognizer: gesture triggered: " << state;
triggeredGestures << state;
- } else if (type == QGestureRecognizer::GestureFinished) {
+ } else if (type == QGestureRecognizer::FinishGesture) {
DEBUG() << "QGestureManager:Recognizer: gesture finished: " << state;
finishedGestures << state;
- } else if (type == QGestureRecognizer::MaybeGesture) {
+ } else if (type == QGestureRecognizer::MayBeGesture) {
DEBUG() << "QGestureManager:Recognizer: maybe gesture: " << state;
newMaybeGestures << state;
- } else if (type == QGestureRecognizer::NotGesture) {
+ } else if (type == QGestureRecognizer::CancelGesture) {
DEBUG() << "QGestureManager:Recognizer: not gesture: " << state;
notGestures << state;
} else if (type == QGestureRecognizer::Ignore) {
@@ -346,12 +369,7 @@ bool QGestureManager::filterEventThroughContexts(const QMultiHash<QObject *,
QSet<QGesture *> endedGestures =
finishedGestures + canceledGestures + undeliveredGestures;
foreach (QGesture *gesture, endedGestures) {
- if (QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0)) {
- gesture->setGestureCancelPolicy(QGesture::CancelNone);
- recognizer->reset(gesture);
- } else {
- cleanupGesturesForRemovedRecognizer(gesture);
- }
+ recycle(gesture);
m_gestureTargets.remove(gesture);
}
return ret;
@@ -409,15 +427,8 @@ void QGestureManager::cancelGesturesForChildren(QGesture *original)
deliverEvents(gestures, &undeliveredGestures);
}
- for (iter = cancelledGestures.begin(); iter != cancelledGestures.end(); ++iter) {
- QGestureRecognizer *recognizer = m_gestureToRecognizer.value(*iter, 0);
- if (recognizer) {
- (*iter)->setGestureCancelPolicy(QGesture::CancelNone);
- recognizer->reset(*iter);
- } else {
- cleanupGesturesForRemovedRecognizer(*iter);
- }
- }
+ for (iter = cancelledGestures.begin(); iter != cancelledGestures.end(); ++iter)
+ recycle(*iter);
}
void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture)
@@ -439,7 +450,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
QSet<Qt::GestureType> types;
QMultiHash<QObject *, Qt::GestureType> contexts;
QWidget *w = receiver;
- typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
+ typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
if (!w->d_func()->gestureContext.isEmpty()) {
for(ContextIterator it = w->d_func()->gestureContext.begin(),
e = w->d_func()->gestureContext.end(); it != e; ++it) {
@@ -453,7 +464,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
{
for (ContextIterator it = w->d_func()->gestureContext.begin(),
e = w->d_func()->gestureContext.end(); it != e; ++it) {
- if (it.value() == Qt::WidgetWithChildrenGesture) {
+ if (!(it.value() & Qt::DontStartGestureOnChildren)) {
if (!types.contains(it.key())) {
types.insert(it.key());
contexts.insertMulti(w, it.key());
@@ -474,7 +485,7 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
QMultiHash<QObject *, Qt::GestureType> contexts;
QGraphicsObject *item = receiver;
if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
- typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
+ typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
types.insert(it.key());
@@ -485,10 +496,10 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
item = item->parentObject();
while (item)
{
- typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
+ typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
- if (it.value() == Qt::ItemWithChildrenGesture) {
+ if (!(it.value() & Qt::DontStartGestureOnChildren)) {
if (!types.contains(it.key())) {
types.insert(it.key());
contexts.insertMulti(item, it.key());
@@ -528,12 +539,12 @@ void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures,
foreach (QWidget *widget, gestures.keys()) {
QWidget *w = widget->parentWidget();
while (w) {
- QMap<Qt::GestureType, Qt::GestureContext>::const_iterator it
+ QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator it
= w->d_func()->gestureContext.find(type);
if (it != w->d_func()->gestureContext.end()) {
// i.e. 'w' listens to gesture 'type'
- Qt::GestureContext context = it.value();
- if (context == Qt::WidgetWithChildrenGesture && w != widget) {
+ Qt::GestureFlags flags = it.value();
+ if (!(it.value() & Qt::DontStartGestureOnChildren) && w != widget) {
// conflicting gesture!
(*conflicts)[widget].append(gestures[widget]);
break;
@@ -627,7 +638,7 @@ void QGestureManager::deliverEvents(const QSet<QGesture *> &gestures,
QApplication::sendEvent(receiver, &event);
bool eventAccepted = event.isAccepted();
- foreach(QGesture *gesture, event.allGestures()) {
+ foreach(QGesture *gesture, event.gestures()) {
if (eventAccepted || event.isAccepted(gesture)) {
QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
Q_ASSERT(w);
@@ -652,6 +663,16 @@ void QGestureManager::deliverEvents(const QSet<QGesture *> &gestures,
<< "gestures:" << it.value();
QGestureEvent event(it.value());
QApplication::sendEvent(it.key(), &event);
+ bool eventAccepted = event.isAccepted();
+ foreach (QGesture *gesture, event.gestures()) {
+ if (gesture->state() == Qt::GestureStarted &&
+ (eventAccepted || event.isAccepted(gesture))) {
+ QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
+ Q_ASSERT(w);
+ DEBUG() << "started gesture was delivered and accepted by" << w;
+ m_gestureTargets[gesture] = w;
+ }
+ }
}
}
}
@@ -669,19 +690,24 @@ void QGestureManager::timerEvent(QTimerEvent *event)
it = m_maybeGestures.erase(it);
DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:"
<< gesture;
- QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0);
- if (recognizer) {
- gesture->setGestureCancelPolicy(QGesture::CancelNone);
- recognizer->reset(gesture);
- } else {
- cleanupGesturesForRemovedRecognizer(gesture);
- }
+ recycle(gesture);
} else {
++it;
}
}
}
+void QGestureManager::recycle(QGesture *gesture)
+{
+ QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0);
+ if (recognizer) {
+ gesture->setGestureCancelPolicy(QGesture::CancelNone);
+ recognizer->reset(gesture);
+ } else {
+ cleanupGesturesForRemovedRecognizer(gesture);
+ }
+}
+
QT_END_NAMESPACE
#include "moc_qgesturemanager_p.cpp"
diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h
index 1e0734b..4efa10b 100644
--- a/src/gui/kernel/qgesturemanager_p.h
+++ b/src/gui/kernel/qgesturemanager_p.h
@@ -78,11 +78,12 @@ public:
bool filterEvent(QGraphicsObject *receiver, QEvent *event);
#endif //QT_NO_GRAPHICSVIEW
- // declared in qapplication.cpp
static QGestureManager* instance();
void cleanupCachedGestures(QObject *target, Qt::GestureType type);
+ void recycle(QGesture *gesture);
+
protected:
void timerEvent(QTimerEvent *event);
bool filterEventThroughContexts(const QMultiHash<QObject *, Qt::GestureType> &contexts,
@@ -141,6 +142,8 @@ private:
void cancelGesturesForChildren(QGesture *originatingGesture);
};
+extern QGestureManager *qt_gestureManager;
+
QT_END_NAMESPACE
#endif // QGESTUREMANAGER_P_H
diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp
index 2673be3..ed0bdcc 100644
--- a/src/gui/kernel/qgesturerecognizer.cpp
+++ b/src/gui/kernel/qgesturerecognizer.cpp
@@ -42,6 +42,7 @@
#include "qgesturerecognizer.h"
#include "private/qgesture_p.h"
+#include "private/qgesturemanager_p.h"
QT_BEGIN_NAMESPACE
@@ -65,12 +66,12 @@ QT_BEGIN_NAMESPACE
objects, and modifying the associated QGesture objects to include relevant information
about the user's input.
- Gestures are created when the framework calls createGesture() to handle user input
+ Gestures are created when the framework calls create() to handle user input
for a particular instance of a QWidget or QGraphicsObject subclass. A QGesture object
is created for each widget or item that is configured to use gestures.
Once a QGesture has been created for a target object, the gesture recognizer will
- receive events for it in its filterEvent() handler function.
+ receive events for it in its recognize() handler function.
When a gesture is canceled, the reset() function is called, giving the recognizer the
chance to update the appropriate properties in the corresponding QGesture object.
@@ -79,20 +80,22 @@ QT_BEGIN_NAMESPACE
To add support for new gestures, you need to derive from QGestureRecognizer to create
a custom recognizer class, construct an instance of this class, and register it with
- the application by calling QApplication::registerGestureRecognizer(). You can also
+ the application by calling QGestureRecognizer::registerRecognizer(). You can also
subclass QGesture to create a custom gesture class, or rely on dynamic properties
to express specific details of the gesture you want to handle.
- Your custom QGestureRecognizer subclass needs to reimplement the filterEvent() function
- to handle and filter the incoming input events for QWidget and QGraphicsObject subclasses.
- Although the logic for gesture recognition is implemented in this function, you can
- store persistent information about the state of the recognition process in the QGesture
- object supplied. The filterEvent() function must return a value of Qt::GestureState that
- indicates the state of recognition for a given gesture and target object. This determines
- whether or not a gesture event will be delivered to a target object.
+ Your custom QGestureRecognizer subclass needs to reimplement the recognize()
+ function to handle and filter the incoming input events for QWidget and
+ QGraphicsObject subclasses. Although the logic for gesture recognition is
+ implemented in this function, you can store persistent information about the
+ state of the recognition process in the QGesture object supplied. The
+ recognize() function must return a value of QGestureRecognizer::Result that
+ indicates the state of recognition for a given gesture and target object.
+ This determines whether or not a gesture event will be delivered to a target
+ object.
If you choose to represent a gesture by a custom QGesture subclass, you will need to
- reimplement the createGesture() function to construct instances of your gesture class.
+ reimplement the create() function to construct instances of your gesture class.
Similarly, you may need to reimplement the reset() function if your custom gesture
objects need to be specially handled when a gesture is canceled.
@@ -105,37 +108,37 @@ QT_BEGIN_NAMESPACE
This enum describes the result of the current event filtering step in
a gesture recognizer state machine.
- The result consists of a state value (one of Ignore, NotGesture,
- MaybeGesture, GestureTriggered, GestureFinished) and an optional hint
+ The result consists of a state value (one of Ignore, MayBeGesture,
+ TriggerGesture, FinishGesture, CancelGesture) and an optional hint
(ConsumeEventHint).
\value Ignore The event does not change the state of the recognizer.
- \value NotGesture The event made it clear that it is not a gesture. If the
- gesture recognizer was in GestureTriggered state before, then the gesture
- is canceled and the appropriate QGesture object will be delivered to the
- target as a part of a QGestureEvent.
-
- \value MaybeGesture The event changed the internal state of the recognizer,
+ \value MayBeGesture The event changed the internal state of the recognizer,
but it isn't clear yet if it is a gesture or not. The recognizer needs to
- filter more events to decide. Gesture recognizers in the MaybeGesture state
+ filter more events to decide. Gesture recognizers in the MayBeGesture state
may be reset automatically if they take too long to recognize gestures.
- \value GestureTriggered The gesture has been triggered and the appropriate
+ \value TriggerGesture The gesture has been triggered and the appropriate
QGesture object will be delivered to the target as a part of a
QGestureEvent.
- \value GestureFinished The gesture has been finished successfully and the
+ \value FinishGesture The gesture has been finished successfully and the
appropriate QGesture object will be delivered to the target as a part of a
QGestureEvent.
- \value ConsumeEventHint This hint specifies that the gesture framework should
- consume the filtered event and not deliver it to the receiver.
+ \value CancelGesture The event made it clear that it is not a gesture. If
+ the gesture recognizer was in GestureTriggered state before, then the
+ gesture is canceled and the appropriate QGesture object will be delivered
+ to the target as a part of a QGestureEvent.
+
+ \value ConsumeEventHint This hint specifies that the gesture framework
+ should consume the filtered event and not deliver it to the receiver.
\omitvalue ResultState_Mask
\omitvalue ResultHint_Mask
- \sa QGestureRecognizer::filterEvent()
+ \sa QGestureRecognizer::recognize()
*/
/*!
@@ -159,7 +162,7 @@ QGestureRecognizer::~QGestureRecognizer()
Reimplement this function to create a custom QGesture-derived gesture
object if necessary.
*/
-QGesture *QGestureRecognizer::createGesture(QObject *target)
+QGesture *QGestureRecognizer::create(QObject *target)
{
Q_UNUSED(target);
return new QGesture;
@@ -183,7 +186,7 @@ void QGestureRecognizer::reset(QGesture *gesture)
}
/*!
- \fn QGestureRecognizer::filterEvent(QGesture *gesture, QObject *watched, QEvent *event)
+ \fn QGestureRecognizer::recognize(QGesture *gesture, QObject *watched, QEvent *event)
Handles the given \a event for the \a watched object, updating the state of the \a gesture
object as required, and returns a suitable result for the current recognition step.
@@ -194,7 +197,34 @@ void QGestureRecognizer::reset(QGesture *gesture)
The result reflects how much of the gesture has been recognized. The state of the
\a gesture object is set depending on the result.
- \sa Qt::GestureState
+ \sa QGestureRecognizer::Result
+*/
+
+/*!
+ Registers the given \a recognizer in the gesture framework and returns a gesture ID
+ for it.
+
+ The application takes ownership of the \a recognizer and returns the gesture type
+ ID associated with it. For gesture recognizers which handle custom QGesture
+ objects (i.e., those which return Qt::CustomGesture in a QGesture::gestureType()
+ function) the return value is a generated gesture ID with the Qt::CustomGesture
+ flag set.
+
+ \sa unregisterRecognizer(), QGestureRecognizer::create(), QGesture
*/
+Qt::GestureType QGestureRecognizer::registerRecognizer(QGestureRecognizer *recognizer)
+{
+ return QGestureManager::instance()->registerGestureRecognizer(recognizer);
+}
+
+/*!
+ Unregisters all gesture recognizers of the specified \a type.
+
+ \sa registerRecognizer()
+*/
+void QGestureRecognizer::unregisterRecognizer(Qt::GestureType type)
+{
+ QGestureManager::instance()->unregisterGestureRecognizer(type);
+}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qgesturerecognizer.h b/src/gui/kernel/qgesturerecognizer.h
index a3c990d..4eebf7c 100644
--- a/src/gui/kernel/qgesturerecognizer.h
+++ b/src/gui/kernel/qgesturerecognizer.h
@@ -43,6 +43,7 @@
#define QGESTURERECOGNIZER_H
#include <QtCore/qglobal.h>
+#include <QtCore/qnamespace.h>
QT_BEGIN_HEADER
@@ -58,30 +59,34 @@ class Q_GUI_EXPORT QGestureRecognizer
public:
enum ResultFlag
{
- Ignore = 0x0001,
- NotGesture = 0x0002,
- MaybeGesture = 0x0004,
- GestureTriggered = 0x0008, // Gesture started or updated
- GestureFinished = 0x0010,
+ Ignore = 0x0001,
- ResultState_Mask = 0x00ff,
+ MayBeGesture = 0x0002,
+ TriggerGesture = 0x0004,
+ FinishGesture = 0x0008,
+ CancelGesture = 0x0010,
+
+ ResultState_Mask = 0x00ff,
ConsumeEventHint = 0x0100,
// StoreEventHint = 0x0200,
// ReplayStoredEventsHint = 0x0400,
// DiscardStoredEventsHint = 0x0800,
- ResultHint_Mask = 0xff00
+ ResultHint_Mask = 0xff00
};
Q_DECLARE_FLAGS(Result, ResultFlag)
QGestureRecognizer();
virtual ~QGestureRecognizer();
- virtual QGesture *createGesture(QObject *target);
- virtual QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event) = 0;
-
+ virtual QGesture *create(QObject *target);
+ virtual Result recognize(QGesture *state, QObject *watched,
+ QEvent *event) = 0;
virtual void reset(QGesture *state);
+
+ static Qt::GestureType registerRecognizer(QGestureRecognizer *recognizer);
+ static void unregisterRecognizer(Qt::GestureType type);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QGestureRecognizer::Result)
diff --git a/src/gui/kernel/qmacgesturerecognizer_mac.mm b/src/gui/kernel/qmacgesturerecognizer_mac.mm
index 7019580..f142d71 100644
--- a/src/gui/kernel/qmacgesturerecognizer_mac.mm
+++ b/src/gui/kernel/qmacgesturerecognizer_mac.mm
@@ -53,13 +53,13 @@ QMacSwipeGestureRecognizer::QMacSwipeGestureRecognizer()
{
}
-QGesture *QMacSwipeGestureRecognizer::createGesture(QObject * /*target*/)
+QGesture *QMacSwipeGestureRecognizer::create(QObject * /*target*/)
{
return new QSwipeGesture;
}
QGestureRecognizer::Result
-QMacSwipeGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent *event)
+QMacSwipeGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event)
{
if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
@@ -67,7 +67,7 @@ QMacSwipeGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent
case QNativeGestureEvent::Swipe: {
QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture);
g->setSwipeAngle(ev->angle);
- return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
break; }
default:
break;
@@ -90,13 +90,13 @@ QMacPinchGestureRecognizer::QMacPinchGestureRecognizer()
{
}
-QGesture *QMacPinchGestureRecognizer::createGesture(QObject * /*target*/)
+QGesture *QMacPinchGestureRecognizer::create(QObject * /*target*/)
{
return new QPinchGesture;
}
QGestureRecognizer::Result
-QMacPinchGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent *event)
+QMacPinchGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event)
{
if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
@@ -106,26 +106,26 @@ QMacPinchGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent
reset(gesture);
g->setStartCenterPoint(static_cast<QWidget*>(obj)->mapFromGlobal(ev->position));
g->setCenterPoint(g->startCenterPoint());
- g->setWhatChanged(QPinchGesture::CenterPointChanged);
- return QGestureRecognizer::MaybeGesture | QGestureRecognizer::ConsumeEventHint;
+ g->setChangeFlags(QPinchGesture::CenterPointChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ return QGestureRecognizer::MayBeGesture | QGestureRecognizer::ConsumeEventHint;
case QNativeGestureEvent::Rotate: {
g->setLastScaleFactor(g->scaleFactor());
g->setLastRotationAngle(g->rotationAngle());
g->setRotationAngle(g->rotationAngle() + ev->percentage);
- g->setWhatChanged(QPinchGesture::RotationAngleChanged);
- return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
- break;
+ g->setChangeFlags(QPinchGesture::RotationAngleChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
}
case QNativeGestureEvent::Zoom:
g->setLastScaleFactor(g->scaleFactor());
g->setLastRotationAngle(g->rotationAngle());
- g->setScaleFactor(g->scaleFactor() + ev->percentage);
- g->setWhatChanged(QPinchGesture::ScaleFactorChanged);
- return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
- break;
+ g->setScaleFactor(g->scaleFactor() * (1 + ev->percentage));
+ g->setChangeFlags(QPinchGesture::ScaleFactorChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
case QNativeGestureEvent::GestureEnd:
- return QGestureRecognizer::GestureFinished | QGestureRecognizer::ConsumeEventHint;
- break;
+ return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
default:
break;
}
@@ -137,7 +137,8 @@ QMacPinchGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent
void QMacPinchGestureRecognizer::reset(QGesture *gesture)
{
QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
- g->setWhatChanged(0);
+ g->setChangeFlags(0);
+ g->setTotalChangeFlags(0);
g->setScaleFactor(1.0f);
g->setTotalScaleFactor(1.0f);
g->setLastScaleFactor(1.0f);
@@ -158,7 +159,7 @@ QMacPanGestureRecognizer::QMacPanGestureRecognizer() : _panCanceled(true)
{
}
-QGesture *QMacPanGestureRecognizer::createGesture(QObject *target)
+QGesture *QMacPanGestureRecognizer::create(QObject *target)
{
if (!target)
return new QPanGesture;
@@ -172,7 +173,7 @@ QGesture *QMacPanGestureRecognizer::createGesture(QObject *target)
}
QGestureRecognizer::Result
-QMacPanGestureRecognizer::filterEvent(QGesture *gesture, QObject *target, QEvent *event)
+QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *event)
{
const int panBeginDelay = 300;
const int panBeginRadius = 3;
@@ -185,10 +186,9 @@ QMacPanGestureRecognizer::filterEvent(QGesture *gesture, QObject *target, QEvent
if (ev->touchPoints().size() == 1) {
reset(gesture);
_startPos = QCursor::pos();
- _lastPos = _startPos;
_panTimer.start(panBeginDelay, target);
_panCanceled = false;
- return QGestureRecognizer::MaybeGesture;
+ return QGestureRecognizer::MayBeGesture;
}
break;}
case QEvent::TouchEnd: {
@@ -197,7 +197,7 @@ QMacPanGestureRecognizer::filterEvent(QGesture *gesture, QObject *target, QEvent
const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
if (ev->touchPoints().size() == 1)
- return QGestureRecognizer::GestureFinished;
+ return QGestureRecognizer::FinishGesture;
break;}
case QEvent::TouchUpdate: {
if (_panCanceled)
@@ -212,23 +212,21 @@ QMacPanGestureRecognizer::filterEvent(QGesture *gesture, QObject *target, QEvent
if ((p - _startPos).manhattanLength() > panBeginRadius) {
_panCanceled = true;
_panTimer.stop();
- return QGestureRecognizer::NotGesture;
+ return QGestureRecognizer::CancelGesture;
}
} else {
const QPointF p = QCursor::pos();
- const QPointF posOffset = p - _lastPos;
+ const QPointF posOffset = p - _startPos;
g->setLastOffset(g->offset());
g->setOffset(QPointF(posOffset.x(), posOffset.y()));
- g->setTotalOffset(g->lastOffset() + g->offset());
- _lastPos = p;
- return QGestureRecognizer::GestureTriggered;
+ return QGestureRecognizer::TriggerGesture;
}
} else if (_panTimer.isActive()) {
// I only want to cancel the pan if the user is pressing
// more than one finger, and the pan hasn't started yet:
_panCanceled = true;
_panTimer.stop();
- return QGestureRecognizer::NotGesture;
+ return QGestureRecognizer::CancelGesture;
}
break;}
case QEvent::Timer: {
@@ -239,8 +237,7 @@ QMacPanGestureRecognizer::filterEvent(QGesture *gesture, QObject *target, QEvent
break;
// Begin new pan session!
_startPos = QCursor::pos();
- _lastPos = _startPos;
- return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
}
break; }
default:
@@ -254,11 +251,9 @@ void QMacPanGestureRecognizer::reset(QGesture *gesture)
{
QPanGesture *g = static_cast<QPanGesture *>(gesture);
_startPos = QPointF();
- _lastPos = QPointF();
_panCanceled = true;
g->setOffset(QPointF(0, 0));
g->setLastOffset(QPointF(0, 0));
- g->setTotalOffset(QPointF(0, 0));
g->setAcceleration(qreal(1));
QGestureRecognizer::reset(gesture);
}
diff --git a/src/gui/kernel/qmacgesturerecognizer_mac_p.h b/src/gui/kernel/qmacgesturerecognizer_mac_p.h
index bdc2e08..2dac56a 100644
--- a/src/gui/kernel/qmacgesturerecognizer_mac_p.h
+++ b/src/gui/kernel/qmacgesturerecognizer_mac_p.h
@@ -64,8 +64,8 @@ class QMacSwipeGestureRecognizer : public QGestureRecognizer
public:
QMacSwipeGestureRecognizer();
- QGesture *createGesture(QObject *target);
- QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event);
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
void reset(QGesture *gesture);
};
@@ -74,8 +74,8 @@ class QMacPinchGestureRecognizer : public QGestureRecognizer
public:
QMacPinchGestureRecognizer();
- QGesture *createGesture(QObject *target);
- QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event);
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
void reset(QGesture *gesture);
};
@@ -86,12 +86,11 @@ class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer
public:
QMacPanGestureRecognizer();
- QGesture *createGesture(QObject *target);
- QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event);
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
void reset(QGesture *gesture);
private:
QPointF _startPos;
- QPointF _lastPos;
QBasicTimer _panTimer;
bool _panCanceled;
};
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp
index 21795b4..a914220 100644
--- a/src/gui/kernel/qsoftkeymanager.cpp
+++ b/src/gui/kernel/qsoftkeymanager.cpp
@@ -197,8 +197,7 @@ bool QSoftKeyManager::event(QEvent *e)
} while (source);
QSoftKeyManagerPrivate::softKeySource = source;
- if (source)
- QSoftKeyManagerPrivate::updateSoftKeys_sys(softKeys);
+ QSoftKeyManagerPrivate::updateSoftKeys_sys(softKeys);
return true;
}
return false;
@@ -247,7 +246,10 @@ void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys)
}
}
- Qt::WindowType sourceWindowType = QSoftKeyManagerPrivate::softKeySource->window()->windowType();
+ const Qt::WindowType sourceWindowType = QSoftKeyManagerPrivate::softKeySource
+ ? QSoftKeyManagerPrivate::softKeySource->window()->windowType()
+ : Qt::Widget;
+
if (needsExitButton && sourceWindowType != Qt::Dialog && sourceWindowType != Qt::Popup)
QT_TRAP_THROWING(nativeContainer->SetCommandL(2, EAknSoftkeyExit, qt_QString2TPtrC(QSoftKeyManager::tr("Exit"))));
diff --git a/src/gui/kernel/qsound_s60.cpp b/src/gui/kernel/qsound_s60.cpp
index 352580e..e4b7cec 100644
--- a/src/gui/kernel/qsound_s60.cpp
+++ b/src/gui/kernel/qsound_s60.cpp
@@ -60,13 +60,13 @@ class QAuServerS60;
class QAuBucketS60 : public QAuBucket, public MMdaAudioPlayerCallback
{
public:
- QAuBucketS60( QAuServerS60 *server, QSound *sound);
+ QAuBucketS60(QAuServerS60 *server, QSound *sound);
~QAuBucketS60();
void play();
void stop();
- inline QSound* sound() const { return m_sound; }
+ inline QSound *sound() const { return m_sound; }
public: // from MMdaAudioPlayerCallback
void MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration);
@@ -77,88 +77,106 @@ private:
QAuServerS60 *m_server;
bool m_prepared;
bool m_playCalled;
- CMdaAudioPlayerUtility* m_playUtility;
+ CMdaAudioPlayerUtility *m_playUtility;
};
class QAuServerS60 : public QAuServer
{
public:
- QAuServerS60( QObject* parent );
+ QAuServerS60(QObject *parent);
- void init( QSound* s )
+ void init(QSound *s)
{
- QAuBucketS60 *bucket = new QAuBucketS60( this, s );
- setBucket( s, bucket );
+ QAuBucketS60 *bucket = new QAuBucketS60(this, s);
+ setBucket(s, bucket);
}
- void play( QSound* s )
+ void play(QSound *s)
{
- bucket( s )->play();
+ bucket(s)->play();
}
- void stop( QSound* s )
+ void stop(QSound *s)
{
- bucket( s )->stop();
+ bucket(s)->stop();
}
bool okay() { return true; }
+ void play(const QString& filename);
+
protected:
- void playCompleted(QAuBucketS60* bucket, int error)
- {
- QSound *sound = bucket->sound();
- if(!error) {
- // We need to handle repeats by ourselves, since with Symbian API we don't
- // know how many loops have been played when user asks it
- if( decLoop( sound ) ) {
- play( sound );
- }
- } else {
- // We don't have a way to inform about errors -> just decrement loops
- // in order that QSound::isFinished will return true;
- while(decLoop(sound)) {}
- }
- }
+ void playCompleted(QAuBucketS60 *bucket, int error);
protected:
- QAuBucketS60* bucket( QSound *s )
+ QAuBucketS60 *bucket(QSound *s)
{
- return (QAuBucketS60*)QAuServer::bucket( s );
+ return (QAuBucketS60 *)QAuServer::bucket( s );
}
friend class QAuBucketS60;
+ // static QSound::play(filename) cannot be stopped, meaning that playCompleted
+ // will get always called and QSound gets removed form this list.
+ QList<QSound *> staticPlayingSounds;
};
-QAuServerS60::QAuServerS60(QObject* parent) :
+QAuServerS60::QAuServerS60(QObject *parent) :
QAuServer(parent)
{
setObjectName(QLatin1String("QAuServerS60"));
}
+void QAuServerS60::play(const QString& filename)
+{
+ QSound *s = new QSound(filename);
+ staticPlayingSounds.append(s);
+ play(s);
+}
+
+void QAuServerS60::playCompleted(QAuBucketS60 *bucket, int error)
+{
+ QSound *sound = bucket->sound();
+ if (!error) {
+ // We need to handle repeats by ourselves, since with Symbian API we don't
+ // know how many loops have been played when user asks it
+ if (decLoop(sound)) {
+ play(sound);
+ } else {
+ if (staticPlayingSounds.removeAll(sound))
+ delete sound;
+ }
+ } else {
+ // We don't have a way to inform about errors -> just decrement loops
+ // in order that QSound::isFinished will return true;
+ while (decLoop(sound)) {}
+ if (staticPlayingSounds.removeAll(sound))
+ delete sound;
+ }
+}
-QAuServer* qt_new_audio_server()
+QAuServer *qt_new_audio_server()
{
return new QAuServerS60(qApp);
}
-QAuBucketS60::QAuBucketS60( QAuServerS60 *server, QSound *sound )
- : m_sound( sound ), m_server( server ), m_prepared(false), m_playCalled(false)
+QAuBucketS60::QAuBucketS60(QAuServerS60 *server, QSound *sound)
+ : m_sound(sound), m_server(server), m_prepared(false), m_playCalled(false)
{
- QString filepath = QFileInfo( m_sound->fileName() ).absoluteFilePath();
+ QString filepath = QFileInfo(m_sound->fileName()).absoluteFilePath();
filepath = QDir::toNativeSeparators(filepath);
TPtrC filepathPtr(qt_QString2TPtrC(filepath));
TRAPD(err, m_playUtility = CMdaAudioPlayerUtility::NewL(*this);
m_playUtility->OpenFileL(filepathPtr));
- if(err){
+ if (err) {
m_server->playCompleted(this, err);
}
}
void QAuBucketS60::play()
{
- if(m_prepared) {
+ if (m_prepared) {
// OpenFileL call is completed we can start playing immediately
m_playUtility->Play();
} else {
@@ -180,11 +198,11 @@ void QAuBucketS60::MapcPlayComplete(TInt aError)
void QAuBucketS60::MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& /*aDuration*/)
{
- if(aError) {
+ if (aError) {
m_server->playCompleted(this, aError);
} else {
m_prepared = true;
- if(m_playCalled){
+ if (m_playCalled){
play();
}
}
@@ -192,7 +210,7 @@ void QAuBucketS60::MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds
QAuBucketS60::~QAuBucketS60()
{
- if(m_playUtility){
+ if (m_playUtility){
m_playUtility->Stop();
m_playUtility->Close();
}
diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp
index dec2311..0ea4764 100644
--- a/src/gui/kernel/qstandardgestures.cpp
+++ b/src/gui/kernel/qstandardgestures.cpp
@@ -44,6 +44,8 @@
#include "qgesture_p.h"
#include "qevent.h"
#include "qwidget.h"
+#include "qabstractscrollarea.h"
+#include "qdebug.h"
QT_BEGIN_NAMESPACE
@@ -51,29 +53,36 @@ QPanGestureRecognizer::QPanGestureRecognizer()
{
}
-QGesture *QPanGestureRecognizer::createGesture(QObject *target)
+QGesture *QPanGestureRecognizer::create(QObject *target)
{
if (target && target->isWidgetType()) {
+#if defined(Q_OS_WIN)
+ // for scroll areas on Windows we want to use native gestures instead
+ if (!qobject_cast<QAbstractScrollArea *>(target->parent()))
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+#else
static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+#endif
}
return new QPanGesture;
}
-QGestureRecognizer::Result QPanGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event)
+QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
+ QObject *,
+ QEvent *event)
{
- QPanGesture *q = static_cast<QPanGesture*>(state);
+ QPanGesture *q = static_cast<QPanGesture *>(state);
QPanGesturePrivate *d = q->d_func();
- const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
QGestureRecognizer::Result result;
switch (event->type()) {
case QEvent::TouchBegin: {
- result = QGestureRecognizer::MaybeGesture;
+ result = QGestureRecognizer::MayBeGesture;
QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
- d->lastPosition = p.pos().toPoint();
- d->lastOffset = d->totalOffset = d->offset = QPointF();
+ d->lastOffset = d->offset = QPointF();
break;
}
case QEvent::TouchEnd: {
@@ -83,13 +92,12 @@ QGestureRecognizer::Result QPanGestureRecognizer::filterEvent(QGesture *state, Q
QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
d->lastOffset = d->offset;
d->offset =
- QPointF(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(),
- p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2;
- d->totalOffset += d->offset;
+ QPointF(p1.pos().x() - p1.startPos().x() + p2.pos().x() - p2.startPos().x(),
+ p1.pos().y() - p1.startPos().y() + p2.pos().y() - p2.startPos().y()) / 2;
}
- result = QGestureRecognizer::GestureFinished;
+ result = QGestureRecognizer::FinishGesture;
} else {
- result = QGestureRecognizer::NotGesture;
+ result = QGestureRecognizer::CancelGesture;
}
break;
}
@@ -99,14 +107,13 @@ QGestureRecognizer::Result QPanGestureRecognizer::filterEvent(QGesture *state, Q
QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
d->lastOffset = d->offset;
d->offset =
- QPointF(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(),
- p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2;
- d->totalOffset += d->offset;
- if (d->totalOffset.x() > 10 || d->totalOffset.y() > 10 ||
- d->totalOffset.x() < -10 || d->totalOffset.y() < -10) {
- result = QGestureRecognizer::GestureTriggered;
+ QPointF(p1.pos().x() - p1.startPos().x() + p2.pos().x() - p2.startPos().x(),
+ p1.pos().y() - p1.startPos().y() + p2.pos().y() - p2.startPos().y()) / 2;
+ if (d->offset.x() > 10 || d->offset.y() > 10 ||
+ d->offset.x() < -10 || d->offset.y() < -10) {
+ result = QGestureRecognizer::TriggerGesture;
} else {
- result = QGestureRecognizer::MaybeGesture;
+ result = QGestureRecognizer::MayBeGesture;
}
}
break;
@@ -128,108 +135,433 @@ void QPanGestureRecognizer::reset(QGesture *state)
QPanGesture *pan = static_cast<QPanGesture*>(state);
QPanGesturePrivate *d = pan->d_func();
- d->totalOffset = d->lastOffset = d->offset = QPointF();
- d->lastPosition = QPoint();
+ d->lastOffset = d->offset = QPointF();
d->acceleration = 0;
-//#if defined(QT_MAC_USE_COCOA)
-// d->singleTouchPanTimer.stop();
-// d->prevMousePos = QPointF(0, 0);
-//#endif
-
QGestureRecognizer::reset(state);
}
-/*
-bool QPanGestureRecognizer::event(QEvent *event)
+
+//
+// QPinchGestureRecognizer
+//
+
+QPinchGestureRecognizer::QPinchGestureRecognizer()
{
-#if defined(QT_MAC_USE_COCOA)
- Q_D(QPanGesture);
- if (event->type() == QEvent::Timer) {
- const QTimerEvent *te = static_cast<QTimerEvent *>(event);
- if (te->timerId() == d->singleTouchPanTimer.timerId()) {
- d->singleTouchPanTimer.stop();
- updateState(Qt::GestureStarted);
- }
+}
+
+QGesture *QPinchGestureRecognizer::create(QObject *target)
+{
+ if (target && target->isWidgetType()) {
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
}
-#endif
+ return new QPinchGesture;
+}
+
+QGestureRecognizer::Result QPinchGestureRecognizer::recognize(QGesture *state,
+ QObject *,
+ QEvent *event)
+{
+ QPinchGesture *q = static_cast<QPinchGesture *>(state);
+ QPinchGesturePrivate *d = q->d_func();
- bool consume = false;
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
-#if defined(Q_WS_WIN)
-#elif defined(QT_MAC_USE_COCOA)
- // The following implements single touch
- // panning on Mac:
- const int panBeginDelay = 300;
- const int panBeginRadius = 3;
- const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ QGestureRecognizer::Result result;
switch (event->type()) {
case QEvent::TouchBegin: {
- if (ev->touchPoints().size() == 1) {
- d->delayManager->setEnabled(true);
- consume = d->delayManager->append(d->gestureTarget, *event);
- d->lastPosition = QCursor::pos();
- d->singleTouchPanTimer.start(panBeginDelay, this);
+ result = QGestureRecognizer::MayBeGesture;
+ break;
+ }
+ case QEvent::TouchEnd: {
+ if (q->state() != Qt::NoGesture) {
+ result = QGestureRecognizer::FinishGesture;
+ } else {
+ result = QGestureRecognizer::CancelGesture;
}
- break;}
+ break;
+ }
+ case QEvent::TouchUpdate: {
+ d->changeFlags = 0;
+ if (ev->touchPoints().size() == 2) {
+ QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
+ QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
+
+ d->hotSpot = p1.screenPos();
+ d->isHotSpotSet = true;
+
+ if (d->isNewSequence) {
+ d->startPosition[0] = p1.screenPos();
+ d->startPosition[1] = p2.screenPos();
+ }
+ QLineF line(p1.screenPos(), p2.screenPos());
+ QLineF tmp(line);
+ tmp.setLength(line.length() / 2.);
+ QPointF centerPoint = tmp.p2();
+
+ d->lastCenterPoint = d->centerPoint;
+ d->centerPoint = centerPoint;
+ d->changeFlags |= QPinchGesture::CenterPointChanged;
+
+ const qreal scaleFactor =
+ QLineF(p1.screenPos(), p2.screenPos()).length()
+ / QLineF(d->startPosition[0], d->startPosition[1]).length();
+ if (d->isNewSequence) {
+ d->lastScaleFactor = scaleFactor;
+ } else {
+ d->lastScaleFactor = d->scaleFactor;
+ }
+ d->scaleFactor = scaleFactor;
+ d->totalScaleFactor += d->scaleFactor - d->lastScaleFactor;
+ d->changeFlags |= QPinchGesture::ScaleFactorChanged;
+
+ qreal angle = QLineF(p1.screenPos(), p2.screenPos()).angle();
+ if (angle > 180)
+ angle -= 360;
+ qreal startAngle = QLineF(p1.startScreenPos(), p2.startScreenPos()).angle();
+ if (startAngle > 180)
+ startAngle -= 360;
+ const qreal rotationAngle = startAngle - angle;
+ if (d->isNewSequence)
+ d->lastRotationAngle = rotationAngle;
+ else
+ d->lastRotationAngle = d->rotationAngle;
+ d->rotationAngle = rotationAngle;
+ d->totalRotationAngle += d->rotationAngle - d->lastRotationAngle;
+ d->changeFlags |= QPinchGesture::RotationAngleChanged;
+
+ d->totalChangeFlags |= d->changeFlags;
+ d->isNewSequence = false;
+ result = QGestureRecognizer::TriggerGesture;
+ } else {
+ d->isNewSequence = true;
+ if (q->state() == Qt::NoGesture)
+ result = QGestureRecognizer::Ignore;
+ else
+ result = QGestureRecognizer::FinishGesture;
+ }
+ break;
+ }
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ result = QGestureRecognizer::Ignore;
+ break;
+ default:
+ result = QGestureRecognizer::Ignore;
+ break;
+ }
+ return result;
+}
+
+void QPinchGestureRecognizer::reset(QGesture *state)
+{
+ QPinchGesture *pinch = static_cast<QPinchGesture *>(state);
+ QPinchGesturePrivate *d = pinch->d_func();
+
+ d->totalChangeFlags = d->changeFlags = 0;
+
+ d->startCenterPoint = d->lastCenterPoint = d->centerPoint = QPointF();
+ d->totalScaleFactor = d->lastScaleFactor = d->scaleFactor = 0;
+ d->totalRotationAngle = d->lastRotationAngle = d->rotationAngle = 0;
+
+ d->isNewSequence = true;
+ d->startPosition[0] = d->startPosition[1] = QPointF();
+
+ QGestureRecognizer::reset(state);
+}
+
+//
+// QSwipeGestureRecognizer
+//
+
+QSwipeGestureRecognizer::QSwipeGestureRecognizer()
+{
+}
+
+QGesture *QSwipeGestureRecognizer::create(QObject *target)
+{
+ if (target && target->isWidgetType()) {
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+ return new QSwipeGesture;
+}
+
+QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
+ QObject *,
+ QEvent *event)
+{
+ QSwipeGesture *q = static_cast<QSwipeGesture *>(state);
+ QSwipeGesturePrivate *d = q->d_func();
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+
+ QGestureRecognizer::Result result;
+
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ d->speed = 1;
+ d->time = QTime::currentTime();
+ d->started = true;
+ result = QGestureRecognizer::MayBeGesture;
+ break;
+ }
case QEvent::TouchEnd: {
- d->delayManager->setEnabled(false);
- if (state() != Qt::NoGesture) {
- updateState(Qt::GestureFinished);
- consume = true;
- d->delayManager->clear();
+ if (q->state() != Qt::NoGesture) {
+ result = QGestureRecognizer::FinishGesture;
} else {
- d->delayManager->replay();
+ result = QGestureRecognizer::CancelGesture;
}
- reset();
- break;}
+ break;
+ }
case QEvent::TouchUpdate: {
- consume = d->delayManager->append(d->gestureTarget, *event);
- if (ev->touchPoints().size() == 1) {
- if (state() == Qt::NoGesture) {
- // INVARIANT: The singleTouchTimer has still not fired.
- // Lets check if the user moved his finger so much from
- // the starting point that it makes sense to cancel:
- const QPointF startPos = ev->touchPoints().at(0).startPos().toPoint();
- const QPointF p = ev->touchPoints().at(0).pos().toPoint();
- if ((startPos - p).manhattanLength() > panBeginRadius) {
- d->delayManager->replay();
- consume = false;
- reset();
- } else {
- d->lastPosition = QCursor::pos();
+ if (!d->started)
+ result = QGestureRecognizer::CancelGesture;
+ else if (ev->touchPoints().size() == 3) {
+ QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
+ QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
+ QTouchEvent::TouchPoint p3 = ev->touchPoints().at(2);
+
+ if (d->lastPositions[0].isNull()) {
+ d->lastPositions[0] = p1.startScreenPos().toPoint();
+ d->lastPositions[1] = p2.startScreenPos().toPoint();
+ d->lastPositions[2] = p3.startScreenPos().toPoint();
+ }
+ d->hotSpot = p1.screenPos();
+ d->isHotSpotSet = true;
+
+ int xDistance = (p1.screenPos().x() - d->lastPositions[0].x() +
+ p2.screenPos().x() - d->lastPositions[1].x() +
+ p3.screenPos().x() - d->lastPositions[2].x()) / 3;
+ int yDistance = (p1.screenPos().y() - d->lastPositions[0].y() +
+ p2.screenPos().y() - d->lastPositions[1].y() +
+ p3.screenPos().y() - d->lastPositions[2].y()) / 3;
+
+ const int distance = xDistance >= yDistance ? xDistance : yDistance;
+ int elapsedTime = d->time.msecsTo(QTime::currentTime());
+ if (!elapsedTime)
+ elapsedTime = 1;
+ d->speed = 0.9 * d->speed + distance / elapsedTime;
+ d->time = QTime::currentTime();
+ d->swipeAngle = QLineF(p1.startScreenPos(), p1.screenPos()).angle();
+
+ static const int MoveThreshold = 50;
+ if (xDistance > MoveThreshold || yDistance > MoveThreshold) {
+ // measure the distance to check if the direction changed
+ d->lastPositions[0] = p1.screenPos().toPoint();
+ d->lastPositions[1] = p2.screenPos().toPoint();
+ d->lastPositions[2] = p3.screenPos().toPoint();
+ QSwipeGesture::SwipeDirection horizontal =
+ xDistance > 0 ? QSwipeGesture::Right : QSwipeGesture::Left;
+ QSwipeGesture::SwipeDirection vertical =
+ yDistance > 0 ? QSwipeGesture::Down : QSwipeGesture::Up;
+ if (d->verticalDirection == QSwipeGesture::NoDirection)
+ d->verticalDirection = vertical;
+ if (d->horizontalDirection == QSwipeGesture::NoDirection)
+ d->horizontalDirection = horizontal;
+ if (d->verticalDirection != vertical || d->horizontalDirection != horizontal) {
+ // the user has changed the direction!
+ result = QGestureRecognizer::CancelGesture;
}
+ result = QGestureRecognizer::TriggerGesture;
} else {
- d->delayManager->clear();
- QPointF mousePos = QCursor::pos();
- QPointF dist = mousePos - d->lastPosition;
- d->lastPosition = mousePos;
- d->lastOffset = d->offset;
- d->offset = QSizeF(dist.x(), dist.y());
- d->totalOffset += d->offset;
- updateState(Qt::GestureUpdated);
+ if (q->state() != Qt::NoGesture)
+ result = QGestureRecognizer::TriggerGesture;
+ else
+ result = QGestureRecognizer::MayBeGesture;
}
- } else if (state() == Qt::NoGesture) {
- d->delayManager->replay();
- consume = false;
- reset();
+ } else if (ev->touchPoints().size() > 3) {
+ result = QGestureRecognizer::CancelGesture;
+ } else { // less than 3 touch points
+ if (d->started && (ev->touchPointStates() & Qt::TouchPointPressed))
+ result = QGestureRecognizer::CancelGesture;
+ else if (d->started)
+ result = QGestureRecognizer::Ignore;
+ else
+ result = QGestureRecognizer::MayBeGesture;
}
- break;}
+ break;
+ }
case QEvent::MouseButtonPress:
case QEvent::MouseMove:
case QEvent::MouseButtonRelease:
- if (d->delayManager->isEnabled())
- consume = d->delayManager->append(d->gestureTarget, *event);
+ result = QGestureRecognizer::Ignore;
break;
default:
- return false;
+ result = QGestureRecognizer::Ignore;
+ break;
}
-#else
- Q_UNUSED(event);
-#endif
- return QGestureRecognizer::Ignore;
+ return result;
+}
+
+void QSwipeGestureRecognizer::reset(QGesture *state)
+{
+ QSwipeGesture *q = static_cast<QSwipeGesture *>(state);
+ QSwipeGesturePrivate *d = q->d_func();
+
+ d->verticalDirection = d->horizontalDirection = QSwipeGesture::NoDirection;
+ d->swipeAngle = 0;
+
+ d->lastPositions[0] = d->lastPositions[1] = d->lastPositions[2] = QPoint();
+ d->started = false;
+ d->speed = 0;
+ d->time = QTime();
+
+ QGestureRecognizer::reset(state);
+}
+
+//
+// QTapGestureRecognizer
+//
+
+QTapGestureRecognizer::QTapGestureRecognizer()
+{
+}
+
+QGesture *QTapGestureRecognizer::create(QObject *target)
+{
+ if (target && target->isWidgetType()) {
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+ return new QTapGesture;
+}
+
+QGestureRecognizer::Result QTapGestureRecognizer::recognize(QGesture *state,
+ QObject *,
+ QEvent *event)
+{
+ QTapGesture *q = static_cast<QTapGesture *>(state);
+ QTapGesturePrivate *d = q->d_func();
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+
+ QGestureRecognizer::Result result = QGestureRecognizer::CancelGesture;
+
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ d->position = ev->touchPoints().at(0).pos();
+ result = QGestureRecognizer::TriggerGesture;
+ break;
+ }
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd: {
+ if (q->state() != Qt::NoGesture && ev->touchPoints().size() == 1) {
+ QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
+ QPoint delta = p.pos().toPoint() - p.startPos().toPoint();
+ enum { TapRadius = 40 };
+ if (delta.manhattanLength() <= TapRadius) {
+ if (event->type() == QEvent::TouchEnd)
+ result = QGestureRecognizer::FinishGesture;
+ else
+ result = QGestureRecognizer::TriggerGesture;
+ }
+ }
+ break;
+ }
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ result = QGestureRecognizer::Ignore;
+ break;
+ default:
+ result = QGestureRecognizer::Ignore;
+ break;
+ }
+ return result;
+}
+
+void QTapGestureRecognizer::reset(QGesture *state)
+{
+ QTapGesture *q = static_cast<QTapGesture *>(state);
+ QTapGesturePrivate *d = q->d_func();
+
+ d->position = QPointF();
+
+ QGestureRecognizer::reset(state);
+}
+
+//
+// QTapAndHoldGestureRecognizer
+//
+
+QTapAndHoldGestureRecognizer::QTapAndHoldGestureRecognizer()
+{
+}
+
+QGesture *QTapAndHoldGestureRecognizer::create(QObject *target)
+{
+ if (target && target->isWidgetType()) {
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
+ }
+ return new QTapAndHoldGesture;
+}
+
+QGestureRecognizer::Result
+QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object,
+ QEvent *event)
+{
+ QTapAndHoldGesture *q = static_cast<QTapAndHoldGesture *>(state);
+ QTapAndHoldGesturePrivate *d = q->d_func();
+
+ if (object == state && event->type() == QEvent::Timer) {
+ q->killTimer(d->timerId);
+ d->timerId = 0;
+ return QGestureRecognizer::Ignore | QGestureRecognizer::ConsumeEventHint;
+ }
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
+
+ QGestureRecognizer::Result result = QGestureRecognizer::CancelGesture;
+
+ enum { TimerInterval = 2000 };
+ enum { TapRadius = 40 };
+
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ d->position = ev->touchPoints().at(0).pos();
+ if (d->timerId)
+ q->killTimer(d->timerId);
+ d->timerId = q->startTimer(TimerInterval);
+ result = QGestureRecognizer::TriggerGesture;
+ break;
+ case QEvent::TouchEnd:
+ if (d->timerId)
+ result = QGestureRecognizer::CancelGesture;
+ else
+ result = QGestureRecognizer::FinishGesture;
+ break;
+ case QEvent::TouchUpdate:
+ if (q->state() != Qt::NoGesture && ev->touchPoints().size() == 1) {
+ QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
+ QPoint delta = p.pos().toPoint() - p.startPos().toPoint();
+ if (delta.manhattanLength() <= TapRadius)
+ result = QGestureRecognizer::TriggerGesture;
+ }
+ break;
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ result = QGestureRecognizer::Ignore;
+ break;
+ default:
+ result = QGestureRecognizer::Ignore;
+ break;
+ }
+ return result;
+}
+
+void QTapAndHoldGestureRecognizer::reset(QGesture *state)
+{
+ QTapAndHoldGesture *q = static_cast<QTapAndHoldGesture *>(state);
+ QTapAndHoldGesturePrivate *d = q->d_func();
+
+ d->position = QPointF();
+ if (d->timerId)
+ q->killTimer(d->timerId);
+ d->timerId = 0;
+
+ QGestureRecognizer::reset(state);
}
- */
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h
index fec5c2f..8fea2bc 100644
--- a/src/gui/kernel/qstandardgestures_p.h
+++ b/src/gui/kernel/qstandardgestures_p.h
@@ -63,9 +63,48 @@ class QPanGestureRecognizer : public QGestureRecognizer
public:
QPanGestureRecognizer();
- QGesture *createGesture(QObject *target);
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+class QPinchGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QPinchGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+class QSwipeGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QSwipeGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+class QTapGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QTapGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+class QTapAndHoldGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QTapAndHoldGestureRecognizer();
- QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event);
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
void reset(QGesture *state);
};
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 789d89e..3405bcf 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -73,6 +73,7 @@
#include <akntitle.h> // CAknTitlePane
#include <akncontext.h> // CAknContextPane
#include <eikspane.h> // CEikStatusPane
+#include <aknpopupfader.h> // MAknFadedComponent and TAknPopupFader
#endif
QT_BEGIN_NAMESPACE
@@ -114,7 +115,7 @@ public:
int supportsPremultipliedAlpha : 1;
QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type
static inline void updateScreenSize();
- static inline RWsSession& wsSession();
+ static inline RWsSession& wsSession();
static inline RWindowGroup& windowGroup();
static inline CWsScreenDevice* screenDevice();
static inline CCoeAppUi* appUi();
@@ -140,7 +141,11 @@ public:
};
class QLongTapTimer;
+
class QSymbianControl : public CCoeControl, public QAbstractLongTapObserver
+#ifdef Q_WS_S60
+, public MAknFadedComponent
+#endif
{
public:
DECLARE_TYPE_ID(0x51740000) // Fun fact: the two first values are "Qt" in ASCII.
@@ -165,6 +170,17 @@ public:
void setFocusSafely(bool focus);
+#ifdef Q_WS_S60
+ void FadeBehindPopup(bool fade){ popupFader.FadeBehindPopup( this, this, fade); }
+
+protected: // from MAknFadedComponent
+ TInt CountFadedComponents() {return 1;}
+ CCoeControl* FadedComponent(TInt aIndex) {return this;}
+#else
+ #warning No fallback implementation for QSymbianControl::FadeBehindPopup
+ void FadeBehindPopup(bool /*fade*/){ }
+#endif
+
protected:
void Draw(const TRect& aRect) const;
void SizeChanged();
@@ -189,6 +205,11 @@ private:
bool m_ignoreFocusChanged;
QLongTapTimer* m_longTapDetector;
bool m_previousEventLongTap;
+
+#ifdef Q_WS_S60
+ // Fader object used to fade everything except this menu and the CBA.
+ TAknPopupFader popupFader;
+#endif
};
inline QS60Data::QS60Data()
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 9165515..271b939 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -197,6 +197,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
, picture(0)
#elif defined(Q_WS_WIN)
, noPaintOnScreen(0)
+ , nativeGesturePanEnabled(0)
#elif defined(Q_WS_MAC)
, needWindowChange(0)
, isGLWidget(0)
@@ -229,7 +230,9 @@ QWidgetPrivate::~QWidgetPrivate()
if (extra)
deleteExtra();
+#ifndef QT_NO_GRAPHICSEFFECT
delete graphicsEffect;
+#endif //QT_NO_GRAPHICSEFFECT
}
QWindowSurface *QWidgetPrivate::createDefaultWindowSurface()
@@ -1792,6 +1795,7 @@ QRegion QWidgetPrivate::clipRegion() const
return r;
}
+#ifndef QT_NO_GRAPHICSEFFECT
void QWidgetPrivate::invalidateGraphicsEffectsRecursively()
{
Q_Q(QWidget);
@@ -1806,6 +1810,7 @@ void QWidgetPrivate::invalidateGraphicsEffectsRecursively()
w = w->parentWidget();
} while (w);
}
+#endif //QT_NO_GRAPHICSEFFECT
void QWidgetPrivate::setDirtyOpaqueRegion()
{
@@ -1813,7 +1818,9 @@ void QWidgetPrivate::setDirtyOpaqueRegion()
dirtyOpaqueChildren = true;
+#ifndef QT_NO_GRAPHICSEFFECT
invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
if (q->isWindow())
return;
@@ -1962,10 +1969,12 @@ void QWidgetPrivate::clipToEffectiveMask(QRegion &region) const
const QWidget *w = q;
QPoint offset;
+#ifndef QT_NO_GRAPHICSEFFECT
if (graphicsEffect) {
w = q->parentWidget();
offset -= data.crect.topLeft();
}
+#endif //QT_NO_GRAPHICSEFFECT
while (w) {
const QWidgetPrivate *wd = w->d_func();
@@ -2000,11 +2009,13 @@ void QWidgetPrivate::updateIsOpaque()
// hw: todo: only needed if opacity actually changed
setDirtyOpaqueRegion();
+#ifndef QT_NO_GRAPHICSEFFECT
if (graphicsEffect) {
// ### We should probably add QGraphicsEffect::isOpaque at some point.
setOpaque(false);
return;
}
+#endif //QT_NO_GRAPHICSEFFECT
Q_Q(QWidget);
#ifdef Q_WS_X11
@@ -5012,11 +5023,13 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
\sa setGraphicsEffect()
*/
+#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsEffect *QWidget::graphicsEffect() const
{
Q_D(const QWidget);
return d->graphicsEffect;
}
+#endif //QT_NO_GRAPHICSEFFECT
/*!
@@ -5035,6 +5048,7 @@ QGraphicsEffect *QWidget::graphicsEffect() const
\sa graphicsEffect()
*/
+#ifndef QT_NO_GRAPHICSEFFECT
void QWidget::setGraphicsEffect(QGraphicsEffect *effect)
{
Q_D(QWidget);
@@ -5064,6 +5078,7 @@ void QWidget::setGraphicsEffect(QGraphicsEffect *effect)
d->updateIsOpaque();
update();
}
+#endif //QT_NO_GRAPHICSEFFECT
bool QWidgetPrivate::isAboutToShow() const
{
@@ -5156,8 +5171,7 @@ void QWidgetPrivate::render_helper(QPainter *painter, const QPoint &targetOffset
return;
QPixmap pixmap(size);
- if (!(renderFlags & QWidget::DrawWindowBackground)
- || !q->palette().brush(q->backgroundRole()).isOpaque())
+ if (!(renderFlags & QWidget::DrawWindowBackground) || !isOpaque)
pixmap.fill(Qt::transparent);
q->render(&pixmap, QPoint(), toBePainted, renderFlags);
@@ -5210,6 +5224,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
return;
Q_Q(QWidget);
+#ifndef QT_NO_GRAPHICSEFFECT
if (graphicsEffect && graphicsEffect->isEnabled()) {
QGraphicsEffectSource *source = graphicsEffect->d_func()->source;
QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
@@ -5240,6 +5255,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
return;
}
}
+#endif //QT_NO_GRAFFICSEFFECT
const bool asRoot = flags & DrawAsRoot;
const bool alsoOnScreen = flags & DrawPaintOnScreen;
@@ -5394,7 +5410,6 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
QWidgetPrivate *wd = w->d_func();
const QPoint widgetPos(w->data->crect.topLeft());
const bool hasMask = wd->extra && wd->extra->hasMask && !wd->graphicsEffect;
-
if (index > 0) {
QRegion wr(rgn);
if (wd->isOpaque)
@@ -5420,6 +5435,7 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
}
}
+#ifndef QT_NO_GRAPHICSEFFECT
QRectF QWidgetEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
{
if (system != Qt::DeviceCoordinates)
@@ -5520,6 +5536,7 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *
m_widget->render(&pixmap, pixmapOffset);
return pixmap;
}
+#endif //QT_NO_GRAPHICSEFFECT
#ifndef QT_NO_GRAPHICSVIEW
/*!
@@ -11736,22 +11753,22 @@ QGraphicsProxyWidget *QWidget::graphicsProxyWidget() const
*/
/*!
- Subscribes the widget to a given \a gesture with a \a context.
+ Subscribes the widget to a given \a gesture with specific \a flags.
- \sa QGestureEvent
+ \sa ungrabGesture(), QGestureEvent
\since 4.6
*/
-void QWidget::grabGesture(Qt::GestureType gesture, Qt::GestureContext context)
+void QWidget::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
{
Q_D(QWidget);
- d->gestureContext.insert(gesture, context);
+ d->gestureContext.insert(gesture, flags);
(void)QGestureManager::instance(); // create a gesture manager
}
/*!
- Unsubscribes the widget to a given \a gesture type
+ Unsubscribes the widget from a given \a gesture type
- \sa QGestureEvent
+ \sa grabGesture(), QGestureEvent
\since 4.6
*/
void QWidget::ungrabGesture(Qt::GestureType gesture)
diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h
index fce3f09..b7c55f9 100644
--- a/src/gui/kernel/qwidget.h
+++ b/src/gui/kernel/qwidget.h
@@ -351,10 +351,12 @@ public:
const QRegion &sourceRegion = QRegion(),
RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren));
+#ifndef QT_NO_GRAPHICSEFFECT
QGraphicsEffect *graphicsEffect() const;
void setGraphicsEffect(QGraphicsEffect *effect);
+#endif //QT_NO_GRAPHICSEFFECT
- void grabGesture(Qt::GestureType type, Qt::GestureContext context = Qt::WidgetWithChildrenGesture);
+ void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags());
void ungrabGesture(Qt::GestureType type);
public Q_SLOTS:
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 58252ca..75f9a59 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -730,6 +730,7 @@ static EventTypeSpec window_events[] = {
{ kEventClassWindow, kEventWindowClose },
{ kEventClassWindow, kEventWindowExpanded },
{ kEventClassWindow, kEventWindowHidden },
+ { kEventClassWindow, kEventWindowZoom },
{ kEventClassWindow, kEventWindowZoomed },
{ kEventClassWindow, kEventWindowCollapsed },
{ kEventClassWindow, kEventWindowToolbarSwitchMode },
@@ -812,6 +813,9 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event,
QShowEvent qse;
QApplication::sendSpontaneousEvent(widget, &qse);
+ } else if(ekind == kEventWindowZoom) {
+ widget->d_func()->topData()->normalGeometry = widget->geometry();
+ handled_event = false;
} else if(ekind == kEventWindowZoomed) {
WindowPartCode windowPart;
GetEventParameter(event, kEventParamWindowPartCode,
@@ -3017,10 +3021,17 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
#else
QMacCocoaAutoReleasePool pool;
NSButton *iconButton = [qt_mac_window_for(q) standardWindowButton:NSWindowDocumentIconButton];
+ if (iconButton == nil) {
+ QCFString string(q->windowTitle());
+ const NSString *tmpString = reinterpret_cast<const NSString *>((CFStringRef)string);
+ [qt_mac_window_for(q) setRepresentedURL:[NSURL fileURLWithPath:tmpString]];
+ iconButton = [qt_mac_window_for(q) standardWindowButton:NSWindowDocumentIconButton];
+ }
if (icon.isNull()) {
[iconButton setImage:nil];
} else {
- NSImage *image = static_cast<NSImage *>(qt_mac_create_nsimage(*pm));
+ QPixmap scaled = pm->scaled(QSize(16,16), Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ NSImage *image = static_cast<NSImage *>(qt_mac_create_nsimage(scaled));
[iconButton setImage:image];
[image release];
}
@@ -3480,10 +3491,10 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
qt_mac_set_fullscreen_mode(true);
} else {
needShow = isVisible();
- setParent(parentWidget(), d->topData()->savedFlags);
- setGeometry(d->topData()->normalGeometry);
if(!qApp->desktop()->screenNumber(this))
qt_mac_set_fullscreen_mode(false);
+ setParent(parentWidget(), d->topData()->savedFlags);
+ setGeometry(d->topData()->normalGeometry);
d->topData()->normalGeometry.setRect(0, 0, -1, -1);
}
}
@@ -3585,7 +3596,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
[window zoom:window];
#endif
needSendStateChange = oldstate == windowState(); // Zoom didn't change flags.
- } else if(oldstate & Qt::WindowMaximized) {
+ } else if(oldstate & Qt::WindowMaximized && !(oldstate & Qt::WindowFullScreen)) {
#ifndef QT_MAC_USE_COCOA
Point idealSize;
ZoomWindowIdeal(window, inZoomIn, &idealSize);
@@ -3780,7 +3791,7 @@ void QWidgetPrivate::stackUnder_sys(QWidget *w)
/*
Modifies the bounds for a widgets backing HIView during moves and resizes. Also updates the
widget, either by scrolling its contents or repainting, depending on the WA_StaticContents
- and QWidgetPrivate::isOpaque flags.
+ flag
*/
static void qt_mac_update_widget_posisiton(QWidget *q, QRect oldRect, QRect newRect)
{
@@ -3797,8 +3808,8 @@ static void qt_mac_update_widget_posisiton(QWidget *q, QRect oldRect, QRect newR
// Perform a normal (complete repaint) update in some cases:
if (
- // move-by-scroll requires QWidgetPrivate::isOpaque set
- (isMove && q->testAttribute(Qt::WA_OpaquePaintEvent) == false) ||
+ // always repaint on move.
+ (isMove) ||
// limited update on resize requires WA_StaticContents.
(isResize && q->testAttribute(Qt::WA_StaticContents) == false) ||
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 73a7d68..151b90a 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -384,7 +384,9 @@ public:
void setOpaque(bool opaque);
void updateIsTranslucent();
bool paintOnScreen() const;
+#ifndef QT_NO_GRAPHICSEFFECT
void invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
const QRegion &getOpaqueChildren() const;
void setDirtyOpaqueRegion();
@@ -530,8 +532,10 @@ public:
inline QRect effectiveRectFor(const QRect &rect) const
{
+#ifndef QT_NO_GRAPHICSEFFECT
if (graphicsEffect && graphicsEffect->isEnabled())
return graphicsEffect->boundingRectFor(rect).toAlignedRect();
+#endif //QT_NO_GRAPHICSEFFECT
return rect;
}
@@ -630,7 +634,7 @@ public:
#ifndef QT_NO_ACTION
QList<QAction*> actions;
#endif
- QMap<Qt::GestureType, Qt::GestureContext> gestureContext;
+ QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
// Bit fields.
uint high_attributes[3]; // the low ones are in QWidget::widget_attributes
@@ -774,6 +778,7 @@ struct QWidgetPaintContext
QPainter *painter;
};
+#ifndef QT_NO_GRAPHICSEFFECT
class QWidgetEffectSourcePrivate : public QGraphicsEffectSourcePrivate
{
public:
@@ -826,6 +831,7 @@ public:
QTransform lastEffectTransform;
bool updateDueToGraphicsEffect;
};
+#endif //QT_NO_GRAPHICSEFFECT
inline QWExtra *QWidgetPrivate::extraData() const
{
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index a6d8ed7..88cd63d 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -434,8 +434,10 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
drawableWindow->PointerFilter(EPointerFilterEnterExit
| EPointerFilterMove | EPointerFilterDrag, 0);
- if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
+ if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) {
activateSymbianWindow(control.data());
+ control->MakeVisible(true);
+ }
// We wait until the control is fully constructed before calling setWinId, because
// this generates a WinIdChanged event.
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index 5bf7649..22a94b9 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -2036,7 +2036,7 @@ void QWidgetPrivate::winSetupGestures()
if (!q || !q->isVisible())
return;
QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
- WId winid = q->effectiveWinId();
+ WId winid = q->internalWinId();
bool needh = false;
bool needv = false;
@@ -2052,6 +2052,8 @@ void QWidgetPrivate::winSetupGestures()
needv = (vbarpolicy == Qt::ScrollBarAlwaysOn ||
(vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum()));
singleFingerPanEnabled = asa->d_func()->singleFingerPanEnabled;
+ if (!winid)
+ winid = q->winId(); // enforces the native winid on the viewport
}
if (winid && qAppPriv->SetGestureConfig) {
GESTURECONFIG gc[1];
@@ -2071,17 +2073,6 @@ void QWidgetPrivate::winSetupGestures()
gc[0].dwBlock = GC_PAN;
}
-// gc[1].dwID = GID_ZOOM;
-// if (gestures.pinch)
-// gc[1].dwWant = GC_ZOOM;
-// else
-// gc[1].dwBlock = GC_ZOOM;
-// gc[2].dwID = GID_ROTATE;
-// if (gestures.pinch)
-// gc[2].dwWant = GC_ROTATE;
-// else
-// gc[2].dwBlock = GC_ROTATE;
-
qAppPriv->SetGestureConfig(winid, 0, sizeof(gc)/sizeof(gc[0]), gc, sizeof(gc[0]));
}
}
diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp
index 12d3058..5fceb13 100644
--- a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp
+++ b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp
@@ -56,16 +56,16 @@ QWinNativePanGestureRecognizer::QWinNativePanGestureRecognizer()
{
}
-QGesture* QWinNativePanGestureRecognizer::createGesture(QObject *target) const
+QGesture *QWinNativePanGestureRecognizer::create(QObject *target)
{
if (!target)
return new QPanGesture; // a special case
- if (qobject_cast<QGraphicsObject*>(target))
- return 0;
if (!target->isWidgetType())
return 0;
+ if (qobject_cast<QGraphicsObject *>(target))
+ return 0;
- QWidget *q = static_cast<QWidget*>(target);
+ QWidget *q = static_cast<QWidget *>(target);
QWidgetPrivate *d = q->d_func();
d->nativeGesturePanEnabled = true;
d->winSetupGestures();
@@ -73,7 +73,9 @@ QGesture* QWinNativePanGestureRecognizer::createGesture(QObject *target) const
return new QPanGesture;
}
-QGestureRecognizer::Result QWinNativePanGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event)
+QGestureRecognizer::Result QWinNativePanGestureRecognizer::recognize(QGesture *state,
+ QObject *,
+ QEvent *event)
{
QPanGesture *q = static_cast<QPanGesture*>(state);
QPanGesturePrivate *d = q->d_func();
@@ -85,26 +87,25 @@ QGestureRecognizer::Result QWinNativePanGestureRecognizer::filterEvent(QGesture
case QNativeGestureEvent::GestureBegin:
break;
case QNativeGestureEvent::Pan:
- result = QGestureRecognizer::GestureTriggered;
+ result = QGestureRecognizer::TriggerGesture;
event->accept();
break;
case QNativeGestureEvent::GestureEnd:
if (q->state() == Qt::NoGesture)
return QGestureRecognizer::Ignore; // some other gesture has ended
- result = QGestureRecognizer::GestureFinished;
+ result = QGestureRecognizer::FinishGesture;
break;
default:
return QGestureRecognizer::Ignore;
}
if (q->state() == Qt::NoGesture) {
- d->lastOffset = d->totalOffset = d->offset = QPointF();
+ d->lastOffset = d->offset = QPointF();
+ d->startPosition = ev->position;
} else {
d->lastOffset = d->offset;
- d->offset = QPointF(ev->position.x() - d->lastPosition.x(),
- ev->position.y() - d->lastPosition.y());
- d->totalOffset += d->offset;
+ d->offset = QPointF(ev->position.x() - d->startPosition.x(),
+ ev->position.y() - d->startPosition.y());
}
- d->lastPosition = ev->position;
}
return result;
}
@@ -114,8 +115,8 @@ void QWinNativePanGestureRecognizer::reset(QGesture *state)
QPanGesture *pan = static_cast<QPanGesture*>(state);
QPanGesturePrivate *d = pan->d_func();
- d->totalOffset = d->lastOffset = d->offset = QPointF();
- d->lastPosition = QPoint();
+ d->lastOffset = d->offset = QPointF();
+ d->startPosition = QPoint();
d->acceleration = 0;
QGestureRecognizer::reset(state);
diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h
index a1e8511..8fb0d50 100644
--- a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h
+++ b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h
@@ -62,9 +62,8 @@ class QWinNativePanGestureRecognizer : public QGestureRecognizer
public:
QWinNativePanGestureRecognizer();
- QGesture* createGesture(QObject *target) const;
-
- QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event);
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event);
void reset(QGesture *state);
};
diff --git a/src/gui/math3d/qgenericmatrix.cpp b/src/gui/math3d/qgenericmatrix.cpp
index d211229..aa98536 100644
--- a/src/gui/math3d/qgenericmatrix.cpp
+++ b/src/gui/math3d/qgenericmatrix.cpp
@@ -80,7 +80,7 @@ QT_BEGIN_NAMESPACE
The contents of the array \a values is assumed to be in
row-major order.
- \sa toValueArray()
+ \sa copyDataTo()
*/
/*!
@@ -102,11 +102,11 @@ QT_BEGIN_NAMESPACE
Returns true if this matrix is the identity; false otherwise.
- \sa setIdentity()
+ \sa setToIdentity()
*/
/*!
- \fn void QGenericMatrix::setIdentity()
+ \fn void QGenericMatrix::setToIdentity()
Sets this matrix to the identity.
@@ -213,9 +213,9 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn void QGenericMatrix::toValueArray(T *values)
+ \fn void QGenericMatrix::copyDataTo(T *values) const
- Retrieves the N * M items in this matrix and writes them to \a values
+ Retrieves the N * M items in this matrix and copies them to \a values
in row-major order.
*/
@@ -243,4 +243,100 @@ QT_BEGIN_NAMESPACE
\sa data()
*/
+#ifndef QT_NO_DATASTREAM
+
+/*!
+ \fn QDataStream &operator<<(QDataStream &stream, const QGenericMatrix<N, M, T> &matrix)
+ \relates QGenericMatrix
+
+ Writes the given \a matrix to the given \a stream and returns a
+ reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &stream, QGenericMatrix<N, M, T> &matrix)
+ \relates QGenericMatrix
+
+ Reads a NxM matrix from the given \a stream into the given \a matrix
+ and returns a reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+#endif
+
+/*!
+ \typedef QMatrix2x2
+ \relates QGenericMatrix
+
+ The QMatrix2x2 type defines a convenient instantiation of the
+ QGenericMatrix template for 2 columns, 2 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix2x3
+ \relates QGenericMatrix
+
+ The QMatrix2x3 type defines a convenient instantiation of the
+ QGenericMatrix template for 2 columns, 3 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix2x4
+ \relates QGenericMatrix
+
+ The QMatrix2x4 type defines a convenient instantiation of the
+ QGenericMatrix template for 2 columns, 4 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix3x2
+ \relates QGenericMatrix
+
+ The QMatrix3x2 type defines a convenient instantiation of the
+ QGenericMatrix template for 3 columns, 2 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix3x3
+ \relates QGenericMatrix
+
+ The QMatrix3x3 type defines a convenient instantiation of the
+ QGenericMatrix template for 3 columns, 3 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix3x4
+ \relates QGenericMatrix
+
+ The QMatrix3x4 type defines a convenient instantiation of the
+ QGenericMatrix template for 3 columns, 4 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix4x2
+ \relates QGenericMatrix
+
+ The QMatrix4x2 type defines a convenient instantiation of the
+ QGenericMatrix template for 4 columns, 2 rows, and qreal as
+ the element type.
+*/
+
+/*!
+ \typedef QMatrix4x3
+ \relates QGenericMatrix
+
+ The QMatrix4x3 type defines a convenient instantiation of the
+ QGenericMatrix template for 4 columns, 3 rows, and qreal as
+ the element type.
+*/
+
QT_END_NAMESPACE
diff --git a/src/gui/math3d/qgenericmatrix.h b/src/gui/math3d/qgenericmatrix.h
index f178d02..3871754 100644
--- a/src/gui/math3d/qgenericmatrix.h
+++ b/src/gui/math3d/qgenericmatrix.h
@@ -44,6 +44,7 @@
#include <QtCore/qmetatype.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qdatastream.h>
QT_BEGIN_HEADER
@@ -63,7 +64,7 @@ public:
T& operator()(int row, int column);
bool isIdentity() const;
- void setIdentity();
+ void setToIdentity();
void fill(T value);
@@ -76,7 +77,7 @@ public:
bool operator==(const QGenericMatrix<N, M, T>& other) const;
bool operator!=(const QGenericMatrix<N, M, T>& other) const;
- void toValueArray(T *values);
+ void copyDataTo(T *values) const;
T *data() { return m[0]; }
const T *data() const { return m[0]; }
@@ -113,7 +114,7 @@ private:
template <int N, int M, typename T>
Q_INLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix()
{
- setIdentity();
+ setToIdentity();
}
template <int N, int M, typename T>
@@ -164,7 +165,7 @@ Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::isIdentity() const
}
template <int N, int M, typename T>
-Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::setIdentity()
+Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::setToIdentity()
{
for (int col = 0; col < N; ++col) {
for (int row = 0; row < M; ++row) {
@@ -316,7 +317,7 @@ Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator/(const QGenericMatrix<N, M
}
template <int N, int M, typename T>
-Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::toValueArray(T *values)
+Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::copyDataTo(T *values) const
{
for (int col = 0; col < N; ++col)
for (int row = 0; row < M; ++row)
@@ -352,6 +353,32 @@ QDebug operator<<(QDebug dbg, const QGenericMatrix<N, M, T> &m)
#endif
+#ifndef QT_NO_DATASTREAM
+
+template <int N, int M, typename T>
+QDataStream &operator<<(QDataStream &stream, const QGenericMatrix<N, M, T> &matrix)
+{
+ for (int row = 0; row < M; ++row)
+ for (int col = 0; col < N; ++col)
+ stream << double(matrix(row, col));
+ return stream;
+}
+
+template <int N, int M, typename T>
+QDataStream &operator>>(QDataStream &stream, QGenericMatrix<N, M, T> &matrix)
+{
+ double x;
+ for (int row = 0; row < M; ++row) {
+ for (int col = 0; col < N; ++col) {
+ stream >> x;
+ matrix(row, col) = T(x);
+ }
+ }
+ return stream;
+}
+
+#endif
+
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QMatrix2x2)
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp
index 5d624d8..2c3d616 100644
--- a/src/gui/math3d/qmatrix4x4.cpp
+++ b/src/gui/math3d/qmatrix4x4.cpp
@@ -73,10 +73,10 @@ static const qreal inv_dist_to_plane = 1. / 1024.;
If the matrix has a special type (identity, translate, scale, etc),
the programmer should follow this constructor with a call to
- inferSpecialType() if they wish QMatrix4x4 to optimize further
+ optimize() if they wish QMatrix4x4 to optimize further
calls to translate(), scale(), etc.
- \sa toValueArray(), inferSpecialType()
+ \sa copyDataTo(), optimize()
*/
QMatrix4x4::QMatrix4x4(const qreal *values)
{
@@ -96,10 +96,10 @@ QMatrix4x4::QMatrix4x4(const qreal *values)
If the matrix has a special type (identity, translate, scale, etc),
the programmer should follow this constructor with a call to
- inferSpecialType() if they wish QMatrix4x4 to optimize further
+ optimize() if they wish QMatrix4x4 to optimize further
calls to translate(), scale(), etc.
- \sa inferSpecialType()
+ \sa optimize()
*/
#if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC)
@@ -176,10 +176,10 @@ QMatrix4x4::QMatrix4x4(const qreal *values, int cols, int rows)
If \a matrix has a special type (identity, translate, scale, etc),
the programmer should follow this constructor with a call to
- inferSpecialType() if they wish QMatrix4x4 to optimize further
+ optimize() if they wish QMatrix4x4 to optimize further
calls to translate(), scale(), etc.
- \sa toAffine(), inferSpecialType()
+ \sa toAffine(), optimize()
*/
QMatrix4x4::QMatrix4x4(const QMatrix& matrix)
{
@@ -208,10 +208,10 @@ QMatrix4x4::QMatrix4x4(const QMatrix& matrix)
If \a transform has a special type (identity, translate, scale, etc),
the programmer should follow this constructor with a call to
- inferSpecialType() if they wish QMatrix4x4 to optimize further
+ optimize() if they wish QMatrix4x4 to optimize further
calls to translate(), scale(), etc.
- \sa toTransform(), inferSpecialType()
+ \sa toTransform(), optimize()
*/
QMatrix4x4::QMatrix4x4(const QTransform& transform)
{
@@ -249,7 +249,7 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform)
Returns a reference to the element at position (\a row, \a column)
in this matrix so that the element can be assigned to.
- \sa inferSpecialType(), setColumn(), setRow()
+ \sa optimize(), setColumn(), setRow()
*/
/*!
@@ -289,11 +289,11 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform)
Returns true if this matrix is the identity; false otherwise.
- \sa setIdentity()
+ \sa setToIdentity()
*/
/*!
- \fn void QMatrix4x4::setIdentity()
+ \fn void QMatrix4x4::setToIdentity()
Sets this matrix to the identity.
@@ -694,11 +694,11 @@ QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor)
/*!
Multiplies this matrix by another that scales coordinates by
- the components of \a vector. Returns this matrix.
+ the components of \a vector.
\sa translate(), rotate()
*/
-QMatrix4x4& QMatrix4x4::scale(const QVector3D& vector)
+void QMatrix4x4::scale(const QVector3D& vector)
{
qreal vx = vector.x();
qreal vy = vector.y();
@@ -732,7 +732,6 @@ QMatrix4x4& QMatrix4x4::scale(const QVector3D& vector)
m[2][3] *= vz;
flagBits = General;
}
- return *this;
}
#endif
@@ -740,11 +739,11 @@ QMatrix4x4& QMatrix4x4::scale(const QVector3D& vector)
\overload
Multiplies this matrix by another that scales coordinates by the
- components \a x, and \a y. Returns this matrix.
+ components \a x, and \a y.
\sa translate(), rotate()
*/
-QMatrix4x4& QMatrix4x4::scale(qreal x, qreal y)
+void QMatrix4x4::scale(qreal x, qreal y)
{
if (flagBits == Identity) {
m[0][0] = x;
@@ -768,18 +767,17 @@ QMatrix4x4& QMatrix4x4::scale(qreal x, qreal y)
m[1][3] *= y;
flagBits = General;
}
- return *this;
}
/*!
\overload
Multiplies this matrix by another that scales coordinates by the
- components \a x, \a y, and \a z. Returns this matrix.
+ components \a x, \a y, and \a z.
\sa translate(), rotate()
*/
-QMatrix4x4& QMatrix4x4::scale(qreal x, qreal y, qreal z)
+void QMatrix4x4::scale(qreal x, qreal y, qreal z)
{
if (flagBits == Identity) {
m[0][0] = x;
@@ -810,18 +808,17 @@ QMatrix4x4& QMatrix4x4::scale(qreal x, qreal y, qreal z)
m[2][3] *= z;
flagBits = General;
}
- return *this;
}
/*!
\overload
Multiplies this matrix by another that scales coordinates by the
- given \a factor. Returns this matrix.
+ given \a factor.
\sa translate(), rotate()
*/
-QMatrix4x4& QMatrix4x4::scale(qreal factor)
+void QMatrix4x4::scale(qreal factor)
{
if (flagBits == Identity) {
m[0][0] = factor;
@@ -852,17 +849,16 @@ QMatrix4x4& QMatrix4x4::scale(qreal factor)
m[2][3] *= factor;
flagBits = General;
}
- return *this;
}
#ifndef QT_NO_VECTOR3D
/*!
Multiplies this matrix by another that translates coordinates by
- the components of \a vector. Returns this matrix.
+ the components of \a vector.
\sa scale(), rotate()
*/
-QMatrix4x4& QMatrix4x4::translate(const QVector3D& vector)
+void QMatrix4x4::translate(const QVector3D& vector)
{
qreal vx = vector.x();
qreal vy = vector.y();
@@ -895,7 +891,6 @@ QMatrix4x4& QMatrix4x4::translate(const QVector3D& vector)
else if (flagBits != (Rotation | Translation))
flagBits = General;
}
- return *this;
}
#endif
@@ -904,11 +899,11 @@ QMatrix4x4& QMatrix4x4::translate(const QVector3D& vector)
\overload
Multiplies this matrix by another that translates coordinates
- by the components \a x, and \a y. Returns this matrix.
+ by the components \a x, and \a y.
\sa scale(), rotate()
*/
-QMatrix4x4& QMatrix4x4::translate(qreal x, qreal y)
+void QMatrix4x4::translate(qreal x, qreal y)
{
if (flagBits == Identity) {
m[3][0] = x;
@@ -935,18 +930,17 @@ QMatrix4x4& QMatrix4x4::translate(qreal x, qreal y)
else if (flagBits != (Rotation | Translation))
flagBits = General;
}
- return *this;
}
/*!
\overload
Multiplies this matrix by another that translates coordinates
- by the components \a x, \a y, and \a z. Returns this matrix.
+ by the components \a x, \a y, and \a z.
\sa scale(), rotate()
*/
-QMatrix4x4& QMatrix4x4::translate(qreal x, qreal y, qreal z)
+void QMatrix4x4::translate(qreal x, qreal y, qreal z)
{
if (flagBits == Identity) {
m[3][0] = x;
@@ -976,20 +970,19 @@ QMatrix4x4& QMatrix4x4::translate(qreal x, qreal y, qreal z)
else if (flagBits != (Rotation | Translation))
flagBits = General;
}
- return *this;
}
#ifndef QT_NO_VECTOR3D
/*!
Multiples this matrix by another that rotates coordinates through
- \a angle degrees about \a vector. Returns this matrix.
+ \a angle degrees about \a vector.
\sa scale(), translate()
*/
-QMatrix4x4& QMatrix4x4::rotate(qreal angle, const QVector3D& vector)
+void QMatrix4x4::rotate(qreal angle, const QVector3D& vector)
{
- return rotate(angle, vector.x(), vector.y(), vector.z());
+ rotate(angle, vector.x(), vector.y(), vector.z());
}
#endif
@@ -998,14 +991,14 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, const QVector3D& vector)
\overload
Multiplies this matrix by another that rotates coordinates through
- \a angle degrees about the vector (\a x, \a y, \a z). Returns this matrix.
+ \a angle degrees about the vector (\a x, \a y, \a z).
\sa scale(), translate()
*/
-QMatrix4x4& QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
+void QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
{
if (angle == 0.0f)
- return *this;
+ return;
QMatrix4x4 m(1); // The "1" says to not load the identity.
qreal c, s, ic;
if (angle == 90.0f || angle == -270.0f) {
@@ -1027,7 +1020,7 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
if (y == 0.0f) {
if (z != 0.0f) {
// Rotate around the Z axis.
- m.setIdentity();
+ m.setToIdentity();
m.m[0][0] = c;
m.m[1][1] = c;
if (z < 0.0f) {
@@ -1042,7 +1035,7 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
}
} else if (z == 0.0f) {
// Rotate around the Y axis.
- m.setIdentity();
+ m.setToIdentity();
m.m[0][0] = c;
m.m[2][2] = c;
if (y < 0.0f) {
@@ -1057,7 +1050,7 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
}
} else if (y == 0.0f && z == 0.0f) {
// Rotate around the X axis.
- m.setIdentity();
+ m.setToIdentity();
m.m[1][1] = c;
m.m[2][2] = c;
if (x < 0.0f) {
@@ -1102,18 +1095,17 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
flagBits = flags | Rotation;
else
flagBits = Rotation;
- return *this;
}
/*!
\internal
*/
-QMatrix4x4& QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
+void QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
{
// Used by QGraphicsRotation::applyTo() to perform a rotation
// and projection back to 2D in a single step.
if (angle == 0.0f)
- return *this;
+ return;
QMatrix4x4 m(1); // The "1" says to not load the identity.
qreal c, s, ic;
if (angle == 90.0f || angle == -270.0f) {
@@ -1135,7 +1127,7 @@ QMatrix4x4& QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
if (y == 0.0f) {
if (z != 0.0f) {
// Rotate around the Z axis.
- m.setIdentity();
+ m.setToIdentity();
m.m[0][0] = c;
m.m[1][1] = c;
if (z < 0.0f) {
@@ -1150,7 +1142,7 @@ QMatrix4x4& QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
}
} else if (z == 0.0f) {
// Rotate around the Y axis.
- m.setIdentity();
+ m.setToIdentity();
m.m[0][0] = c;
m.m[2][2] = 1.0f;
if (y < 0.0f) {
@@ -1163,7 +1155,7 @@ QMatrix4x4& QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
}
} else if (y == 0.0f && z == 0.0f) {
// Rotate around the X axis.
- m.setIdentity();
+ m.setToIdentity();
m.m[1][1] = c;
m.m[2][2] = 1.0f;
if (x < 0.0f) {
@@ -1206,7 +1198,6 @@ QMatrix4x4& QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
flagBits = flags | Rotation;
else
flagBits = Rotation;
- return *this;
}
#ifndef QT_NO_QUATERNION
@@ -1214,11 +1205,11 @@ QMatrix4x4& QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
/*!
Multiples this matrix by another that rotates coordinates according
to a specified \a quaternion. The \a quaternion is assumed to have
- been normalized. Returns this matrix.
+ been normalized.
\sa scale(), translate(), QQuaternion
*/
-QMatrix4x4& QMatrix4x4::rotate(const QQuaternion& quaternion)
+void QMatrix4x4::rotate(const QQuaternion& quaternion)
{
// Algorithm from:
// http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54
@@ -1254,7 +1245,6 @@ QMatrix4x4& QMatrix4x4::rotate(const QQuaternion& quaternion)
flagBits = flags | Rotation;
else
flagBits = Rotation;
- return *this;
}
#endif
@@ -1265,17 +1255,16 @@ QMatrix4x4& QMatrix4x4::rotate(const QQuaternion& quaternion)
Multiplies this matrix by another that applies an orthographic
projection for a window with boundaries specified by \a rect.
The near and far clipping planes will be -1 and 1 respectively.
- Returns this matrix.
\sa frustum(), perspective()
*/
-QMatrix4x4& QMatrix4x4::ortho(const QRect& rect)
+void QMatrix4x4::ortho(const QRect& rect)
{
// Note: rect.right() and rect.bottom() subtract 1 in QRect,
// which gives the location of a pixel within the rectangle,
// instead of the extent of the rectangle. We want the extent.
// QRectF expresses the extent properly.
- return ortho(rect.x(), rect.x() + rect.width(), rect.y() + rect.height(), rect.y(), -1.0f, 1.0f);
+ ortho(rect.x(), rect.x() + rect.width(), rect.y() + rect.height(), rect.y(), -1.0f, 1.0f);
}
/*!
@@ -1284,28 +1273,27 @@ QMatrix4x4& QMatrix4x4::ortho(const QRect& rect)
Multiplies this matrix by another that applies an orthographic
projection for a window with boundaries specified by \a rect.
The near and far clipping planes will be -1 and 1 respectively.
- Returns this matrix.
\sa frustum(), perspective()
*/
-QMatrix4x4& QMatrix4x4::ortho(const QRectF& rect)
+void QMatrix4x4::ortho(const QRectF& rect)
{
- return ortho(rect.left(), rect.right(), rect.bottom(), rect.top(), -1.0f, 1.0f);
+ ortho(rect.left(), rect.right(), rect.bottom(), rect.top(), -1.0f, 1.0f);
}
/*!
Multiplies this matrix by another that applies an orthographic
projection for a window with lower-left corner (\a left, \a bottom),
upper-right corner (\a right, \a top), and the specified \a nearPlane
- and \a farPlane clipping planes. Returns this matrix.
+ and \a farPlane clipping planes.
\sa frustum(), perspective()
*/
-QMatrix4x4& QMatrix4x4::ortho(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane)
+void QMatrix4x4::ortho(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane)
{
// Bail out if the projection volume is zero-sized.
if (left == right || bottom == top || nearPlane == farPlane)
- return *this;
+ return;
// Construct the projection.
qreal width = right - left;
@@ -1324,7 +1312,7 @@ QMatrix4x4& QMatrix4x4::ortho(qreal left, qreal right, qreal bottom, qreal top,
(2.0f / width,
2.0f / invheight,
-1.0f));
- return *this;
+ return;
}
#endif
QMatrix4x4 m(1);
@@ -1347,22 +1335,22 @@ QMatrix4x4& QMatrix4x4::ortho(qreal left, qreal right, qreal bottom, qreal top,
// Apply the projection.
*this *= m;
- return *this;
+ return;
}
/*!
Multiplies this matrix by another that applies a perspective
frustum projection for a window with lower-left corner (\a left, \a bottom),
upper-right corner (\a right, \a top), and the specified \a nearPlane
- and \a farPlane clipping planes. Returns this matrix.
+ and \a farPlane clipping planes.
\sa ortho(), perspective()
*/
-QMatrix4x4& QMatrix4x4::frustum(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane)
+void QMatrix4x4::frustum(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane)
{
// Bail out if the projection volume is zero-sized.
if (left == right || bottom == top || nearPlane == farPlane)
- return *this;
+ return;
// Construct the projection.
QMatrix4x4 m(1);
@@ -1388,7 +1376,6 @@ QMatrix4x4& QMatrix4x4::frustum(qreal left, qreal right, qreal bottom, qreal top
// Apply the projection.
*this *= m;
- return *this;
}
/*!
@@ -1396,22 +1383,21 @@ QMatrix4x4& QMatrix4x4::frustum(qreal left, qreal right, qreal bottom, qreal top
projection. The field of view will be \a angle degrees within
a window with a given \a aspect ratio. The projection will
have the specified \a nearPlane and \a farPlane clipping planes.
- Returns this matrix.
\sa ortho(), frustum()
*/
-QMatrix4x4& QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane, qreal farPlane)
+void QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane, qreal farPlane)
{
// Bail out if the projection volume is zero-sized.
if (nearPlane == farPlane || aspect == 0.0f)
- return *this;
+ return;
// Construct the projection.
QMatrix4x4 m(1);
qreal radians = (angle / 2.0f) * M_PI / 180.0f;
qreal sine = qSin(radians);
if (sine == 0.0f)
- return *this;
+ return;
qreal cotan = qCos(radians) / sine;
qreal clip = farPlane - nearPlane;
m.m[0][0] = cotan / aspect;
@@ -1433,7 +1419,6 @@ QMatrix4x4& QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane,
// Apply the projection.
*this *= m;
- return *this;
}
#ifndef QT_NO_VECTOR3D
@@ -1443,9 +1428,8 @@ QMatrix4x4& QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane,
transformation. The \a center value indicates the center of the
view that the \a eye is looking at. The \a up value indicates
which direction should be considered up with respect to the \a eye.
- Returns this matrix.
*/
-QMatrix4x4& QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up)
+void QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up)
{
QVector3D forward = (center - eye).normalized();
QVector3D side = QVector3D::crossProduct(forward, up).normalized();
@@ -1471,7 +1455,7 @@ QMatrix4x4& QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, co
m.m[3][3] = 1.0f;
*this *= m;
- return translate(-eye);
+ translate(-eye);
}
#endif
@@ -1480,11 +1464,11 @@ QMatrix4x4& QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, co
Flips between right-handed and left-handed coordinate systems
by multiplying the y and z co-ordinates by -1. This is normally
used to create a left-handed orthographic view without scaling
- the viewport as ortho() does. Returns this matrix.
+ the viewport as ortho() does.
\sa ortho()
*/
-QMatrix4x4& QMatrix4x4::flipCoordinates()
+void QMatrix4x4::flipCoordinates()
{
if (flagBits == Scale || flagBits == (Scale | Translation)) {
m[1][1] = -m[1][1];
@@ -1508,14 +1492,13 @@ QMatrix4x4& QMatrix4x4::flipCoordinates()
m[2][3] = -m[2][3];
flagBits = General;
}
- return *this;
}
/*!
- Retrieves the 16 items in this matrix and writes them to \a values
+ Retrieves the 16 items in this matrix and copies them to \a values
in row-major order.
*/
-void QMatrix4x4::toValueArray(qreal *values) const
+void QMatrix4x4::copyDataTo(qreal *values) const
{
for (int row = 0; row < 4; ++row)
for (int col = 0; col < 4; ++col)
@@ -1739,7 +1722,7 @@ QRectF QMatrix4x4::mapRect(const QRectF& rect) const
Returns a pointer to the raw data of this matrix.
- \sa constData(), inferSpecialType()
+ \sa constData(), optimize()
*/
/*!
@@ -1788,94 +1771,8 @@ QMatrix4x4 QMatrix4x4::orthonormalInverse() const
return result;
}
-#ifndef QT_NO_VECTOR3D
-/*!
- Decomposes the current rotation matrix into an \a axis of rotation plus
- an \a angle. The result can be used to construct an equivalent rotation
- matrix using glRotate(). It is assumed that the homogenous coordinate
- is 1.0. The returned vector is guaranteed to be normalized.
-
- \code
- qreal angle;
- QVector3D axis;
-
- matrix.extractAxisAngle(angle, axis);
- glRotate(angle, axis[0], axis[1], axis[2]);
- \endcode
-
- \sa rotate()
-*/
-void QMatrix4x4::extractAxisRotation(qreal &angle, QVector3D &axis) const
-{
- // Orientation is dependent on the upper 3x3 matrix; subtract the
- // homogeneous scaling element from the trace of the 4x4 matrix
- qreal tr = m[0][0] + m[1][1] + m[2][2];
- qreal cosa = qreal(0.5f * (tr - 1.0f));
- angle = acos(cosa) * 180.0f / M_PI;
-
- // Any axis will work if r is zero (means no rotation)
- if (qFuzzyIsNull(angle)) {
- axis.setX(1.0f);
- axis.setY(0.0f);
- axis.setZ(0.0f);
- return;
- }
-
- if (angle < 180.0f) {
- axis.setX(m[1][2] - m[2][1]);
- axis.setY(m[2][0] - m[0][2]);
- axis.setZ(m[0][1] - m[1][0]);
- axis.normalize();
- return;
- }
-
- // rads == PI
- qreal tmp;
-
- // r00 is maximum
- if ((m[0][0] >= m[2][2]) && (m[0][0] >= m[1][1])) {
- axis.setX(0.5f * qSqrt(m[0][0] - m[1][1] - m[2][2] + 1.0f));
- tmp = 0.5f / axis.x();
- axis.setY(m[1][0] * tmp);
- axis.setZ(m[2][0] * tmp);
- }
-
- // r11 is maximum
- if ((m[1][1] >= m[2][2]) && (m[1][1] >= m[0][0])) {
- axis.setY(0.5f * qSqrt(m[1][1] - m[0][0] - m[2][2] + 1.0f));
- tmp = 0.5f / axis.y();
- axis.setX(tmp * m[1][0]);
- axis.setZ(tmp * m[2][1]);
- }
-
- // r22 is maximum
- if ((m[2][2] >= m[1][1]) && (m[2][2] >= m[0][0])) {
- axis.setZ(0.5f * qSqrt(m[2][2] - m[0][0] - m[1][1] + 1.0f));
- tmp = 0.5f / axis.z();
- axis.setX(m[2][0]*tmp);
- axis.setY(m[2][1]*tmp);
- }
-}
-
-/*!
- If this is an orthonormal transformation matrix (e.g. only rotations and
- translations have been applied to the matrix, no scaling, or shearing)
- then the world translational component can be obtained by calling this function.
-
- This is most useful for camera matrices, where the negation of this vector
- is effectively the camera world coordinates.
-*/
-QVector3D QMatrix4x4::extractTranslation() const
-{
- return QVector3D
- (m[0][0] * m[3][0] + m[0][1] * m[3][1] + m[0][2] * m[3][2],
- m[1][0] * m[3][0] + m[1][1] * m[3][1] + m[1][2] * m[3][2],
- m[2][0] * m[3][0] + m[2][1] * m[3][1] + m[2][2] * m[3][2]);
-}
-#endif
-
/*!
- Infers the special type of this matrix from its current elements.
+ Optimize the usage of this matrix from its current elements.
Some operations such as translate(), scale(), and rotate() can be
performed more efficiently if the matrix being modified is already
@@ -1888,13 +1785,13 @@ QVector3D QMatrix4x4::extractTranslation() const
the special type and will revert to the safest but least efficient
operations thereafter.
- By calling inferSpecialType() after directly modifying the matrix,
+ By calling optimize() after directly modifying the matrix,
the programmer can force QMatrix4x4 to recover the special type if
the elements appear to conform to one of the known optimized types.
\sa operator()(), data(), translate()
*/
-void QMatrix4x4::inferSpecialType()
+void QMatrix4x4::optimize()
{
// If the last element is not 1, then it can never be special.
if (m[3][3] != 1.0f) {
@@ -2011,7 +1908,7 @@ QDataStream &operator>>(QDataStream &stream, QMatrix4x4 &matrix)
matrix(row, col) = qreal(x);
}
}
- matrix.inferSpecialType();
+ matrix.optimize();
return stream;
}
diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h
index ba74b89..4193bdc 100644
--- a/src/gui/math3d/qmatrix4x4.h
+++ b/src/gui/math3d/qmatrix4x4.h
@@ -63,7 +63,7 @@ class QVariant;
class Q_GUI_EXPORT QMatrix4x4
{
public:
- inline QMatrix4x4() { setIdentity(); }
+ inline QMatrix4x4() { setToIdentity(); }
explicit QMatrix4x4(const qreal *values);
inline QMatrix4x4(qreal m11, qreal m12, qreal m13, qreal m14,
qreal m21, qreal m22, qreal m23, qreal m24,
@@ -87,7 +87,7 @@ public:
inline void setRow(int index, const QVector4D& value);
inline bool isIdentity() const;
- inline void setIdentity();
+ inline void setToIdentity();
inline void fill(qreal value);
@@ -127,36 +127,31 @@ public:
friend inline bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2);
#ifndef QT_NO_VECTOR3D
- QMatrix4x4& scale(const QVector3D& vector);
- QMatrix4x4& translate(const QVector3D& vector);
- QMatrix4x4& rotate(qreal angle, const QVector3D& vector);
+ void scale(const QVector3D& vector);
+ void translate(const QVector3D& vector);
+ void rotate(qreal angle, const QVector3D& vector);
#endif
- QMatrix4x4& scale(qreal x, qreal y);
- QMatrix4x4& scale(qreal x, qreal y, qreal z);
- QMatrix4x4& scale(qreal factor);
- QMatrix4x4& translate(qreal x, qreal y);
- QMatrix4x4& translate(qreal x, qreal y, qreal z);
- QMatrix4x4& rotate(qreal angle, qreal x, qreal y, qreal z = 0.0f);
+ void scale(qreal x, qreal y);
+ void scale(qreal x, qreal y, qreal z);
+ void scale(qreal factor);
+ void translate(qreal x, qreal y);
+ void translate(qreal x, qreal y, qreal z);
+ void rotate(qreal angle, qreal x, qreal y, qreal z = 0.0f);
#ifndef QT_NO_QUATERNION
- QMatrix4x4& rotate(const QQuaternion& quaternion);
+ void rotate(const QQuaternion& quaternion);
#endif
+ void ortho(const QRect& rect);
+ void ortho(const QRectF& rect);
+ void ortho(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
+ void frustum(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
+ void perspective(qreal angle, qreal aspect, qreal nearPlane, qreal farPlane);
#ifndef QT_NO_VECTOR3D
- void extractAxisRotation(qreal &angle, QVector3D &axis) const;
- QVector3D extractTranslation() const;
+ void lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up);
#endif
+ void flipCoordinates();
- QMatrix4x4& ortho(const QRect& rect);
- QMatrix4x4& ortho(const QRectF& rect);
- QMatrix4x4& ortho(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
- QMatrix4x4& frustum(qreal left, qreal right, qreal bottom, qreal top, qreal nearPlane, qreal farPlane);
- QMatrix4x4& perspective(qreal angle, qreal aspect, qreal nearPlane, qreal farPlane);
-#ifndef QT_NO_VECTOR3D
- QMatrix4x4& lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up);
-#endif
- QMatrix4x4& flipCoordinates();
-
- void toValueArray(qreal *values) const;
+ void copyDataTo(qreal *values) const;
QMatrix toAffine() const;
QTransform toTransform() const;
@@ -183,7 +178,7 @@ public:
inline const qreal *data() const { return m[0]; }
inline const qreal *constData() const { return m[0]; }
- void inferSpecialType();
+ void optimize();
operator QVariant() const;
@@ -208,7 +203,7 @@ private:
QMatrix4x4 orthonormalInverse() const;
- QMatrix4x4& projectedRotate(qreal angle, qreal x, qreal y, qreal z);
+ void projectedRotate(qreal angle, qreal x, qreal y, qreal z);
friend class QGraphicsRotation;
};
@@ -330,7 +325,7 @@ inline bool QMatrix4x4::isIdentity() const
return (m[3][3] == 1.0f);
}
-inline void QMatrix4x4::setIdentity()
+inline void QMatrix4x4::setToIdentity()
{
m[0][0] = 1.0f;
m[0][1] = 0.0f;
diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp
index d5ec054..626cb3c 100644
--- a/src/gui/math3d/qquaternion.cpp
+++ b/src/gui/math3d/qquaternion.cpp
@@ -288,7 +288,7 @@ void QQuaternion::normalize()
in 3D space. The following code:
\code
- QVector3D result = q.rotateVector(vector);
+ QVector3D result = q.rotatedVector(vector);
\endcode
is equivalent to the following:
@@ -297,7 +297,7 @@ void QQuaternion::normalize()
QVector3D result = (q * QQuaternion(0, vector) * q.conjugate()).vector();
\endcode
*/
-QVector3D QQuaternion::rotateVector(const QVector3D& vector) const
+QVector3D QQuaternion::rotatedVector(const QVector3D& vector) const
{
return (*this * QQuaternion(0, vector) * conjugate()).vector();
}
diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h
index 7480a5c..5b2454f 100644
--- a/src/gui/math3d/qquaternion.h
+++ b/src/gui/math3d/qquaternion.h
@@ -95,7 +95,7 @@ public:
QQuaternion conjugate() const;
- QVector3D rotateVector(const QVector3D& vector) const;
+ QVector3D rotatedVector(const QVector3D& vector) const;
QQuaternion &operator+=(const QQuaternion &quaternion);
QQuaternion &operator-=(const QQuaternion &quaternion);
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index f36470a..8226797 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -529,7 +529,9 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up
Q_ASSERT(widget->window() == tlw);
Q_ASSERT(!rgn.isEmpty());
+#ifndef QT_NO_GRAPHICSEFFECT
widget->d_func()->invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
if (widget->d_func()->paintOnScreen()) {
if (widget->d_func()->dirty.isEmpty()) {
@@ -559,9 +561,11 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up
if (invalidateBuffer) {
const bool eventAlreadyPosted = !dirty.isEmpty();
+#ifndef QT_NO_GRAPHICSEFFECT
if (widget->d_func()->graphicsEffect)
dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()).translated(offset);
else
+#endif //QT_NO_GRAPHICSEFFECT
dirty += rgn.translated(offset);
if (!eventAlreadyPosted || updateImmediately)
sendUpdateRequest(tlw, updateImmediately);
@@ -576,9 +580,11 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up
if (widget->d_func()->inDirtyList) {
if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) {
+#ifndef QT_NO_GRAPHICSEFFECT
if (widget->d_func()->graphicsEffect)
widget->d_func()->dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect());
else
+#endif //QT_NO_GRAPHICSEFFECT
widget->d_func()->dirty += rgn;
}
} else {
@@ -606,7 +612,9 @@ void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, bool upd
Q_ASSERT(widget->window() == tlw);
Q_ASSERT(!rect.isEmpty());
+#ifndef QT_NO_GRAPHICSEFFECT
widget->d_func()->invalidateGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
if (widget->d_func()->paintOnScreen()) {
if (widget->d_func()->dirty.isEmpty()) {
diff --git a/src/gui/painting/qbackingstore_p.h b/src/gui/painting/qbackingstore_p.h
index 3288dae..fbef980 100644
--- a/src/gui/painting/qbackingstore_p.h
+++ b/src/gui/painting/qbackingstore_p.h
@@ -146,9 +146,11 @@ private:
{
if (widget && !widget->d_func()->inDirtyList && !widget->data->in_destructor) {
QWidgetPrivate *widgetPrivate = widget->d_func();
+#ifndef QT_NO_GRAPHICSEFFECT
if (widgetPrivate->graphicsEffect)
widgetPrivate->dirty = widgetPrivate->effectiveRectFor(rgn.boundingRect());
else
+#endif //QT_NO_GRAPHICSEFFECT
widgetPrivate->dirty = rgn;
dirtyWidgets.append(widget);
widgetPrivate->inDirtyList = true;
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index f8dd424..8737f10 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -223,11 +223,23 @@ void qt_scale_image_16bit(uchar *destPixels, int dbpl,
int h = ty2 - ty1;
int w = tx2 - tx1;
- const int dstx = qCeil((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix) - 1;
- const int dsty = qCeil((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy) - 1;
+ quint32 basex;
+ quint32 srcy;
- quint32 basex = quint32((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx;
- quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty;
+ if (sx < 0) {
+ int dstx = qFloor((tx1 + 0.5 - targetRect.right()) * ix) + 1;
+ basex = quint32(srcRect.right() * 65536) + dstx;
+ } else {
+ int dstx = qCeil((tx1 + 0.5 - targetRect.left()) * ix) - 1;
+ basex = quint32(srcRect.left() * 65536) + dstx;
+ }
+ if (sy < 0) {
+ int dsty = qFloor((ty1 + 0.5 - targetRect.bottom()) * iy) + 1;
+ srcy = quint32(srcRect.bottom() * 65536) + dsty;
+ } else {
+ int dsty = qCeil((ty1 + 0.5 - targetRect.top()) * iy) - 1;
+ srcy = quint32(srcRect.top() * 65536) + dsty;
+ }
quint16 *dst = ((quint16 *) (destPixels + ty1 * dbpl)) + tx1;
@@ -723,11 +735,23 @@ template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
int h = ty2 - ty1;
int w = tx2 - tx1;
- const int dstx = qCeil((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix) - 1;
- const int dsty = qCeil((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy) - 1;
+ quint32 basex;
+ quint32 srcy;
- quint32 basex = quint32((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx;
- quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty;
+ if (sx < 0) {
+ int dstx = qFloor((tx1 + 0.5 - targetRect.right()) * ix) + 1;
+ basex = quint32(srcRect.right() * 65536) + dstx;
+ } else {
+ int dstx = qCeil((tx1 + 0.5 - targetRect.left()) * ix) - 1;
+ basex = quint32(srcRect.left() * 65536) + dstx;
+ }
+ if (sy < 0) {
+ int dsty = qFloor((ty1 + 0.5 - targetRect.bottom()) * iy) + 1;
+ srcy = quint32(srcRect.bottom() * 65536) + dsty;
+ } else {
+ int dsty = qCeil((ty1 + 0.5 - targetRect.top()) * iy) - 1;
+ srcy = quint32(srcRect.top() * 65536) + dsty;
+ }
quint32 *dst = ((quint32 *) (destPixels + ty1 * dbpl)) + tx1;
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index cbfbba6..6f5d892 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -970,7 +970,29 @@ bool QBrush::operator==(const QBrush &b) const
QDebug operator<<(QDebug dbg, const QBrush &b)
{
#ifndef Q_BROKEN_DEBUG_STREAM
- dbg.nospace() << "QBrush(" << b.color() << ',' << b.style() << ')';
+ char *BRUSH_STYLES[] = {
+ "NoBrush",
+ "SolidPattern",
+ "Dense1Pattern",
+ "Dense2Pattern",
+ "Dense3Pattern",
+ "Dense4Pattern",
+ "Dense5Pattern",
+ "Dense6Pattern",
+ "Dense7Pattern",
+ "HorPattern",
+ "VerPattern",
+ "CrossPattern",
+ "BDiagPattern",
+ "FDiagPattern",
+ "DiagCrossPattern",
+ "LinearGradientPattern",
+ "RadialGradientPattern",
+ "ConicalGradientPattern",
+ "TexturePattern"
+ };
+
+ dbg.nospace() << "QBrush(" << b.color() << ',' << BRUSH_STYLES[b.style()] << ')';
return dbg.space();
#else
qWarning("This compiler doesn't support streaming QBrush to QDebug");
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 53edbb0..4df7f8a 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -2386,12 +2386,12 @@ static void QT_FASTCALL comp_func_HardLight(uint *dest, const uint *src, int len
}
/*
- if 2.Sca < Sa
- Dca' = Dca.(Sa - (1 - Dca/Da).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa)
- otherwise if 8.Dca <= Da
- Dca' = Dca.(Sa - (1 - Dca/Da).(2.Sca - Sa).(3 - 8.Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa)
- otherwise
- Dca' = (Dca.Sa + ((Dca/Da)^(0.5).Da - Dca).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa)
+ if 2.Sca <= Sa
+ Dca' = Dca.(Sa + (2.Sca - Sa).(1 - Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa)
+ otherwise if 2.Sca > Sa and 4.Dca <= Da
+ Dca' = Dca.Sa + Da.(2.Sca - Sa).(4.Dca/Da.(4.Dca/Da + 1).(Dca/Da - 1) + 7.Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
+ otherwise if 2.Sca > Sa and 4.Dca > Da
+ Dca' = Dca.Sa + Da.(2.Sca - Sa).((Dca/Da)^0.5 - Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
*/
static inline int soft_light_op(int dst, int src, int da, int sa)
{
@@ -2400,13 +2400,11 @@ static inline int soft_light_op(int dst, int src, int da, int sa)
const int temp = (src * (255 - da) + dst * (255 - sa)) * 255;
if (src2 < sa)
- return (dst * ((sa * 255) - (255 - dst_np) * (src2 - sa)) + temp) / 65025;
- else if (8 * dst <= da)
- return (dst * ((sa * 255) - ((255 - dst_np) * (src2 - sa) * ((3 * 255) - 8 * dst_np)) / 255) + temp) / 65025;
+ return (dst * (sa * 255 + (src2 - sa) * (255 - dst_np)) + temp) / 65025;
+ else if (4 * dst <= da)
+ return (dst * sa * 255 + da * (src2 - sa) * ((((16 * dst_np - 12 * 255) * dst_np + 3 * 65025) * dst_np) / 65025) + temp) / 65025;
else {
- // sqrt is too expensive to do three times per pixel, so skipping it for now
- // a future possibility is to use a LUT
- return ((dst * sa * 255) + (int(dst_np) * da - (dst * 255)) * (src2 - sa) + temp) / 65025;
+ return (dst * sa * 255 + da * (src2 - sa) * (int(sqrt(qreal(dst_np * 255))) - dst_np) + temp) / 65025;
}
}
@@ -7424,6 +7422,14 @@ QT_RECTFILL(qrgb444)
QT_RECTFILL(qargb4444)
#undef QT_RECTFILL
+inline static void qt_rectfill_nonpremul_quint32(QRasterBuffer *rasterBuffer,
+ int x, int y, int width, int height,
+ quint32 color)
+{
+ qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
+ INV_PREMUL(color), x, y, width, height, rasterBuffer->bytesPerLine());
+}
+
// Map table for destination image format. Contains function pointers
// for blends of various types unto the destination
@@ -7466,7 +7472,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
qt_bitmapblit_quint32,
qt_alphamapblit_quint32,
qt_alphargbblit_quint32,
- qt_rectfill_quint32
+ qt_rectfill_nonpremul_quint32
},
// Format_ARGB32_Premultiplied
{
diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp
index 6b9d77c..b8700c3 100644
--- a/src/gui/painting/qpaintbuffer.cpp
+++ b/src/gui/painting/qpaintbuffer.cpp
@@ -48,7 +48,7 @@
#include <QDebug>
-//#define QPAINTBUFFER_DEBUG_DRAW
+// #define QPAINTBUFFER_DEBUG_DRAW
QT_BEGIN_NAMESPACE
@@ -247,23 +247,24 @@ void QPaintBuffer::draw(QPainter *painter, int frame) const
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << "QPaintBuffer::draw() --------------------------------";
-// printf("Float buffer:");
-// for (int i=0; i<d->floats.size(); i++) {
-// if ((i % 10) == 0) {
-// printf("\n%4d-%4d: ", i, i+9);
-// }
-// printf("%4.2f ", d->floats[i]);
-// }
-// printf("\n");
-
-// printf("Int Buffer:");
-// for (int i=0; i<d->ints.size(); i++) {
-// if ((i % 10) == 0) {
-// printf("\n%4d-%4d: ", i, i+10);
-// }
-// printf("%5d", d->ints[i]);
-// }
-// printf("\n");
+ Q_D(const QPaintBuffer);
+ printf("Float buffer:");
+ for (int i=0; i<d->floats.size(); i++) {
+ if ((i % 10) == 0) {
+ printf("\n%4d-%4d: ", i, i+9);
+ }
+ printf("%4.2f ", d->floats[i]);
+ }
+ printf("\n");
+
+ printf("Int Buffer:");
+ for (int i=0; i<d->ints.size(); i++) {
+ if ((i % 10) == 0) {
+ printf("\n%4d-%4d: ", i, i+10);
+ }
+ printf("%5d", d->ints[i]);
+ }
+ printf("\n");
#endif
if (painter && !painter->isActive())
@@ -406,16 +407,17 @@ void QPaintBufferEngine::clipEnabledChanged()
void QPaintBufferEngine::penChanged()
{
-#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine:" << state()->pen;
-#endif
const QPen &pen = state()->pen;
if (!buffer->commands.isEmpty()
&& buffer->commands.last().id == QPaintBufferPrivate::Cmd_SetPen) {
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << "QPaintBufferEngine: penChanged (compressed)" << state()->pen;
+#endif
buffer->variants[buffer->commands.last().offset] = pen;
return;
}
+
if (buffer->calculateBoundingRect) {
if (pen.style() == Qt::NoPen) {
buffer->penWidthAdjustment = 0;
@@ -427,22 +429,28 @@ void QPaintBufferEngine::penChanged()
buffer->penWidthAdjustment = transformedWidth.x() / 2.0;
}
}
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << "QPaintBufferEngine: penChanged" << state()->pen;
+#endif
buffer->addCommand(QPaintBufferPrivate::Cmd_SetPen, pen);
}
void QPaintBufferEngine::brushChanged()
{
-#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine:" << state()->brush;
-#endif
const QBrush &brush = state()->brush;
if (!buffer->commands.isEmpty()
&& buffer->commands.last().id == QPaintBufferPrivate::Cmd_SetBrush) {
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << "QPaintBufferEngine: brushChanged (compressed)" << state()->brush;
+#endif
buffer->variants[buffer->commands.last().offset] = brush;
return;
}
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << "QPaintBufferEngine: brushChanged" << state()->brush;
+#endif
buffer->addCommand(QPaintBufferPrivate::Cmd_SetBrush, brush);
}
@@ -488,14 +496,14 @@ void QPaintBufferEngine::transformChanged()
if (!buffer->commands.isEmpty()
&& buffer->commands.last().id == QPaintBufferPrivate::Cmd_SetTransform) {
#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine: compressing " << state()->matrix;
+ qDebug() << "QPaintBufferEngine: transformChanged (compressing) " << state()->matrix;
#endif
buffer->variants[buffer->commands.last().offset] = state()->matrix;
return;
}
#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine: " << state()->matrix;
+ qDebug() << "QPaintBufferEngine: transformChanged:" << state()->matrix;
#endif
buffer->addCommand(QPaintBufferPrivate::Cmd_SetTransform, state()->matrix);
}
@@ -514,7 +522,18 @@ void QPaintBufferEngine::draw(const QVectorPath &path)
#ifdef QPAINTBUFFER_DEBUG_DRAW
qDebug() << "QPaintBufferEngine: draw vpath:" << path.elementCount();
#endif
- buffer->addCommand(QPaintBufferPrivate::Cmd_DrawVectorPath, path);
+
+ bool hasBrush = qbrush_style(state()->brush) != Qt::NoBrush;
+ bool hasPen = qpen_style(state()->pen) != Qt::NoPen
+ && qbrush_style(qpen_brush(state()->pen)) != Qt::NoBrush;
+
+ if (hasPen || hasBrush)
+ buffer->addCommand(QPaintBufferPrivate::Cmd_DrawVectorPath, path);
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ else
+ qDebug() << " - no pen or brush active, discarded...\n";
+#endif
+
// if (buffer->calculateBoundingRect) {
// QRealRect r = path.controlPointRect();
// buffer->updateBoundingRect(QRectF(r.x1, r.y1, r.x2 - r.x1, r.y2 - r.y1));
@@ -745,15 +764,15 @@ void QPaintBufferEngine::drawEllipse(const QRect &r)
void QPaintBufferEngine::drawPath(const QPainterPath &path)
{
-#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << "QPaintBufferEngine: drawPath: element count:" << path.elementCount();
-#endif
- // ### Path -> QVariant
- // buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPath, QVariant(path));
+// #ifdef QPAINTBUFFER_DEBUG_DRAW
+// qDebug() << "QPaintBufferEngine: drawPath: element count:" << path.elementCount();
+// #endif
+// // ### Path -> QVariant
+// // buffer->addCommand(QPaintBufferPrivate::Cmd_DrawPath, QVariant(path));
QPaintEngineEx::drawPath(path);
- if (buffer->calculateBoundingRect)
- buffer->updateBoundingRect(path.boundingRect());
+// if (buffer->calculateBoundingRect)
+// buffer->updateBoundingRect(path.boundingRect());
}
void QPaintBufferEngine::drawPoints(const QPoint *points, int pointCount)
@@ -1424,10 +1443,6 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
QTextItemInt &ti = (*tiCopy)();
QString text(ti.text());
-#ifdef QPAINTBUFFER_DEBUG_DRAW
- qDebug() << " -> Cmd_DrawTextItem:" << pos << " " << text << " " << scaleFactor;
-#endif
-
QFont font(ti.font());
font.setUnderline(false);
font.setStrikeOut(false);
@@ -1439,6 +1454,10 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
justificationWidth = si.width.toReal();
qreal scaleFactor = font.d->dpi/qreal(qt_defaultDpiY());
+#ifdef QPAINTBUFFER_DEBUG_DRAW
+ qDebug() << " -> Cmd_DrawTextItem:" << pos << " " << text << " " << scaleFactor;
+#endif
+
if (scaleFactor != 1.0) {
QFont fnt(font);
QFakeDevice fake;
diff --git a/src/gui/painting/qpaintbuffer_p.h b/src/gui/painting/qpaintbuffer_p.h
index 6a7ac73..adf0564 100644
--- a/src/gui/painting/qpaintbuffer_p.h
+++ b/src/gui/painting/qpaintbuffer_p.h
@@ -66,6 +66,7 @@ class QPaintBufferPlayback;
class Q_GUI_EXPORT QPaintBuffer : public QPaintDevice
{
+ Q_DECLARE_PRIVATE(QPaintBuffer);
public:
QPaintBuffer();
QPaintBuffer(const QPaintBuffer &other);
@@ -311,7 +312,7 @@ public:
virtual ~QPainterReplayer() { }
void setupTransform(QPainter *painter);
- void process(const QPaintBufferCommand &cmd);
+ virtual void process(const QPaintBufferCommand &cmd);
void draw(const QPaintBuffer &buffer, QPainter *painter, int frame);
protected:
@@ -326,7 +327,7 @@ class Q_GUI_EXPORT QPaintEngineExReplayer : public QPainterReplayer
public:
QPaintEngineExReplayer() { }
- void process(const QPaintBufferCommand &cmd);
+ virtual void process(const QPaintBufferCommand &cmd);
};
class QPaintBufferEnginePrivate;
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 9e21182..1fb8aab 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -431,6 +431,10 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
// Some engines might decide to optimize for the non-shape hint later on...
uint flags = QVectorPath::WindingFill;
+
+ if (path.elementCount() > 2)
+ flags |= QVectorPath::NonConvexShapeMask;
+
if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin)
flags |= QVectorPath::CurvedShapeMask;
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index cddad7d..48629d1 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -2275,8 +2275,9 @@ void QPainter::setBrushOrigin(const QPointF &p)
/*!
Sets the composition mode to the given \a mode.
- \warning You can only set the composition mode for QPainter
- objects that operates on a QImage.
+ \warning Only a QPainter operating on a QImage fully supports all
+ composition modes. The RasterOp modes are supported for X11 as
+ described in compositionMode().
\sa compositionMode()
*/
@@ -3786,27 +3787,14 @@ void QPainter::setPen(const QPen &pen)
if (d->state->pen == pen)
return;
+ d->state->pen = pen;
+
if (d->extended) {
- d->state->pen = pen;
d->checkEmulation();
d->extended->penChanged();
return;
}
- // Do some checks to see if we are the same pen.
- Qt::PenStyle currentStyle = d->state->pen.style();
- if (currentStyle == pen.style() && currentStyle != Qt::CustomDashLine) {
- if (currentStyle == Qt::NoPen ||
- (d->state->pen.isSolid() && pen.isSolid()
- && d->state->pen.color() == pen.color()
- && d->state->pen.widthF() == pen.widthF()
- && d->state->pen.capStyle() == pen.capStyle()
- && d->state->pen.joinStyle() == pen.joinStyle()
- && d->state->pen.isCosmetic() == pen.isCosmetic()))
- return;
- }
-
- d->state->pen = pen;
d->state->dirtyFlags |= QPaintEngine::DirtyPen;
}
@@ -3889,14 +3877,6 @@ void QPainter::setBrush(const QBrush &brush)
return;
}
- Qt::BrushStyle currentStyle = d->state->brush.style();
- if (currentStyle == brush.style()) {
- if (currentStyle == Qt::NoBrush
- || (currentStyle == Qt::SolidPattern
- && d->state->brush.color() == brush.color()))
- return;
- }
-
d->state->brush = brush;
d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
}
@@ -5163,7 +5143,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
Q_D(QPainter);
- if (!d->engine)
+ if (!d->engine || pm.isNull())
return;
#ifndef QT_NO_DEBUG
@@ -7603,7 +7583,7 @@ start_lengthVariant:
l.setPosition(QPointF(0., height));
height += l.height();
width = qMax(width, l.naturalTextWidth());
- if (!brect && height >= r.height())
+ if (!dontclip && !brect && height >= r.height())
break;
}
textLayout.endLayout();
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index c40bcee..8133793 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -3037,11 +3037,11 @@ void QPainterPath::addRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadi
bool first = d_func()->elements.size() < 2;
- arcMoveTo(x, y, rxx2, ryy2, 90);
- arcTo(x, y, rxx2, ryy2, 90, 90);
- arcTo(x, y+h-ryy2, rxx2, ryy2, 2*90, 90);
- arcTo(x+w-rxx2, y+h-ryy2, rxx2, ryy2, 3*90, 90);
- arcTo(x+w-rxx2, y, rxx2, ryy2, 0, 90);
+ arcMoveTo(x, y, rxx2, ryy2, 180);
+ arcTo(x, y, rxx2, ryy2, 180, -90);
+ arcTo(x+w-rxx2, y, rxx2, ryy2, 90, -90);
+ arcTo(x+w-rxx2, y+h-ryy2, rxx2, ryy2, 0, -90);
+ arcTo(x, y+h-ryy2, rxx2, ryy2, 270, -90);
closeSubpath();
d_func()->require_moveTo = true;
@@ -3094,11 +3094,11 @@ void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd)
bool first = d_func()->elements.size() < 2;
- arcMoveTo(x, y, rxx2, ryy2, 90);
- arcTo(x, y, rxx2, ryy2, 90, 90);
- arcTo(x, y+h-ryy2, rxx2, ryy2, 2*90, 90);
- arcTo(x+w-rxx2, y+h-ryy2, rxx2, ryy2, 3*90, 90);
- arcTo(x+w-rxx2, y, rxx2, ryy2, 0, 90);
+ arcMoveTo(x, y, rxx2, ryy2, 180);
+ arcTo(x, y, rxx2, ryy2, 180, -90);
+ arcTo(x+w-rxx2, y, rxx2, ryy2, 90, -90);
+ arcTo(x+w-rxx2, y+h-ryy2, rxx2, ryy2, 0, -90);
+ arcTo(x, y+h-ryy2, rxx2, ryy2, 270, -90);
closeSubpath();
d_func()->require_moveTo = true;
diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h
index 112c2bd..54b9392 100644
--- a/src/gui/painting/qpainterpath_p.h
+++ b/src/gui/painting/qpainterpath_p.h
@@ -132,10 +132,9 @@ public:
QPainterPathData() :
cStart(0),
fillRule(Qt::OddEvenFill),
- pathConverter(0),
dirtyBounds(false),
- dirtyControlBounds(false)
-
+ dirtyControlBounds(false),
+ pathConverter(0)
{
ref = 1;
require_moveTo = false;
@@ -146,10 +145,10 @@ public:
QPainterPathPrivate(), cStart(other.cStart), fillRule(other.fillRule),
bounds(other.bounds),
controlBounds(other.controlBounds),
- pathConverter(0),
dirtyBounds(other.dirtyBounds),
dirtyControlBounds(other.dirtyControlBounds),
- convex(other.convex)
+ convex(other.convex),
+ pathConverter(0)
{
ref = 1;
require_moveTo = false;
diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp
index 41efc80..77aa748 100644
--- a/src/gui/painting/qpen.cpp
+++ b/src/gui/painting/qpen.cpp
@@ -835,16 +835,17 @@ bool QPen::operator==(const QPen &p) const
{
QPenData *dd = static_cast<QPenData *>(d);
QPenData *pdd = static_cast<QPenData *>(p.d);
- return (p.d == d) || (p.d->style == d->style
- && p.d->capStyle == d->capStyle
- && p.d->joinStyle == d->joinStyle
- && p.d->width == d->width
- && pdd->miterLimit == dd->miterLimit
- && (d->style != Qt::CustomDashLine
- || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) &&
- pdd->dashPattern == dd->dashPattern))
- && p.d->brush == d->brush
- && pdd->cosmetic == dd->cosmetic);
+ return (p.d == d)
+ || (p.d->style == d->style
+ && p.d->capStyle == d->capStyle
+ && p.d->joinStyle == d->joinStyle
+ && p.d->width == d->width
+ && pdd->miterLimit == dd->miterLimit
+ && (d->style != Qt::CustomDashLine
+ || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) &&
+ pdd->dashPattern == dd->dashPattern))
+ && p.d->brush == d->brush
+ && pdd->cosmetic == dd->cosmetic);
}
@@ -983,8 +984,18 @@ QDataStream &operator>>(QDataStream &s, QPen &p)
QDebug operator<<(QDebug dbg, const QPen &p)
{
#ifndef Q_BROKEN_DEBUG_STREAM
+ const char *PEN_STYLES[] = {
+ "NoPen",
+ "SolidLine",
+ "DashLine",
+ "DotLine",
+ "DashDotLine",
+ "DashDotDotLine",
+ "CustomDashLine"
+ };
+
dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
- << ',' << int(p.style()) << ',' << int(p.capStyle())
+ << ',' << PEN_STYLES[p.style()] << ',' << int(p.capStyle())
<< ',' << int(p.joinStyle()) << ',' << p.dashPattern()
<< ',' << p.dashOffset()
<< ',' << p.miterLimit() << ')';
diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp
index c57b3c1..228a6b1 100644
--- a/src/gui/painting/qstroker.cpp
+++ b/src/gui/painting/qstroker.cpp
@@ -452,6 +452,17 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine
#endif
if (join == FlatJoin) {
+ QLineF prevLine(qt_fixed_to_real(m_back2X), qt_fixed_to_real(m_back2Y),
+ qt_fixed_to_real(m_back1X), qt_fixed_to_real(m_back1Y));
+ QPointF isect;
+ QLineF::IntersectType type = prevLine.intersect(nextLine, &isect);
+ QLineF shortCut(prevLine.p2(), nextLine.p1());
+ qreal angle = shortCut.angleTo(prevLine);
+ if (type == QLineF::BoundedIntersection || (angle > 90 && !qFuzzyCompare(angle, (qreal)90))) {
+ emitLineTo(focal_x, focal_y);
+ emitLineTo(qt_real_to_fixed(nextLine.x1()), qt_real_to_fixed(nextLine.y1()));
+ return;
+ }
emitLineTo(qt_real_to_fixed(nextLine.x1()),
qt_real_to_fixed(nextLine.y1()));
@@ -468,8 +479,8 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine
// If we are on the inside, do the short cut...
QLineF shortCut(prevLine.p2(), nextLine.p1());
qreal angle = shortCut.angleTo(prevLine);
-
if (type == QLineF::BoundedIntersection || (angle > 90 && !qFuzzyCompare(angle, (qreal)90))) {
+ emitLineTo(focal_x, focal_y);
emitLineTo(qt_real_to_fixed(nextLine.x1()), qt_real_to_fixed(nextLine.y1()));
return;
}
@@ -509,8 +520,9 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine
qfixed offset = m_strokeWidth / 2;
QLineF shortCut(prevLine.p2(), nextLine.p1());
- qreal angle = prevLine.angle(shortCut);
+ qreal angle = shortCut.angleTo(prevLine);
if (type == QLineF::BoundedIntersection || (angle > 90 && !qFuzzyCompare(angle, (qreal)90))) {
+ emitLineTo(focal_x, focal_y);
emitLineTo(qt_real_to_fixed(nextLine.x1()), qt_real_to_fixed(nextLine.y1()));
return;
}
@@ -581,6 +593,13 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine
qt_real_to_fixed(l1.x1()),
qt_real_to_fixed(l1.y1()));
} else if (join == SvgMiterJoin) {
+ QLineF shortCut(prevLine.p2(), nextLine.p1());
+ qreal angle = shortCut.angleTo(prevLine);
+ if (type == QLineF::BoundedIntersection || (angle > 90 && !qFuzzyCompare(angle, (qreal)90))) {
+ emitLineTo(focal_x, focal_y);
+ emitLineTo(qt_real_to_fixed(nextLine.x1()), qt_real_to_fixed(nextLine.y1()));
+ return;
+ }
QLineF miterLine(QPointF(qt_fixed_to_real(focal_x),
qt_fixed_to_real(focal_y)), isect);
if (miterLine.length() > qt_fixed_to_real(m_strokeWidth * m_miterLimit) / 2) {
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 8118450..1bd5842 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -2214,12 +2214,14 @@ bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
{
const QTransform::TransformationType type = transform.type();
if (type <= QTransform::TxTranslate) {
- *scale = 1;
+ if (scale)
+ *scale = 1;
return true;
} else if (type == QTransform::TxScale) {
const qreal xScale = qAbs(transform.m11());
const qreal yScale = qAbs(transform.m22());
- *scale = qMax(xScale, yScale);
+ if (scale)
+ *scale = qMax(xScale, yScale);
return qFuzzyCompare(xScale, yScale);
}
@@ -2227,7 +2229,8 @@ bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
+ transform.m21() * transform.m21();
const qreal yScale = transform.m12() * transform.m12()
+ transform.m22() * transform.m22();
- *scale = qSqrt(qMax(xScale, yScale));
+ if (scale)
+ *scale = qSqrt(qMax(xScale, yScale));
return type == QTransform::TxRotate && qFuzzyCompare(xScale, yScale);
}
diff --git a/src/gui/painting/qwindowsurface_x11.cpp b/src/gui/painting/qwindowsurface_x11.cpp
index 46c4c42..77e019c 100644
--- a/src/gui/painting/qwindowsurface_x11.cpp
+++ b/src/gui/painting/qwindowsurface_x11.cpp
@@ -94,6 +94,8 @@ QPaintDevice *QX11WindowSurface::paintDevice()
void QX11WindowSurface::beginPaint(const QRegion &rgn)
{
#ifndef QT_NO_XRENDER
+ Q_ASSERT(!d_ptr->device.isNull());
+
if (d_ptr->translucentBackground) {
if (d_ptr->device.depth() != 32)
static_cast<QX11PixmapData *>(d_ptr->device.data_ptr().data())->convertToARGB32();
@@ -157,8 +159,8 @@ void QX11WindowSurface::setGeometry(const QRect &rect)
QPixmap::x11SetDefaultScreen(d_ptr->widget->x11Info().screen());
QX11PixmapData *oldData = static_cast<QX11PixmapData *>(d_ptr->device.pixmapData());
- Q_ASSERT(oldData);
- if (!(oldData->flags & QX11PixmapData::Uninitialized) && hasStaticContents()) {
+
+ if (oldData && !(oldData->flags & QX11PixmapData::Uninitialized) && hasStaticContents()) {
// Copy the content of the old pixmap into the new one.
QX11PixmapData *newData = new QX11PixmapData(QPixmapData::PixmapType);
newData->resize(size.width(), size.height());
diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp
index 4ad78f9..4c4c994 100644
--- a/src/gui/s60framework/qs60mainappui.cpp
+++ b/src/gui/s60framework/qs60mainappui.cpp
@@ -163,7 +163,7 @@ void QS60MainAppUi::HandleResourceChangeL(TInt type)
/*!
* \brief Handles raw window server events.
*
- * The event type and information is passed in \a event, while the receiving control is passed in
+ * The event type and information is passed in \a wsEvent, while the receiving control is passed in
* \a destination.
*
* If you override this function, you should call the base class implementation if you do not
diff --git a/src/gui/s60framework/s60framework.pri b/src/gui/s60framework/s60framework.pri
index fea74fe..5884b68 100644
--- a/src/gui/s60framework/s60framework.pri
+++ b/src/gui/s60framework/s60framework.pri
@@ -1,3 +1,14 @@
+# This block serves the minimalistic resource file for S60 3.1 platforms.
+# Note there is no way to ifdef S60 version in mmp file, that is why the resource
+# file is always compiled for WINSCW
+minimalAppResource31 = \
+ "SOURCEPATH s60framework" \
+ "START RESOURCE s60main.rss" \
+ "HEADER" \
+ "TARGETPATH resource\apps" \
+ "END"
+MMP_RULES += minimalAppResource31
+
SOURCES += s60framework/qs60mainapplication.cpp \
s60framework/qs60mainappui.cpp \
s60framework/qs60maindocument.cpp
diff --git a/src/gui/s60framework/s60main.rss b/src/gui/s60framework/s60main.rss
new file mode 100644
index 0000000..07dc6a1
--- /dev/null
+++ b/src/gui/s60framework/s60main.rss
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Symbian application wrapper of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Even S60 application have ENoAppResourceFile and ENonStandardResourceFile
+// flags set, the S60 3rd Edition FP1 emulator requires applications to have
+// very minimalistic application resource file, otherwise apps refures to start
+// This file serves the minimalistic resource file for S60 3.1 platforms.
+
+// RESOURCE IDENTIFIER
+NAME QTMA // 4 letter ID
+
+// INCLUDES
+//#include <eikon.rh>
+#include <appinfo.rh>
+#include <eikon.rh>
+#include <avkon.rsg>
+#include <avkon.rh>
+#include <avkon.mbg>
+
+// RESOURCE DEFINITIONS
+RESOURCE RSS_SIGNATURE
+ {
+ }
+
+RESOURCE TBUF r_default_document_name
+ {
+ buf="QTMA";
+ }
+
+RESOURCE EIK_APP_INFO
+ {
+ menubar = r_qt_wrapperapp_menubar;
+ cba = R_AVKON_SOFTKEYS_EXIT;
+ }
+
+RESOURCE MENU_BAR r_qt_wrapperapp_menubar
+ {
+ titles =
+ {
+ MENU_TITLE { menu_pane = r_qt_wrapperapp_menu; }
+ };
+ }
+
+RESOURCE MENU_PANE r_qt_wrapperapp_menu
+ {
+ }
+// End of File
diff --git a/src/gui/statemachine/qbasickeyeventtransition.cpp b/src/gui/statemachine/qbasickeyeventtransition.cpp
index 445a253..bf10e3d 100644
--- a/src/gui/statemachine/qbasickeyeventtransition.cpp
+++ b/src/gui/statemachine/qbasickeyeventtransition.cpp
@@ -68,14 +68,14 @@ public:
QEvent::Type eventType;
int key;
- Qt::KeyboardModifiers modifiersMask;
+ Qt::KeyboardModifiers modifierMask;
};
QBasicKeyEventTransitionPrivate::QBasicKeyEventTransitionPrivate()
{
eventType = QEvent::None;
key = 0;
- modifiersMask = Qt::NoModifier;
+ modifierMask = Qt::NoModifier;
}
QBasicKeyEventTransitionPrivate *QBasicKeyEventTransitionPrivate::get(QBasicKeyEventTransition *q)
@@ -106,17 +106,17 @@ QBasicKeyEventTransition::QBasicKeyEventTransition(QEvent::Type type, int key,
/*!
Constructs a new event transition for events of the given \a type for the
- given \a key, with the given \a modifiersMask and \a sourceState.
+ given \a key, with the given \a modifierMask and \a sourceState.
*/
QBasicKeyEventTransition::QBasicKeyEventTransition(QEvent::Type type, int key,
- Qt::KeyboardModifiers modifiersMask,
+ Qt::KeyboardModifiers modifierMask,
QState *sourceState)
: QAbstractTransition(*new QBasicKeyEventTransitionPrivate, sourceState)
{
Q_D(QBasicKeyEventTransition);
d->eventType = type;
d->key = key;
- d->modifiersMask = modifiersMask;
+ d->modifierMask = modifierMask;
}
/*!
@@ -163,23 +163,23 @@ void QBasicKeyEventTransition::setKey(int key)
}
/*!
- Returns the keyboard modifiers mask that this key event transition checks
+ Returns the keyboard modifier mask that this key event transition checks
for.
*/
-Qt::KeyboardModifiers QBasicKeyEventTransition::modifiersMask() const
+Qt::KeyboardModifiers QBasicKeyEventTransition::modifierMask() const
{
Q_D(const QBasicKeyEventTransition);
- return d->modifiersMask;
+ return d->modifierMask;
}
/*!
- Sets the keyboard modifiers mask that this key event transition will check
+ Sets the keyboard modifier mask that this key event transition will check
for.
*/
-void QBasicKeyEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask)
+void QBasicKeyEventTransition::setModifierMask(Qt::KeyboardModifiers modifierMask)
{
Q_D(QBasicKeyEventTransition);
- d->modifiersMask = modifiersMask;
+ d->modifierMask = modifierMask;
}
/*!
@@ -191,7 +191,7 @@ bool QBasicKeyEventTransition::eventTest(QEvent *event)
if (event->type() == d->eventType) {
QKeyEvent *ke = static_cast<QKeyEvent*>(event);
return (ke->key() == d->key)
- && ((ke->modifiers() & d->modifiersMask) == d->modifiersMask);
+ && ((ke->modifiers() & d->modifierMask) == d->modifierMask);
}
return false;
}
diff --git a/src/gui/statemachine/qbasickeyeventtransition_p.h b/src/gui/statemachine/qbasickeyeventtransition_p.h
index 3c2ec7d..87d3dc7 100644
--- a/src/gui/statemachine/qbasickeyeventtransition_p.h
+++ b/src/gui/statemachine/qbasickeyeventtransition_p.h
@@ -69,7 +69,7 @@ public:
QBasicKeyEventTransition(QState *sourceState = 0);
QBasicKeyEventTransition(QEvent::Type type, int key, QState *sourceState = 0);
QBasicKeyEventTransition(QEvent::Type type, int key,
- Qt::KeyboardModifiers modifiersMask,
+ Qt::KeyboardModifiers modifierMask,
QState *sourceState = 0);
~QBasicKeyEventTransition();
@@ -79,8 +79,8 @@ public:
int key() const;
void setKey(int key);
- Qt::KeyboardModifiers modifiersMask() const;
- void setModifiersMask(Qt::KeyboardModifiers modifiers);
+ Qt::KeyboardModifiers modifierMask() const;
+ void setModifierMask(Qt::KeyboardModifiers modifiers);
protected:
bool eventTest(QEvent *event);
diff --git a/src/gui/statemachine/qbasicmouseeventtransition.cpp b/src/gui/statemachine/qbasicmouseeventtransition.cpp
index 694c319..fe0dea9 100644
--- a/src/gui/statemachine/qbasicmouseeventtransition.cpp
+++ b/src/gui/statemachine/qbasicmouseeventtransition.cpp
@@ -69,7 +69,7 @@ public:
QEvent::Type eventType;
Qt::MouseButton button;
- Qt::KeyboardModifiers modifiersMask;
+ Qt::KeyboardModifiers modifierMask;
QPainterPath path;
};
@@ -149,38 +149,38 @@ void QBasicMouseEventTransition::setButton(Qt::MouseButton button)
}
/*!
- Returns the keyboard modifiers mask that this mouse event transition checks
+ Returns the keyboard modifier mask that this mouse event transition checks
for.
*/
-Qt::KeyboardModifiers QBasicMouseEventTransition::modifiersMask() const
+Qt::KeyboardModifiers QBasicMouseEventTransition::modifierMask() const
{
Q_D(const QBasicMouseEventTransition);
- return d->modifiersMask;
+ return d->modifierMask;
}
/*!
- Sets the keyboard modifiers mask that this mouse event transition will check
+ Sets the keyboard modifier mask that this mouse event transition will check
for.
*/
-void QBasicMouseEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask)
+void QBasicMouseEventTransition::setModifierMask(Qt::KeyboardModifiers modifierMask)
{
Q_D(QBasicMouseEventTransition);
- d->modifiersMask = modifiersMask;
+ d->modifierMask = modifierMask;
}
/*!
- Returns the path for this mouse event transition.
+ Returns the hit test path for this mouse event transition.
*/
-QPainterPath QBasicMouseEventTransition::path() const
+QPainterPath QBasicMouseEventTransition::hitTestPath() const
{
Q_D(const QBasicMouseEventTransition);
return d->path;
}
/*!
- Sets the path for this mouse event transition.
+ Sets the hit test path for this mouse event transition.
*/
-void QBasicMouseEventTransition::setPath(const QPainterPath &path)
+void QBasicMouseEventTransition::setHitTestPath(const QPainterPath &path)
{
Q_D(QBasicMouseEventTransition);
d->path = path;
@@ -195,7 +195,7 @@ bool QBasicMouseEventTransition::eventTest(QEvent *event)
if (event->type() == d->eventType) {
QMouseEvent *me = static_cast<QMouseEvent*>(event);
return (me->button() == d->button)
- && ((me->modifiers() & d->modifiersMask) == d->modifiersMask)
+ && ((me->modifiers() & d->modifierMask) == d->modifierMask)
&& (d->path.isEmpty() || d->path.contains(me->pos()));
}
return false;
diff --git a/src/gui/statemachine/qbasicmouseeventtransition_p.h b/src/gui/statemachine/qbasicmouseeventtransition_p.h
index 512e0f8..6754c55 100644
--- a/src/gui/statemachine/qbasicmouseeventtransition_p.h
+++ b/src/gui/statemachine/qbasicmouseeventtransition_p.h
@@ -79,11 +79,11 @@ public:
Qt::MouseButton button() const;
void setButton(Qt::MouseButton button);
- Qt::KeyboardModifiers modifiersMask() const;
- void setModifiersMask(Qt::KeyboardModifiers modifiers);
+ Qt::KeyboardModifiers modifierMask() const;
+ void setModifierMask(Qt::KeyboardModifiers modifiers);
- QPainterPath path() const;
- void setPath(const QPainterPath &path);
+ QPainterPath hitTestPath() const;
+ void setHitTestPath(const QPainterPath &path);
protected:
bool eventTest(QEvent *event);
diff --git a/src/gui/statemachine/qguistatemachine.cpp b/src/gui/statemachine/qguistatemachine.cpp
index 1de5ffa..4f7806f 100644
--- a/src/gui/statemachine/qguistatemachine.cpp
+++ b/src/gui/statemachine/qguistatemachine.cpp
@@ -106,8 +106,10 @@ static QEvent *cloneEvent(QEvent *e)
return new QEvent(*e);
case QEvent::HideToParent:
return new QEvent(*e);
+#ifndef QT_NO_WHEELEVENT
case QEvent::Wheel:
return new QWheelEvent(*static_cast<QWheelEvent*>(e));
+#endif //QT_NO_WHEELEVENT
case QEvent::WindowTitleChange:
return new QEvent(*e);
case QEvent::WindowIconChange:
@@ -190,8 +192,10 @@ static QEvent *cloneEvent(QEvent *e)
return new QInputMethodEvent(*static_cast<QInputMethodEvent*>(e));
case QEvent::AccessibilityPrepare:
return new QEvent(*e);
+#ifndef QT_NO_TABLETEVENT
case QEvent::TabletMove:
return new QTabletEvent(*static_cast<QTabletEvent*>(e));
+#endif //QT_NO_TABLETEVENT
case QEvent::LocaleChange:
return new QEvent(*e);
case QEvent::LanguageChange:
@@ -200,10 +204,12 @@ static QEvent *cloneEvent(QEvent *e)
return new QEvent(*e);
case QEvent::Style:
return new QEvent(*e);
+#ifndef QT_NO_TABLETEVENT
case QEvent::TabletPress:
return new QTabletEvent(*static_cast<QTabletEvent*>(e));
case QEvent::TabletRelease:
return new QTabletEvent(*static_cast<QTabletEvent*>(e));
+#endif //QT_NO_TABLETEVENT
case QEvent::OkRequest:
return new QEvent(*e);
case QEvent::HelpRequest:
@@ -238,8 +244,10 @@ static QEvent *cloneEvent(QEvent *e)
return new QHelpEvent(*static_cast<QHelpEvent*>(e));
case QEvent::WhatsThis:
return new QHelpEvent(*static_cast<QHelpEvent*>(e));
+#ifndef QT_NO_STATUSTIP
case QEvent::StatusTip:
return new QStatusTipEvent(*static_cast<QStatusTipEvent*>(e));
+#endif //QT_NO_STATUSTIP
#ifndef QT_NO_ACTION
case QEvent::ActionChanged:
case QEvent::ActionAdded:
@@ -249,8 +257,10 @@ static QEvent *cloneEvent(QEvent *e)
case QEvent::FileOpen:
return new QFileOpenEvent(*static_cast<QFileOpenEvent*>(e));
+#ifndef QT_NO_SHORTCUT
case QEvent::Shortcut:
return new QShortcutEvent(*static_cast<QShortcutEvent*>(e));
+#endif //QT_NO_SHORTCUT
case QEvent::ShortcutOverride:
return new QKeyEvent(*static_cast<QKeyEvent*>(e));
@@ -263,11 +273,15 @@ static QEvent *cloneEvent(QEvent *e)
break;
#endif
+#ifndef QT_NO_WHATSTHIS
case QEvent::WhatsThisClicked:
return new QWhatsThisClickedEvent(*static_cast<QWhatsThisClickedEvent*>(e));
+#endif //QT_NO_WHATSTHIS
+#ifndef QT_NO_TOOLBAR
case QEvent::ToolBarChange:
return new QToolBarChangeEvent(*static_cast<QToolBarChangeEvent*>(e));
+#endif //QT_NO_TOOLBAR
case QEvent::ApplicationActivate:
return new QEvent(*e);
@@ -397,9 +411,11 @@ static QEvent *cloneEvent(QEvent *e)
case QEvent::DynamicPropertyChange:
return new QDynamicPropertyChangeEvent(*static_cast<QDynamicPropertyChangeEvent*>(e));
+#ifndef QT_NO_TABLETEVENT
case QEvent::TabletEnterProximity:
case QEvent::TabletLeaveProximity:
return new QTabletEvent(*static_cast<QTabletEvent*>(e));
+#endif //QT_NO_TABLETEVENT
case QEvent::NonClientAreaMouseMove:
case QEvent::NonClientAreaMouseButtonPress:
diff --git a/src/gui/statemachine/qkeyeventtransition.cpp b/src/gui/statemachine/qkeyeventtransition.cpp
index dee3168..a15e671 100644
--- a/src/gui/statemachine/qkeyeventtransition.cpp
+++ b/src/gui/statemachine/qkeyeventtransition.cpp
@@ -69,9 +69,9 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \property QKeyEventTransition::modifiersMask
+ \property QKeyEventTransition::modifierMask
- \brief the keyboard modifiers mask that this key event transition checks for
+ \brief the keyboard modifier mask that this key event transition checks for
*/
class QKeyEventTransitionPrivate : public QEventTransitionPrivate
@@ -133,23 +133,23 @@ void QKeyEventTransition::setKey(int key)
}
/*!
- Returns the keyboard modifiers mask that this key event transition checks
+ Returns the keyboard modifier mask that this key event transition checks
for.
*/
-Qt::KeyboardModifiers QKeyEventTransition::modifiersMask() const
+Qt::KeyboardModifiers QKeyEventTransition::modifierMask() const
{
Q_D(const QKeyEventTransition);
- return d->transition->modifiersMask();
+ return d->transition->modifierMask();
}
/*!
- Sets the keyboard \a modifiers mask that this key event transition will
- check for.
+ Sets the keyboard modifier mask that this key event transition will
+ check for to \a modifierMask.
*/
-void QKeyEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask)
+void QKeyEventTransition::setModifierMask(Qt::KeyboardModifiers modifierMask)
{
Q_D(QKeyEventTransition);
- d->transition->setModifiersMask(modifiersMask);
+ d->transition->setModifierMask(modifierMask);
}
/*!
diff --git a/src/gui/statemachine/qkeyeventtransition.h b/src/gui/statemachine/qkeyeventtransition.h
index 8df8138..ab1c155 100644
--- a/src/gui/statemachine/qkeyeventtransition.h
+++ b/src/gui/statemachine/qkeyeventtransition.h
@@ -57,7 +57,7 @@ class Q_GUI_EXPORT QKeyEventTransition : public QEventTransition
{
Q_OBJECT
Q_PROPERTY(int key READ key WRITE setKey)
- Q_PROPERTY(Qt::KeyboardModifiers modifiersMask READ modifiersMask WRITE setModifiersMask)
+ Q_PROPERTY(Qt::KeyboardModifiers modifierMask READ modifierMask WRITE setModifierMask)
public:
QKeyEventTransition(QState *sourceState = 0);
QKeyEventTransition(QObject *object, QEvent::Type type, int key,
@@ -67,8 +67,8 @@ public:
int key() const;
void setKey(int key);
- Qt::KeyboardModifiers modifiersMask() const;
- void setModifiersMask(Qt::KeyboardModifiers modifiers);
+ Qt::KeyboardModifiers modifierMask() const;
+ void setModifierMask(Qt::KeyboardModifiers modifiers);
protected:
void onTransition(QEvent *event);
diff --git a/src/gui/statemachine/qmouseeventtransition.cpp b/src/gui/statemachine/qmouseeventtransition.cpp
index 86cacf7..f5c0cb1 100644
--- a/src/gui/statemachine/qmouseeventtransition.cpp
+++ b/src/gui/statemachine/qmouseeventtransition.cpp
@@ -70,9 +70,9 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \property QMouseEventTransition::modifiersMask
+ \property QMouseEventTransition::modifierMask
- \brief the keyboard modifiers mask that this mouse event transition checks for
+ \brief the keyboard modifier mask that this mouse event transition checks for
*/
class QMouseEventTransitionPrivate : public QEventTransitionPrivate
@@ -139,45 +139,45 @@ void QMouseEventTransition::setButton(Qt::MouseButton button)
}
/*!
- Returns the keyboard modifiers mask that this mouse event transition checks
+ Returns the keyboard modifier mask that this mouse event transition checks
for.
*/
-Qt::KeyboardModifiers QMouseEventTransition::modifiersMask() const
+Qt::KeyboardModifiers QMouseEventTransition::modifierMask() const
{
Q_D(const QMouseEventTransition);
- return d->transition->modifiersMask();
+ return d->transition->modifierMask();
}
/*!
- Sets the keyboard \a modifiers mask that this mouse event transition will
- check for.
+ Sets the keyboard modifier mask that this mouse event transition will
+ check for to \a modifierMask.
*/
-void QMouseEventTransition::setModifiersMask(Qt::KeyboardModifiers modifiersMask)
+void QMouseEventTransition::setModifierMask(Qt::KeyboardModifiers modifierMask)
{
Q_D(QMouseEventTransition);
- d->transition->setModifiersMask(modifiersMask);
+ d->transition->setModifierMask(modifierMask);
}
/*!
- Returns the path for this mouse event transition.
+ Returns the hit test path for this mouse event transition.
*/
-QPainterPath QMouseEventTransition::path() const
+QPainterPath QMouseEventTransition::hitTestPath() const
{
Q_D(const QMouseEventTransition);
- return d->transition->path();
+ return d->transition->hitTestPath();
}
/*!
- Sets the \a path for this mouse event transition.
+ Sets the hit test path for this mouse event transition to \a path.
If a valid path has been set, the transition will only trigger if the mouse
event position (QMouseEvent::pos()) is inside the path.
\sa QPainterPath::contains()
*/
-void QMouseEventTransition::setPath(const QPainterPath &path)
+void QMouseEventTransition::setHitTestPath(const QPainterPath &path)
{
Q_D(QMouseEventTransition);
- d->transition->setPath(path);
+ d->transition->setHitTestPath(path);
}
/*!
diff --git a/src/gui/statemachine/qmouseeventtransition.h b/src/gui/statemachine/qmouseeventtransition.h
index 4e324ec..e7f6a45 100644
--- a/src/gui/statemachine/qmouseeventtransition.h
+++ b/src/gui/statemachine/qmouseeventtransition.h
@@ -58,7 +58,7 @@ class Q_GUI_EXPORT QMouseEventTransition : public QEventTransition
{
Q_OBJECT
Q_PROPERTY(Qt::MouseButton button READ button WRITE setButton)
- Q_PROPERTY(Qt::KeyboardModifiers modifiersMask READ modifiersMask WRITE setModifiersMask)
+ Q_PROPERTY(Qt::KeyboardModifiers modifierMask READ modifierMask WRITE setModifierMask)
public:
QMouseEventTransition(QState *sourceState = 0);
QMouseEventTransition(QObject *object, QEvent::Type type,
@@ -68,11 +68,11 @@ public:
Qt::MouseButton button() const;
void setButton(Qt::MouseButton button);
- Qt::KeyboardModifiers modifiersMask() const;
- void setModifiersMask(Qt::KeyboardModifiers modifiers);
+ Qt::KeyboardModifiers modifierMask() const;
+ void setModifierMask(Qt::KeyboardModifiers modifiers);
- QPainterPath path() const;
- void setPath(const QPainterPath &path);
+ QPainterPath hitTestPath() const;
+ void setHitTestPath(const QPainterPath &path);
protected:
void onTransition(QEvent *event);
diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp
index bf2f68e..4c9541b 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/gui/styles/qcommonstyle.cpp
@@ -5656,102 +5656,103 @@ QIcon QCommonStyle::standardIconImplementation(StandardPixmap standardIcon, cons
default:
break;
}
-
+ } // if (QApplication::desktopSettingsAware() && !QIcon::themeName().isEmpty())
if (!icon.isNull())
return icon;
#if defined(Q_WS_MAC)
- OSType iconType = 0;
- switch (standardIcon) {
- case QStyle::SP_MessageBoxQuestion:
- case QStyle::SP_MessageBoxInformation:
- case QStyle::SP_MessageBoxWarning:
- case QStyle::SP_MessageBoxCritical:
- iconType = kGenericApplicationIcon;
- break;
- case SP_DesktopIcon:
- iconType = kDesktopIcon;
- break;
- case SP_TrashIcon:
- iconType = kTrashIcon;
- break;
- case SP_ComputerIcon:
- iconType = kComputerIcon;
- break;
- case SP_DriveFDIcon:
- iconType = kGenericFloppyIcon;
- break;
- case SP_DriveHDIcon:
- iconType = kGenericHardDiskIcon;
- break;
- case SP_DriveCDIcon:
- case SP_DriveDVDIcon:
- iconType = kGenericCDROMIcon;
- break;
- case SP_DriveNetIcon:
- iconType = kGenericNetworkIcon;
- break;
- case SP_DirOpenIcon:
- iconType = kOpenFolderIcon;
- break;
- case SP_DirClosedIcon:
- case SP_DirLinkIcon:
- iconType = kGenericFolderIcon;
- break;
- case SP_FileLinkIcon:
- case SP_FileIcon:
- iconType = kGenericDocumentIcon;
- break;
- case SP_DirIcon: {
- // A rather special case
- QIcon closeIcon = QStyle::standardIcon(SP_DirClosedIcon, option, widget);
- QIcon openIcon = QStyle::standardIcon(SP_DirOpenIcon, option, widget);
- closeIcon.addPixmap(openIcon.pixmap(16, 16), QIcon::Normal, QIcon::On);
- closeIcon.addPixmap(openIcon.pixmap(32, 32), QIcon::Normal, QIcon::On);
- closeIcon.addPixmap(openIcon.pixmap(64, 64), QIcon::Normal, QIcon::On);
- closeIcon.addPixmap(openIcon.pixmap(128, 128), QIcon::Normal, QIcon::On);
- return closeIcon;
- }
- case SP_TitleBarNormalButton:
- case SP_TitleBarCloseButton: {
- QIcon titleBarIcon;
- if (standardIcon == SP_TitleBarCloseButton) {
- titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/closedock-16.png"));
- titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/closedock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
- } else {
- titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/dockdock-16.png"));
- titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/dockdock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
+ if (QApplication::desktopSettingsAware()) {
+ OSType iconType = 0;
+ switch (standardIcon) {
+ case QStyle::SP_MessageBoxQuestion:
+ case QStyle::SP_MessageBoxInformation:
+ case QStyle::SP_MessageBoxWarning:
+ case QStyle::SP_MessageBoxCritical:
+ iconType = kGenericApplicationIcon;
+ break;
+ case SP_DesktopIcon:
+ iconType = kDesktopIcon;
+ break;
+ case SP_TrashIcon:
+ iconType = kTrashIcon;
+ break;
+ case SP_ComputerIcon:
+ iconType = kComputerIcon;
+ break;
+ case SP_DriveFDIcon:
+ iconType = kGenericFloppyIcon;
+ break;
+ case SP_DriveHDIcon:
+ iconType = kGenericHardDiskIcon;
+ break;
+ case SP_DriveCDIcon:
+ case SP_DriveDVDIcon:
+ iconType = kGenericCDROMIcon;
+ break;
+ case SP_DriveNetIcon:
+ iconType = kGenericNetworkIcon;
+ break;
+ case SP_DirOpenIcon:
+ iconType = kOpenFolderIcon;
+ break;
+ case SP_DirClosedIcon:
+ case SP_DirLinkIcon:
+ iconType = kGenericFolderIcon;
+ break;
+ case SP_FileLinkIcon:
+ case SP_FileIcon:
+ iconType = kGenericDocumentIcon;
+ break;
+ case SP_DirIcon: {
+ // A rather special case
+ QIcon closeIcon = QStyle::standardIcon(SP_DirClosedIcon, option, widget);
+ QIcon openIcon = QStyle::standardIcon(SP_DirOpenIcon, option, widget);
+ closeIcon.addPixmap(openIcon.pixmap(16, 16), QIcon::Normal, QIcon::On);
+ closeIcon.addPixmap(openIcon.pixmap(32, 32), QIcon::Normal, QIcon::On);
+ closeIcon.addPixmap(openIcon.pixmap(64, 64), QIcon::Normal, QIcon::On);
+ closeIcon.addPixmap(openIcon.pixmap(128, 128), QIcon::Normal, QIcon::On);
+ return closeIcon;
+ }
+ case SP_TitleBarNormalButton:
+ case SP_TitleBarCloseButton: {
+ QIcon titleBarIcon;
+ if (standardIcon == SP_TitleBarCloseButton) {
+ titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/closedock-16.png"));
+ titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/closedock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
+ } else {
+ titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/dockdock-16.png"));
+ titleBarIcon.addFile(QLatin1String(":/trolltech/styles/macstyle/images/dockdock-down-16.png"), QSize(16, 16), QIcon::Normal, QIcon::On);
+ }
+ return titleBarIcon;
}
- return titleBarIcon;
- }
- default:
- break;
- }
- if (iconType != 0) {
- QIcon retIcon;
- IconRef icon;
- IconRef overlayIcon = 0;
- if (iconType != kGenericApplicationIcon) {
- GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon);
- } else {
- FSRef fsRef;
- ProcessSerialNumber psn = { 0, kCurrentProcess };
- GetProcessBundleLocation(&psn, &fsRef);
- GetIconRefFromFileInfo(&fsRef, 0, 0, 0, 0, kIconServicesNormalUsageFlag, &icon, 0);
- if (standardIcon == SP_MessageBoxCritical) {
- overlayIcon = icon;
- GetIconRef(kOnSystemDisk, kSystemIconsCreator, kAlertCautionIcon, &icon);
- }
- }
- if (icon) {
- qt_mac_constructQIconFromIconRef(icon, overlayIcon, &retIcon, standardIcon);
- ReleaseIconRef(icon);
- }
- if (overlayIcon)
- ReleaseIconRef(overlayIcon);
- return retIcon;
- }
+ default:
+ break;
+ }
+ if (iconType != 0) {
+ QIcon retIcon;
+ IconRef icon;
+ IconRef overlayIcon = 0;
+ if (iconType != kGenericApplicationIcon) {
+ GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon);
+ } else {
+ FSRef fsRef;
+ ProcessSerialNumber psn = { 0, kCurrentProcess };
+ GetProcessBundleLocation(&psn, &fsRef);
+ GetIconRefFromFileInfo(&fsRef, 0, 0, 0, 0, kIconServicesNormalUsageFlag, &icon, 0);
+ if (standardIcon == SP_MessageBoxCritical) {
+ overlayIcon = icon;
+ GetIconRef(kOnSystemDisk, kSystemIconsCreator, kAlertCautionIcon, &icon);
+ }
+ }
+ if (icon) {
+ qt_mac_constructQIconFromIconRef(icon, overlayIcon, &retIcon, standardIcon);
+ ReleaseIconRef(icon);
+ }
+ if (overlayIcon)
+ ReleaseIconRef(overlayIcon);
+ return retIcon;
+ }
+ } // if (QApplication::desktopSettingsAware())
#endif // Q_WS_MAC
- }
switch (standardIcon) {
#ifndef QT_NO_IMAGEFORMAT_PNG
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index b87f3a8..e0fcb92 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -281,7 +281,7 @@ void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter,
drawFrame(SF_ButtonInactive, painter, rect, flags | SF_PointNorth);
break;
case SE_Editor:
- drawFrame(SF_Editor, painter, rect, flags | SF_PointNorth);
+ drawFrame(SF_FrameLineEdit, painter, rect, flags | SF_PointNorth);
break;
default:
break;
@@ -499,7 +499,7 @@ void QS60StylePrivate::setBackgroundTexture(QApplication *app) const
Q_UNUSED(app)
QPalette applicationPalette = QApplication::palette();
applicationPalette.setBrush(QPalette::Window, backgroundTexture());
- QApplication::setPalette(applicationPalette);
+ setThemePalette(app);
}
void QS60StylePrivate::deleteBackground()
@@ -743,7 +743,7 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const
const QColor mainAreaTextColor =
s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0);
- widgetPalette.setColor(QPalette::All, QPalette::WindowText,
+ widgetPalette.setColor(QPalette::WindowText,
s60Color(QS60StyleEnums::CL_QsnLineColors, 8, 0));
QApplication::setPalette(widgetPalette, "QSlider");
// return to original palette after each widget
@@ -767,34 +767,34 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const
QApplication::setPalette(widgetPalette, "QHeaderView");
widgetPalette = *palette;
- widgetPalette.setColor(QPalette::All, QPalette::ButtonText,
+ widgetPalette.setColor(QPalette::ButtonText,
s60Color(QS60StyleEnums::CL_QsnTextColors, 8, 0));
QApplication::setPalette(widgetPalette, "QMenuBar");
widgetPalette = *palette;
- widgetPalette.setColor(QPalette::Active, QPalette::WindowText,
+ widgetPalette.setColor(QPalette::WindowText,
s60Color(QS60StyleEnums::CL_QsnTextColors, 4, 0));
QApplication::setPalette(widgetPalette, "QTabBar");
widgetPalette = *palette;
- widgetPalette.setColor(QPalette::All, QPalette::Text,
+ widgetPalette.setColor(QPalette::Text,
s60Color(QS60StyleEnums::CL_QsnTextColors, 22, 0));
QApplication::setPalette(widgetPalette, "QTableView");
widgetPalette = *palette;
- widgetPalette.setColor(QPalette::All, QPalette::HighlightedText,
+ widgetPalette.setColor(QPalette::HighlightedText,
s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
QApplication::setPalette(widgetPalette, "QLineEdit");
widgetPalette = *palette;
- widgetPalette.setColor(QPalette::All, QPalette::Text,
+ widgetPalette.setColor(QPalette::Text,
s60Color(QS60StyleEnums::CL_QsnTextColors, 34, 0));
- widgetPalette.setColor(QPalette::All, QPalette::HighlightedText,
+ widgetPalette.setColor(QPalette::HighlightedText,
s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
QApplication::setPalette(widgetPalette, "QTextEdit");
widgetPalette = *palette;
- widgetPalette.setColor(QPalette::All, QPalette::HighlightedText,
+ widgetPalette.setColor(QPalette::HighlightedText,
s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0));
QApplication::setPalette(widgetPalette, "QComboBox");
widgetPalette = *palette;
@@ -831,6 +831,11 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag
pixelMetric(QStyle::PM_SliderControlThickness), Qt::IgnoreAspectRatio);
break;
+ case QS60StyleEnums::SP_QgnGrafBarFrameSideL:
+ case QS60StyleEnums::SP_QgnGrafBarFrameSideR:
+ result.setWidth(pixelMetric(PM_Custom_FrameCornerWidth));
+ break;
+
case QS60StyleEnums::SP_QsnCpScrollHandleBottomPressed:
case QS60StyleEnums::SP_QsnCpScrollHandleTopPressed:
case QS60StyleEnums::SP_QsnCpScrollHandleMiddlePressed:
@@ -994,6 +999,10 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
const State bflags = toolBtn->state;
const QRect button(subControlRect(control, toolBtn, SC_ToolButton, widget));
+ QRect menuRect = QRect();
+ if (toolBtn->subControls & SC_ToolButtonMenu)
+ menuRect = subControlRect(control, toolBtn, SC_ToolButtonMenu, widget);
+
QStyleOptionToolButton toolButton = *toolBtn;
if (sub&SC_ToolButton) {
@@ -1006,7 +1015,7 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
toolBar = qobject_cast<QToolBar *>(widget->parentWidget());
if (bflags & (State_Sunken | State_On | State_Raised)) {
- tool.rect = button;
+ tool.rect = button.unite(menuRect);
tool.state = bflags;
// todo: I'd like to move extension button next to where last button is
@@ -1061,6 +1070,12 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
} else {
drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
}
+
+ if (toolButton.subControls & SC_ToolButtonMenu) {
+ tool.rect = menuRect;
+ tool.state = bflags;
+ drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget);
+ }
}
}
@@ -1666,18 +1681,18 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
if (!styleHint(SH_UnderlineShortcut, menuItem, widget))
text_flags |= Qt::TextHideMnemonic;
- QRect iconRect =
- subElementRect(SE_ItemViewItemDecoration, &optionMenuItem, widget);
- QRect textRect = subElementRect(SE_ItemViewItemText, &optionMenuItem, widget);
-
if ((option->state & State_Selected) && (option->state & State_Enabled))
QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, option->rect, flags);
+ QRect iconRect = subElementRect(SE_ItemViewItemDecoration, &optionMenuItem, widget);
+ QRect textRect = subElementRect(SE_ItemViewItemText, &optionMenuItem, widget);
+
//todo: move the vertical spacing stuff into subElementRect
const int vSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing);
if (checkable){
+ const int hSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
QStyleOptionMenuItem optionCheckBox;
- optionCheckBox.QStyleOption::operator=(*menuItem);
+ optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem);
optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth));
optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight));
const int moveByX = optionCheckBox.rect.width()+vSpacing;
@@ -1686,6 +1701,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
iconRect.translate(moveByX, 0);
iconRect.setWidth(iconRect.width()+vSpacing);
textRect.setWidth(textRect.width()-moveByX-vSpacing);
+ optionCheckBox.rect.translate(vSpacing/2, hSpacing/2);
} else {
textRect.setWidth(textRect.width()-moveByX);
iconRect.setWidth(iconRect.width()+vSpacing);
@@ -1752,7 +1768,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
#endif //QT_NO_MENUBAR
case CE_HeaderSection:
- if ( const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
+ if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
painter->save();
QPen linePen = QPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 1, header));
const int penWidth = (header->orientation == Qt::Horizontal) ?
@@ -1770,6 +1786,25 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
}
}
painter->restore();
+
+ //Draw corner button as normal pushButton.
+ if (qobject_cast<const QAbstractButton *>(widget)) {
+ //Make cornerButton slightly smaller so that it is not on top of table border graphic.
+ QStyleOptionHeader subopt = *header;
+ const int borderTweak =
+ QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth)>>1;
+ if (subopt.direction == Qt::LeftToRight)
+ subopt.rect.adjust(borderTweak, borderTweak, 0, -borderTweak);
+ else
+ subopt.rect.adjust(0, borderTweak, -borderTweak, -borderTweak);
+ drawPrimitive(PE_PanelButtonBevel, &subopt, painter, widget);
+ } else if ((header->palette.brush(QPalette::Button) != Qt::transparent)) {
+ //Draw non-themed background. Background for theme is drawn in CE_ShapedFrame
+ //to get continuous theme graphic across all the header cells.
+ qDrawShadePanel(painter, header->rect, header->palette,
+ header->state & (State_Sunken | State_On), penWidth,
+ &header->palette.brush(QPalette::Button));
+ }
}
break;
case CE_HeaderEmptyArea: // no need to draw this
@@ -1840,15 +1875,24 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
} else if (qobject_cast<const QTableView *>(widget)) {
QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableItem, painter, option->rect, flags);
} else if (const QHeaderView *header = qobject_cast<const QHeaderView *>(widget)) {
- if (header->orientation() == Qt::Horizontal) {
- QRect headerRect = option->rect;
- const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
- headerRect.adjust(0,frameWidth,-2*frameWidth,0);
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableHeaderItem, painter, headerRect, flags);
- } else {
+ //QS60style draws header background here instead of in each headersection, to get
+ //continuous graphic from section to section.
+ QS60StylePrivate::SkinElementFlags adjustableFlags = flags;
+ QRect headerRect = option->rect;
+ if (header->orientation() != Qt::Horizontal) {
//todo: update to horizontal table graphic
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_TableHeaderItem, painter, option->rect, flags | QS60StylePrivate::SF_PointWest);
+ adjustableFlags = (adjustableFlags | QS60StylePrivate::SF_PointWest);
+ } else {
+ const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ if (option->direction == Qt::LeftToRight)
+ headerRect.adjust(-2*frameWidth, 0, 0, 0);
+ else
+ headerRect.adjust(0, 0, 2*frameWidth, 0);
}
+ if (option->palette.brush(QPalette::Button).color() == Qt::transparent)
+ QS60StylePrivate::drawSkinElement(
+ QS60StylePrivate::SE_TableHeaderItem, painter, headerRect, adjustableFlags);
+
} else if (qobject_cast<const QFrame *>(widget)) {
QCommonStyle::drawControl(element, option, painter, widget);
}
@@ -2204,7 +2248,6 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
// todo: items are below with #ifdefs "just in case". in final version, remove all non-required cases
case PE_FrameLineEdit:
- case PE_IndicatorButtonDropDown:
case PE_IndicatorDockWidgetResizeHandle:
case PE_PanelTipLabel:
case PE_PanelScrollAreaCorner:
@@ -2255,8 +2298,18 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
{
QSize sz(csz);
switch (ct) {
+ case CT_ToolButton:
+ sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
+ //FIXME properly - style should calculate the location of border frame-part
+ sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin));
+ if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(opt))
+ if (toolBtn->subControls & SC_ToolButtonMenu)
+ sz += QSize(pixelMetric(PM_MenuButtonIndicator),0);
+ break;
case CT_PushButton:
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
+ //FIXME properly - style should calculate the location of border frame-part
+ sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin));
if (const QAbstractButton *buttonWidget = (qobject_cast<const QAbstractButton *>(widget)))
if (buttonWidget->isCheckable())
sz += QSize(pixelMetric(PM_IndicatorWidth) + pixelMetric(PM_CheckBoxLabelSpacing), 0);
@@ -2266,10 +2319,19 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
sz += QSize(2*f->lineWidth, 4*f->lineWidth);
break;
case CT_TabBarTab:
- QSize naviPaneSize = QS60StylePrivate::naviPaneSize();
+ {
+ const QSize naviPaneSize = QS60StylePrivate::naviPaneSize();
+ sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
+ if (naviPaneSize.height() > sz.height())
+ sz.setHeight(naviPaneSize.height());
+ }
+ break;
+ case CT_ItemViewItem:
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
- if (naviPaneSize.height() > sz.height())
- sz.setHeight(naviPaneSize.height());
+ if (QS60StylePrivate::isTouchSupported())
+ //Make itemview easier to use in touch devices
+ //QCommonStyle does not adjust height with horizontal margin, it only adjusts width
+ sz.setHeight(sz.height() + 2*pixelMetric(QStyle::PM_FocusFrameVMargin));
break;
default:
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
@@ -2524,6 +2586,29 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
}
}
break;
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolButton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2*pixelMetric(PM_ButtonMargin);
+ const int border = pixelMetric(PM_ButtonMargin) + pixelMetric(PM_DefaultFrameWidth);
+ ret = toolButton->rect;
+ const bool popup = (toolButton->features &
+ (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay))
+ == QStyleOptionToolButton::MenuButtonPopup;
+ switch (scontrol) {
+ case SC_ToolButton:
+ if (popup)
+ ret.adjust(0, 0, -indicatorRect, 0);
+ break;
+ case SC_ToolButtonMenu:
+ if (popup)
+ ret.adjust(ret.width() - indicatorRect, border, -pixelMetric(PM_ButtonMargin), -border);
+ break;
+ default:
+ break;
+ }
+ ret = visualRect(toolButton->direction, toolButton->rect, ret);
+ }
+ break;
default:
ret = QCommonStyle::subControlRect(control, option, scontrol, widget);
}
@@ -2538,8 +2623,8 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
QRect ret;
switch (element) {
case SE_LineEditContents: {
- // in S60 the input text box doesn't start from line Edit's TL, but
- // a bit indented.
+ // in S60 the input text box doesn't start from line Edit's TL, but
+ // a bit indented.
QRect lineEditRect = opt->rect;
const int adjustment = opt->rect.height()>>2;
lineEditRect.adjust(adjustment,0,0,0);
diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h
index 54af757..46547bf 100644
--- a/src/gui/styles/qs60style_p.h
+++ b/src/gui/styles/qs60style_p.h
@@ -361,7 +361,6 @@ public:
SF_ToolBarButtonPressed,
SF_PanelBackground,
SF_ButtonInactive,
- SF_Editor,
};
enum SkinElementFlag {
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index 678844c..c2a207c 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -319,16 +319,6 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = {
/* SP_QsnFrButtonSideRInactive */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b8},
/* SP_QsnFrButtonCenterInactive */ {KAknsIIDQsnFrButtonTbCenter, EDrawIcon, ES60_3_1 | ES60_3_2, EAknsMajorSkin, 0x21b9},
- /* SP_QsnFrNotepadCornerTl */ {KAknsIIDQsnFrNotepadContCornerTl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadCornerTr */ {KAknsIIDQsnFrNotepadContCornerTr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadCornerBl */ {KAknsIIDQsnFrNotepadCornerBl, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadCornerBr */ {KAknsIIDQsnFrNotepadCornerBr, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadSideT */ {KAknsIIDQsnFrNotepadContSideT, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadSideB */ {KAknsIIDQsnFrNotepadSideB, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadSideL */ {KAknsIIDQsnFrNotepadSideL, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadSideR */ {KAknsIIDQsnFrNotepadSideR, ENoDraw, ES60_AllReleases, -1,-1},
- /* SP_QsnFrNotepadCenter */ {KAknsIIDQsnFrNotepadCenter, EDrawIcon, ES60_AllReleases, -1,-1},
-
};
QPixmap QS60StyleModeSpecifics::skinnedGraphics(
@@ -852,10 +842,6 @@ void QS60StyleModeSpecifics::frameIdAndCenterId(QS60StylePrivate::SkinFrameEleme
centerId.Set(KAknsIIDNone);
frameId.Set(KAknsIIDQsnFrSetOpt);
break;
- case QS60StylePrivate::SF_Editor:
- centerId.Set(KAknsIIDQsnFrNotepadCenter);
- frameId.Set(KAknsIIDQsnFrNotepadCont);
- break;
default:
// center should be correct here
frameId.iMinor = centerId.iMinor - 9;
@@ -1382,13 +1368,13 @@ QSize QS60StylePrivate::naviPaneSize()
QSize QS60StyleModeSpecifics::naviPaneSize()
{
CAknNavigationControlContainer* naviContainer;
- if (S60->statusPane())
- naviContainer = static_cast<CAknNavigationControlContainer*>
- (S60->statusPane()->ControlL(TUid::Uid(EEikStatusPaneUidNavi)));
- if (naviContainer)
- return QSize(naviContainer->Size().iWidth, naviContainer->Size().iHeight);
- else
- return QSize(0,0);
+ if (S60->statusPane()) {
+ TRAPD(err, naviContainer = static_cast<CAknNavigationControlContainer*>
+ (S60->statusPane()->ControlL(TUid::Uid(EEikStatusPaneUidNavi))));
+ if (err==KErrNone)
+ return QSize(naviContainer->Size().iWidth, naviContainer->Size().iHeight);
+ }
+ return QSize(0,0);
}
#endif // Q_WS_S60
diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp
index 14f0424..706b4e9 100644
--- a/src/gui/styles/qs60style_simulated.cpp
+++ b/src/gui/styles/qs60style_simulated.cpp
@@ -322,7 +322,7 @@ QPixmap QS60StylePrivate::backgroundTexture()
{
if (!m_background) {
const QSize size = QApplication::desktop()->screen()->size();
- QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen, size);
+ QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen, size, 0);
m_background = new QPixmap(background);
}
return *m_background;
diff --git a/src/gui/styles/qstyleoption.cpp b/src/gui/styles/qstyleoption.cpp
index f5a2b94..d73a563 100644
--- a/src/gui/styles/qstyleoption.cpp
+++ b/src/gui/styles/qstyleoption.cpp
@@ -4736,8 +4736,9 @@ QStyleOptionTabWidgetFrameV2::QStyleOptionTabWidgetFrameV2(const QStyleOptionTab
QStyleOptionFrame types.
If the \a{other} style option's version is 1, this style option's
- \l FrameFeature value is set to \l QStyleOptionFrameV2::None. If
- its version is 2, its \l FrameFeature value is simply copied to
+ QStyleOptionFrameV2::FrameFeature value is set to
+ QStyleOptionFrameV2::None. If its version is 2, its
+ \l{QStyleOptionFrameV2::}{FrameFeature} value is simply copied to
this style option.
*/
QStyleOptionTabWidgetFrameV2 &QStyleOptionTabWidgetFrameV2::operator=(const QStyleOptionTabWidgetFrame &other)
diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp
index ae1d33a..ce73fd8 100644
--- a/src/gui/styles/qstylesheetstyle.cpp
+++ b/src/gui/styles/qstylesheetstyle.cpp
@@ -3325,9 +3325,14 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
break;
case CE_PushButton:
- ParentStyle::drawControl(ce, opt, p, w);
- return;
-
+ if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
+ if (rule.hasDrawable() || rule.hasBox() || rule.hasPosition() || rule.hasPalette() ||
+ ((btn->features & QStyleOptionButton::HasMenu) && hasStyleRule(w, PseudoElement_PushButtonMenuIndicator))) {
+ ParentStyle::drawControl(ce, opt, p, w);
+ return;
+ }
+ }
+ break;
case CE_PushButtonBevel:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
QStyleOptionButton btnOpt(*btn);
@@ -3370,7 +3375,9 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
if (rule.hasPosition() && rule.position()->textAlignment != 0) {
Qt::Alignment textAlignment = rule.position()->textAlignment;
QRect textRect = button->rect;
- uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
+ uint tf = Qt::TextShowMnemonic;
+ const uint verticalAlignMask = Qt::AlignVCenter | Qt::AlignTop | Qt::AlignLeft;
+ tf |= (textAlignment & verticalAlignMask) ? (textAlignment & verticalAlignMask) : Qt::AlignVCenter;
if (!styleHint(SH_UnderlineShortcut, button, w))
tf |= Qt::TextHideMnemonic;
if (!button->icon.isNull()) {
@@ -3599,6 +3606,27 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
}
} else if (hasStyleRule(w, PseudoElement_MenuCheckMark) || hasStyleRule(w, PseudoElement_MenuRightArrow)) {
QWindowsStyle::drawControl(ce, &mi, p, w);
+ if (mi.checkType != QStyleOptionMenuItem::NotCheckable && !mi.checked) {
+ // We have a style defined, but QWindowsStyle won't draw anything if not checked.
+ // So we mimick what QWindowsStyle would do.
+ int checkcol = qMax<int>(mi.maxIconWidth, QWindowsStylePrivate::windowsCheckMarkWidth);
+ QRect vCheckRect = visualRect(opt->direction, mi.rect, QRect(mi.rect.x(), mi.rect.y(), checkcol, mi.rect.height()));
+ if (mi.state.testFlag(State_Enabled) && mi.state.testFlag(State_Selected)) {
+ qDrawShadePanel(p, vCheckRect, mi.palette, true, 1, &mi.palette.brush(QPalette::Button));
+ } else {
+ QBrush fill(mi.palette.light().color(), Qt::Dense4Pattern);
+ qDrawShadePanel(p, vCheckRect, mi.palette, true, 1, &fill);
+ }
+ QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
+ if (subSubRule.hasDrawable()) {
+ QStyleOptionMenuItem newMi(mi);
+ newMi.rect = visualRect(opt->direction, mi.rect, QRect(mi.rect.x() + QWindowsStylePrivate::windowsItemFrame,
+ mi.rect.y() + QWindowsStylePrivate::windowsItemFrame,
+ checkcol - 2 * QWindowsStylePrivate::windowsItemFrame,
+ mi.rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame));
+ drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
+ }
+ }
} else {
if (rule.hasDrawable() && !subRule.hasDrawable() && !(opt->state & QStyle::State_Selected)) {
mi.palette.setColor(QPalette::Window, Qt::transparent);
@@ -3668,7 +3696,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
}
if (!cb->currentText.isEmpty() && !cb->editable) {
drawItemText(p, editRect.adjusted(0, 0, 0, 0), Qt::AlignLeft | Qt::AlignVCenter, cb->palette,
- cb->state & State_Enabled, cb->currentText);
+ cb->state & State_Enabled, cb->currentText, QPalette::Text);
}
p->restore();
return;
@@ -4275,23 +4303,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
p->fillRect(v2->rect, v2->palette.alternateBase());
subRule.drawRule(p, opt->rect);
} else {
- QStyleOptionViewItemV2 v2Copy(*v2);
- if (v2->showDecorationSelected) {
- QRenderRule subRule2 = renderRule(w, opt, PseudoElement_ViewItem);
- if (v2->state & QStyle::State_Selected) {
- subRule2.configurePalette(&v2Copy.palette, QPalette::NoRole, QPalette::Highlight);
- } else if (v2->features & QStyleOptionViewItemV2::Alternate) {
- subRule2.configurePalette(&v2Copy.palette, QPalette::NoRole, QPalette::AlternateBase);
- } else if (subRule2.hasBackground()) {
- p->fillRect(v2->rect, subRule2.background()->brush);
- }
- } else if (v2->features & QStyleOptionViewItemV2::Alternate) {
- quint64 pc = v2->state & QStyle::State_Enabled ? PseudoClass_Enabled : PseudoClass_Disabled;
- pc |= PseudoClass_Alternate;
- QRenderRule subRule2 = renderRule(w, PseudoElement_ViewItem, pc);
- subRule2.configurePalette(&v2Copy.palette, QPalette::NoRole, QPalette::AlternateBase);
- }
- baseStyle()->drawPrimitive(pe, &v2Copy, p, w);
+ baseStyle()->drawPrimitive(pe, v2, p, w);
}
}
return;
@@ -4356,18 +4368,6 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
break;
case PE_PanelItemViewItem:
- if (!styleHint(SH_ItemView_ShowDecorationSelected, opt, w)) {
- rect = subElementRect(QStyle::SE_ItemViewItemText, opt, w)
- | subElementRect(QStyle::SE_ItemViewItemDecoration, opt, w)
- | subElementRect(QStyle::SE_ItemViewItemCheckIndicator, opt, w);
- }
- pseudoElement = PseudoElement_ViewItem;
- break;
-
- case PE_PanelItemViewRow:
- ParentStyle::drawPrimitive(pe, opt, p, w);
- if (!styleHint(SH_ItemView_ShowDecorationSelected, opt, w))
- return;
pseudoElement = PseudoElement_ViewItem;
break;
diff --git a/src/gui/styles/qstylesheetstyle_default.cpp b/src/gui/styles/qstylesheetstyle_default.cpp
index 406633e..f79f8e0 100644
--- a/src/gui/styles/qstylesheetstyle_default.cpp
+++ b/src/gui/styles/qstylesheetstyle_default.cpp
@@ -203,49 +203,6 @@ StyleSheet QStyleSheetStyle::getDefaultStyleSheet() const
ADD_STYLE_RULE;
}
- /*QLineEdit[style="QCleanlooksStyle"] {
- padding-top: 2px;
- padding-bottom: 2px;
- }*/
- if (baseStyle()->inherits("QCleanlooksStyle"))
- {
- SET_ELEMENT_NAME(QLatin1String("QLineEdit"));
- ADD_BASIC_SELECTOR;
- ADD_SELECTOR;
-
-
- SET_PROPERTY(QLatin1String("padding-top"), PaddingTop);
- ADD_VALUE(Value::Identifier, QString::fromLatin1("2px"));
- ADD_DECLARATION;
-
- SET_PROPERTY(QLatin1String("padding-bottom"), PaddingBottom);
- ADD_VALUE(Value::Identifier, QString::fromLatin1("2px"));
- ADD_DECLARATION;
-
- ADD_STYLE_RULE;
- }
-
- /*QLineEdit[style="QWindowsXPStyle"],
- QLineEdit[style="QWindowsVistaStyle"],
- QLineEdit[style="QGtkStyle"] {
- padding-top: 1px;
- padding-bottom: 1px;
- }*/
- if (baseStyle()->inherits("QWindowsXPStyle") || baseStyle()->inherits("QGtkStyle"))
- {
- SET_ELEMENT_NAME(QLatin1String("QLineEdit"));
-
- SET_PROPERTY(QLatin1String("padding-top"), PaddingTop);
- ADD_VALUE(Value::Identifier, QString::fromLatin1("1px"));
- ADD_DECLARATION;
-
- SET_PROPERTY(QLatin1String("padding-bottom"), PaddingBottom);
- ADD_VALUE(Value::Identifier, QString::fromLatin1("1px"));
- ADD_DECLARATION;
-
- ADD_STYLE_RULE;
- }
-
/*QFrame {
border: native;
}*/
diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp
index 5cf738e..f894b82 100644
--- a/src/gui/styles/qwindowsstyle.cpp
+++ b/src/gui/styles/qwindowsstyle.cpp
@@ -115,14 +115,6 @@ QT_BEGIN_INCLUDE_NAMESPACE
#include <limits.h>
QT_END_INCLUDE_NAMESPACE
-static const int windowsItemFrame = 2; // menu item frame width
-static const int windowsSepHeight = 9; // separator item height
-static const int windowsItemHMargin = 3; // menu item hor text margin
-static const int windowsItemVMargin = 2; // menu item ver text margin
-static const int windowsArrowHMargin = 6; // arrow horizontal margin
-static const int windowsRightBorder = 15; // right border on windows
-static const int windowsCheckMarkWidth = 12; // checkmarks width on windows
-
enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight };
/*
@@ -1847,7 +1839,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
bool act = menuitem->state & State_Selected;
// windows always has a check column, regardless whether we have an icon or not
- int checkcol = qMax(menuitem->maxIconWidth, windowsCheckMarkWidth);
+ int checkcol = qMax<int>(menuitem->maxIconWidth, QWindowsStylePrivate::windowsCheckMarkWidth);
QBrush fill = menuitem->palette.brush(act ? QPalette::Highlight : QPalette::Button);
p->fillRect(menuitem->rect.adjusted(0, 0, -1, 0), fill);
@@ -1903,8 +1895,10 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
newMi.state |= State_Enabled;
if (act)
newMi.state |= State_On;
- newMi.rect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x() + windowsItemFrame, menuitem->rect.y() + windowsItemFrame,
- checkcol - 2 * windowsItemFrame, menuitem->rect.height() - 2*windowsItemFrame));
+ newMi.rect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x() + QWindowsStylePrivate::windowsItemFrame,
+ menuitem->rect.y() + QWindowsStylePrivate::windowsItemFrame,
+ checkcol - 2 * QWindowsStylePrivate::windowsItemFrame,
+ menuitem->rect.height() - 2 * QWindowsStylePrivate::windowsItemFrame));
proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, widget);
}
p->setPen(act ? menuitem->palette.highlightedText().color() : menuitem->palette.buttonText().color());
@@ -1915,9 +1909,10 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
p->setPen(discol);
}
- int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ int xm = QWindowsStylePrivate::windowsItemFrame + checkcol + QWindowsStylePrivate::windowsItemHMargin;
int xpos = menuitem->rect.x() + xm;
- QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
+ QRect textRect(xpos, y + QWindowsStylePrivate::windowsItemVMargin,
+ w - xm - QWindowsStylePrivate::windowsRightBorder - tab + 1, h - 2 * QWindowsStylePrivate::windowsItemVMargin);
QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
QString s = menuitem->text;
if (!s.isEmpty()) { // draw text
@@ -1951,10 +1946,10 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai
p->restore();
}
if (menuitem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
- int dim = (h - 2 * windowsItemFrame) / 2;
+ int dim = (h - 2 * QWindowsStylePrivate::windowsItemFrame) / 2;
PrimitiveElement arrow;
arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
- xpos = x + w - windowsArrowHMargin - windowsItemFrame - dim;
+ xpos = x + w - QWindowsStylePrivate::windowsArrowHMargin - QWindowsStylePrivate::windowsItemFrame - dim;
QRect vSubMenuRect = visualRect(opt->direction, menuitem->rect, QRect(xpos, y + h / 2 - dim / 2, dim, dim));
QStyleOptionMenuItem newMI = *menuitem;
newMI.rect = vSubMenuRect;
@@ -2994,6 +2989,7 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp
#ifndef QT_NO_COMBOBOX
case CC_ComboBox:
if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
+ p->save();
QBrush editBrush = cmb->palette.brush(QPalette::Base);
if ((cmb->subControls & SC_ComboBoxFrame)) {
if (cmb->frame) {
@@ -3063,6 +3059,7 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp
proxy()->drawPrimitive(PE_FrameFocusRect, &focus, p, widget);
}
}
+ p->restore();
}
break;
#endif // QT_NO_COMBOBOX
@@ -3191,7 +3188,7 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
- sz = QSize(10, windowsSepHeight);
+ sz = QSize(10, QWindowsStylePrivate::windowsSepHeight);
}
else if (mi->icon.isNull()) {
sz.setHeight(sz.height() - 2);
@@ -3202,14 +3199,14 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
sz.setHeight(qMax(sz.height(),
mi->icon.actualSize(QSize(iconExtent, iconExtent)).height()
- + 2 * windowsItemFrame));
+ + 2 * QWindowsStylePrivate::windowsItemFrame));
}
int maxpmw = mi->maxIconWidth;
int tabSpacing = 20;
if (mi->text.contains(QLatin1Char('\t')))
w += tabSpacing;
else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
- w += 2 * windowsArrowHMargin;
+ w += 2 * QWindowsStylePrivate::windowsArrowHMargin;
else if (mi->menuItemType == QStyleOptionMenuItem::DefaultItem) {
// adjust the font and add the difference in size.
// it would be better if the font could be adjusted in the initStyleOption qmenu func!!
@@ -3220,9 +3217,9 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
w += fmBold.width(mi->text) - fm.width(mi->text);
}
- int checkcol = qMax(maxpmw, windowsCheckMarkWidth); // Windows always shows a check column
+ int checkcol = qMax<int>(maxpmw, QWindowsStylePrivate::windowsCheckMarkWidth); // Windows always shows a check column
w += checkcol;
- w += windowsRightBorder + 10;
+ w += QWindowsStylePrivate::windowsRightBorder + 10;
sz.setWidth(w);
}
break;
@@ -3230,7 +3227,7 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
#ifndef QT_NO_MENUBAR
case CT_MenuBarItem:
if (!sz.isEmpty())
- sz += QSize(windowsItemHMargin * 4, windowsItemVMargin * 2);
+ sz += QSize(QWindowsStylePrivate::windowsItemHMargin * 4, QWindowsStylePrivate::windowsItemVMargin * 2);
break;
#endif
// Otherwise, fall through
diff --git a/src/gui/styles/qwindowsstyle_p.h b/src/gui/styles/qwindowsstyle_p.h
index fb84dce..d81c82b 100644
--- a/src/gui/styles/qwindowsstyle_p.h
+++ b/src/gui/styles/qwindowsstyle_p.h
@@ -87,7 +87,17 @@ public:
QColor activeGradientCaptionColor;
QColor inactiveCaptionColor;
QColor inactiveGradientCaptionColor;
+
+ enum {
+ windowsItemFrame = 2, // menu item frame width
+ windowsSepHeight = 9, // separator item height
+ windowsItemHMargin = 3, // menu item hor text margin
+ windowsItemVMargin = 2, // menu item ver text margin
+ windowsArrowHMargin = 6, // arrow horizontal margin
+ windowsRightBorder = 15, // right border on windows
+ windowsCheckMarkWidth = 12 // checkmarks width on windows
};
+};
QT_END_NAMESPACE
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index 6db86bd..93b9fc6 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -1129,19 +1129,22 @@ static bool setFontWeightFromValue(const Value &value, QFont *font)
static bool setFontFamilyFromValues(const QVector<Value> &values, QFont *font, int start = 0)
{
QString family;
+ bool shouldAddSpace = false;
for (int i = start; i < values.count(); ++i) {
const Value &v = values.at(i);
if (v.type == Value::TermOperatorComma) {
family += QLatin1Char(',');
+ shouldAddSpace = false;
continue;
}
const QString str = v.variant.toString();
if (str.isEmpty())
break;
+ if (shouldAddSpace)
+ family += QLatin1Char(' ');
family += str;
- family += QLatin1Char(' ');
+ shouldAddSpace = true;
}
- family = family.simplified();
if (family.isEmpty())
return false;
font->setFamily(family);
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index fb8444e..7e93aa0 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -533,7 +533,13 @@ static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
// Vietnamese,
{ 0, 127 }, // same as latin1
// Other,
- { 126, 127 }
+ { 126, 127 },
+ // Ogham,
+ { 78, 127 },
+ // Runic,
+ { 79, 127 },
+ // Nko,
+ { 14, 127 },
};
#define SimplifiedChineseCsbBit 18
@@ -873,7 +879,8 @@ static const int scriptForWritingSystem[] = {
QUnicodeTables::Common, // Braille
QUnicodeTables::Common, // Symbol
QUnicodeTables::Ogham, // Ogham
- QUnicodeTables::Runic // Runic
+ QUnicodeTables::Runic, // Runic
+ QUnicodeTables::Nko // Nko
};
@@ -881,12 +888,12 @@ static const int scriptForWritingSystem[] = {
static inline bool requiresOpenType(int writingSystem)
{
return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
- || writingSystem == QFontDatabase::Khmer);
+ || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
}
static inline bool scriptRequiresOpenType(int script)
{
return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
- || script == QUnicodeTables::Khmer);
+ || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
}
#endif
@@ -1558,6 +1565,7 @@ QFontDatabase::QFontDatabase()
\value Other (the same as Symbol)
\value Ogham
\value Runic
+ \value Nko
\omitvalue WritingSystemsCount
*/
@@ -2232,6 +2240,9 @@ QString QFontDatabase::writingSystemName(WritingSystem writingSystem)
case Runic:
name = QT_TRANSLATE_NOOP("QFontDatabase", "Runic");
break;
+ case Nko:
+ name = QT_TRANSLATE_NOOP("QFontDatabase", "N'Ko");
+ break;
default:
Q_ASSERT_X(false, "QFontDatabase::writingSystemName", "invalid 'writingSystem' parameter");
break;
@@ -2445,6 +2456,12 @@ QString QFontDatabase::writingSystemSample(WritingSystem writingSystem)
sample += QChar(0x16a2);
sample += QChar(0x16a3);
break;
+ case Nko:
+ sample += QChar(0x7ca);
+ sample += QChar(0x7cb);
+ sample += QChar(0x7cc);
+ sample += QChar(0x7cd);
+ break;
default:
break;
}
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index e6dcfc9..37b5860 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -108,6 +108,7 @@ public:
Ogham,
Runic,
+ Nko,
WritingSystemsCount
};
diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp
index f184811..dd575f9 100644
--- a/src/gui/text/qfontdatabase_x11.cpp
+++ b/src/gui/text/qfontdatabase_x11.cpp
@@ -155,187 +155,187 @@ static const char writingSystems_for_xlfd_encoding[sizeof(xlfd_encoding)][QFontD
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso8859-2
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso8859-3
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso8859-4
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso8859-9
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso8859-10
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso8859-13
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso8859-14
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso8859-15
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// hp-roman8
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso8859-5
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// *-cp1251
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// koi8-ru
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// koi8-u
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// koi8-r
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso8859-7
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso8859-8
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// gb18030-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// gb18030.2000-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// gbk-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// gb2312.*-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// jisx0201*-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0 },
+ 0, 0 },
// jisx0208*-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 0 },
+ 0, 0 },
// ksc5601*-*
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 0 },
+ 0, 0 },
// big5hkscs-0
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0 },
+ 0, 0 },
// hkscs-1
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0 },
+ 0, 0 },
// big5*-*
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0 },
+ 0, 0 },
// tscii-*
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// tis620*-*
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso8859-11
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// mulelao-1
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// ethiopic-unicode
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0 },
+ 0, 0 },
// iso10646-1
{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
- 0 },
+ 0, 0 },
// unicode-*
{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
- 0 },
+ 0, 0 },
// *-symbol
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1 },
+ 1, 0 },
// *-fontspecific
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1 },
+ 1, 0 },
// fontspecific-*
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1 }
+ 1, 0 }
};
@@ -835,7 +835,8 @@ static const char *specialLanguages[] = {
"ko", // Hangul
"", // Ogham
"", // Runic
- "km" // Khmer
+ "km", // Khmer
+ "" // N'Ko
};
enum { SpecialLanguageCount = sizeof(specialLanguages) / sizeof(const char *) };
@@ -866,7 +867,8 @@ static const ushort specialChars[] = {
0, // Hangul
0x1681, // Ogham
0x16a0, // Runic
- 0 // Khmer
+ 0, // Khmer
+ 0x7ca // N'Ko
};
enum { SpecialCharCount = sizeof(specialChars) / sizeof(ushort) };
@@ -905,7 +907,8 @@ static const char *languageForWritingSystem[] = {
"vi", // Vietnamese
0, // Symbol
0, // Ogham
- 0 // Runic
+ 0, // Runic
+ 0 // N'Ko
};
enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
@@ -944,7 +947,8 @@ static const ushort sampleCharForWritingSystem[] = {
0, // Vietnamese
0, // Symbol
0x1681, // Ogham
- 0x16a0 // Runic
+ 0x16a0, // Runic
+ 0x7ca // N'Ko
};
enum { SampleCharCount = sizeof(sampleCharForWritingSystem) / sizeof(ushort) };
@@ -984,7 +988,8 @@ static const char *openType[] = {
0, // Vietnamese
0, // Symbol
0, // Ogham
- 0 // Runic
+ 0, // Runic
+ "nko " // N'Ko
};
enum { OpenTypeCount = sizeof(openType) / sizeof(const char *) };
@@ -1472,7 +1477,7 @@ void qt_addPatternProps(FcPattern *pattern, int screen, int script, const QFontD
!(request.styleStrategy & QFont::NoAntialias));
}
- if (script != QUnicodeTables::Common) {
+ if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
Q_ASSERT(script < QUnicodeTables::ScriptCount);
FcLangSet *ls = FcLangSetCreate();
FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
@@ -1615,7 +1620,7 @@ static QFontEngine *tryPatternLoad(FcPattern *p, int screen,
goto done;
if (!FcCharSetHasChar(cs, specialChars[script]))
goto done;
- } else {
+ } else if (*specialLanguages[script] != '\0'){
FcLangSet *langSet = 0;
if (FcPatternGetLangSet(match, FC_LANG, 0, &langSet) != FcResultMatch)
goto done;
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index 3f6545c..2bfe33c 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -911,7 +911,7 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
break;
case QEvent::MouseButtonPress: {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
- d->mousePressEvent(ev->button(), matrix.map(ev->pos()), ev->modifiers(),
+ d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(),
ev->buttons(), ev->globalPos());
break; }
case QEvent::MouseMove: {
@@ -979,7 +979,7 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte
#ifndef QT_NO_GRAPHICSVIEW
case QEvent::GraphicsSceneMousePress: {
QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
- d->mousePressEvent(ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
+ d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
ev->screenPos());
break; }
case QEvent::GraphicsSceneMouseMove: {
@@ -1296,7 +1296,9 @@ QVariant QTextControl::loadResource(int type, const QUrl &name)
void QTextControlPrivate::_q_updateBlock(const QTextBlock &block)
{
Q_Q(QTextControl);
- emit q->updateRequest(q->blockBoundingRect(block));
+ QRectF br = q->blockBoundingRect(block);
+ br.setRight(qreal(INT_MAX)); // the block might have shrunk
+ emit q->updateRequest(br);
}
QRectF QTextControlPrivate::rectForPosition(int position) const
@@ -1465,7 +1467,7 @@ QRectF QTextControl::selectionRect() const
return selectionRect(d->cursor);
}
-void QTextControlPrivate::mousePressEvent(Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
+void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
Qt::MouseButtons buttons, const QPoint &globalPos)
{
Q_Q(QTextControl);
@@ -1479,11 +1481,11 @@ void QTextControlPrivate::mousePressEvent(Qt::MouseButton button, const QPointF
cursor.clearSelection();
}
}
- if (!(button & Qt::LeftButton))
- return;
-
- if (!((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable)))
- return;
+ if (!(button & Qt::LeftButton) ||
+ !((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable))) {
+ e->ignore();
+ return;
+ }
cursorIsFocusIndicator = false;
const QTextCursor oldSelection = cursor;
@@ -1507,8 +1509,10 @@ void QTextControlPrivate::mousePressEvent(Qt::MouseButton button, const QPointF
trippleClickTimer.stop();
} else {
int cursorPos = q->hitTest(pos, Qt::FuzzyHit);
- if (cursorPos == -1)
+ if (cursorPos == -1) {
+ e->ignore();
return;
+ }
#if !defined(QT_NO_IM)
QTextLayout *layout = cursor.block().layout();
@@ -1519,8 +1523,10 @@ void QTextControlPrivate::mousePressEvent(Qt::MouseButton button, const QPointF
button, buttons, modifiers);
ctx->mouseHandler(cursorPos - cursor.position(), &ev);
}
- if (!layout->preeditAreaText().isEmpty())
+ if (!layout->preeditAreaText().isEmpty()) {
+ e->ignore();
return;
+ }
}
#endif
if (modifiers == Qt::ShiftModifier) {
@@ -1831,7 +1837,8 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
e->ignore();
return;
}
- bool isGettingInput = !e->commitString().isEmpty() || !e->preeditString().isEmpty()
+ bool isGettingInput = !e->commitString().isEmpty()
+ || e->preeditString() != cursor.block().layout()->preeditAreaText()
|| e->replacementLength() > 0;
if (isGettingInput) {
diff --git a/src/gui/text/qtextcontrol_p_p.h b/src/gui/text/qtextcontrol_p_p.h
index ca9db9f..66459f6 100644
--- a/src/gui/text/qtextcontrol_p_p.h
+++ b/src/gui/text/qtextcontrol_p_p.h
@@ -131,10 +131,10 @@ public:
QString anchorForCursor(const QTextCursor &anchor) const;
void keyPressEvent(QKeyEvent *e);
- void mousePressEvent(Qt::MouseButton button, const QPointF &pos,
+ void mousePressEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos,
Qt::KeyboardModifiers modifiers,
Qt::MouseButtons buttons,
- const QPoint &globalPos = QPoint());
+ const QPoint &globalPos);
void mouseMoveEvent(Qt::MouseButtons buttons, const QPointF &pos);
void mouseReleaseEvent(Qt::MouseButton button, const QPointF &pos);
void mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos);
diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp
index eeccc72..54be53b 100644
--- a/src/gui/text/qtextengine_mac.cpp
+++ b/src/gui/text/qtextengine_mac.cpp
@@ -594,53 +594,50 @@ void QTextEngine::shapeTextMac(int item) const
str = reinterpret_cast<const QChar *>(uc);
}
- while (true) {
- ensureSpace(num_glyphs);
- num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used;
-
- QGlyphLayout g = availableGlyphs(&si);
- g.numGlyphs = num_glyphs;
- unsigned short *log_clusters = logClusters(&si);
+ ensureSpace(num_glyphs);
+ num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used;
- if (fe->stringToCMap(str,
- len,
- &g,
- &num_glyphs,
- flags,
- log_clusters,
- attributes())) {
+ QGlyphLayout g = availableGlyphs(&si);
+ g.numGlyphs = num_glyphs;
+ unsigned short *log_clusters = logClusters(&si);
- heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs);
- break;
- }
+ bool stringToCMapFailed = false;
+ if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) {
+ ensureSpace(num_glyphs);
+ stringToCMapFailed = fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
+ attributes());
}
- si.num_glyphs = num_glyphs;
+ if (!stringToCMapFailed) {
+ heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs);
- layoutData->used += si.num_glyphs;
+ si.num_glyphs = num_glyphs;
- QGlyphLayout g = shapedGlyphs(&si);
+ layoutData->used += si.num_glyphs;
- if (si.analysis.script == QUnicodeTables::Arabic) {
- QVarLengthArray<QArabicProperties> props(len + 2);
- QArabicProperties *properties = props.data();
- int f = si.position;
- int l = len;
- if (f > 0) {
- --f;
- ++l;
- ++properties;
- }
- if (f + l < layoutData->string.length()) {
- ++l;
- }
- qt_getArabicProperties((const unsigned short *)(layoutData->string.unicode()+f), l, props.data());
+ QGlyphLayout g = shapedGlyphs(&si);
- unsigned short *log_clusters = logClusters(&si);
+ if (si.analysis.script == QUnicodeTables::Arabic) {
+ QVarLengthArray<QArabicProperties> props(len + 2);
+ QArabicProperties *properties = props.data();
+ int f = si.position;
+ int l = len;
+ if (f > 0) {
+ --f;
+ ++l;
+ ++properties;
+ }
+ if (f + l < layoutData->string.length()) {
+ ++l;
+ }
+ qt_getArabicProperties((const unsigned short *)(layoutData->string.unicode()+f), l, props.data());
- for (int i = 0; i < len; ++i) {
- int gpos = log_clusters[i];
- g.attributes[gpos].justification = properties[i].justification;
+ unsigned short *log_clusters = logClusters(&si);
+
+ for (int i = 0; i < len; ++i) {
+ int gpos = log_clusters[i];
+ g.attributes[gpos].justification = properties[i].justification;
+ }
}
}
diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp
index 1690d87..fd84949 100644
--- a/src/gui/util/qdesktopservices.cpp
+++ b/src/gui/util/qdesktopservices.cpp
@@ -293,17 +293,6 @@ void QDesktopServices::unsetUrlHandler(const QString &scheme)
have desktop concept, DesktopLocation returns same path as DocumentsLocation.
Rest of the standard locations point to folder on same drive with executable, except
that if executable is in ROM the folder from C drive is returned.
-
- \note On Mac OS X, DataLocation does not include QCoreApplication::organizationName.
- Use code like this to add it:
-
- \code
- QString location = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
- #ifdef Q_WS_MAC
- location.insert(location.count() - QCoreApplication::applicationName().count(),
- QCoreApplication::organizationName() + "/");
- #endif
- \endcode
*/
/*!
diff --git a/src/gui/util/qdesktopservices_mac.cpp b/src/gui/util/qdesktopservices_mac.cpp
index 0626e0a..23f9e60 100644
--- a/src/gui/util/qdesktopservices_mac.cpp
+++ b/src/gui/util/qdesktopservices_mac.cpp
@@ -153,9 +153,12 @@ QString QDesktopServices::storageLocation(StandardLocation type)
QString path = getFullPath(ref);
- QString appName = QCoreApplication::applicationName();
- if (!appName.isEmpty() && (type == DataLocation || type == CacheLocation))
- path += QLatin1Char('/') + appName;
+ if (type == DataLocation || type == CacheLocation) {
+ if (QCoreApplication::organizationName().isEmpty() == false)
+ path += QLatin1Char('/') + QCoreApplication::organizationName();
+ if (QCoreApplication::applicationName().isEmpty() == false)
+ path += QLatin1Char('/') + QCoreApplication::applicationName();
+ }
return path;
}
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp
index 0896256..7d81d5a 100644
--- a/src/gui/widgets/qabstractscrollarea.cpp
+++ b/src/gui/widgets/qabstractscrollarea.cpp
@@ -293,13 +293,16 @@ void QAbstractScrollAreaPrivate::init()
q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layoutChildren();
+ viewport->grabGesture(Qt::PanGesture);
}
#ifdef Q_WS_WIN
void QAbstractScrollAreaPrivate::setSingleFingerPanEnabled(bool on)
{
singleFingerPanEnabled = on;
- winSetupGestures();
+ QWidgetPrivate *dd = static_cast<QWidgetPrivate *>(QObjectPrivate::get(viewport));
+ if (dd)
+ dd->winSetupGestures();
}
#endif // Q_WS_WIN
@@ -539,6 +542,7 @@ void QAbstractScrollArea::setViewport(QWidget *widget)
d->viewport->setParent(this);
d->viewport->setFocusProxy(this);
d->viewport->installEventFilter(d->viewportFilter.data());
+ d->viewport->grabGesture(Qt::PanGesture);
d->layoutChildren();
if (isVisible())
d->viewport->show();
@@ -935,6 +939,26 @@ bool QAbstractScrollArea::event(QEvent *e)
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
return false;
+ case QEvent::Gesture:
+ {
+ QGestureEvent *ge = static_cast<QGestureEvent *>(e);
+ QPanGesture *g = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture));
+ if (g) {
+ QScrollBar *hBar = horizontalScrollBar();
+ QScrollBar *vBar = verticalScrollBar();
+ QPointF delta = g->lastOffset();
+ if (!delta.isNull()) {
+ if (QApplication::isRightToLeft())
+ delta.rx() *= -1;
+ int newX = hBar->value() - delta.x();
+ int newY = vBar->value() - delta.y();
+ hBar->setValue(newX);
+ vBar->setValue(newY);
+ }
+ return true;
+ }
+ return false;
+ }
case QEvent::StyleChange:
case QEvent::LayoutDirectionChange:
case QEvent::ApplicationLayoutDirectionChange:
@@ -990,6 +1014,8 @@ bool QAbstractScrollArea::viewportEvent(QEvent *e)
#endif
return QFrame::event(e);
case QEvent::LayoutRequest:
+ case QEvent::Gesture:
+ case QEvent::GestureOverride:
return event(e);
default:
break;
@@ -1266,11 +1292,13 @@ void QAbstractScrollAreaPrivate::_q_vslide(int y)
void QAbstractScrollAreaPrivate::_q_showOrHideScrollBars()
{
layoutChildren();
-#ifdef Q_OS_WIN
+#ifdef Q_WS_WIN
// Need to re-subscribe to gestures as the content changes to make sure we
// enable/disable panning when needed.
- winSetupGestures();
-#endif // Q_OS_WIN
+ QWidgetPrivate *dd = static_cast<QWidgetPrivate *>(QObjectPrivate::get(viewport));
+ if (dd)
+ dd->winSetupGestures();
+#endif // Q_WS_WIN
}
QPoint QAbstractScrollAreaPrivate::contentsOffset() const
@@ -1335,25 +1363,6 @@ void QAbstractScrollArea::setupViewport(QWidget *viewport)
Q_UNUSED(viewport);
}
-//void QAbstractScrollAreaPrivate::_q_gestureTriggered()
-//{
-// Q_Q(QAbstractScrollArea);
-// QPanGesture *g = qobject_cast<QPanGesture*>(q->sender());
-// if (!g)
-// return;
-// QScrollBar *hBar = q->horizontalScrollBar();
-// QScrollBar *vBar = q->verticalScrollBar();
-// QSizeF delta = g->lastOffset();
-// if (!delta.isNull()) {
-// if (QApplication::isRightToLeft())
-// delta.rwidth() *= -1;
-// int newX = hBar->value() - delta.width();
-// int newY = vBar->value() - delta.height();
-// hbar->setValue(newX);
-// vbar->setValue(newY);
-// }
-//}
-
QT_END_NAMESPACE
#include "moc_qabstractscrollarea.cpp"
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index 1879db4..bd1d8ba 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -1111,6 +1111,32 @@ void QComboBoxPrivate::updateLineEditGeometry()
lineEdit->setGeometry(editRect);
}
+Qt::MatchFlags QComboBoxPrivate::matchFlags() const
+{
+ // Base how duplicates are determined on the autocompletion case sensitivity
+ Qt::MatchFlags flags = Qt::MatchFixedString;
+#ifndef QT_NO_COMPLETER
+ if (!lineEdit->completer() || lineEdit->completer()->caseSensitivity() == Qt::CaseSensitive)
+#endif
+ flags |= Qt::MatchCaseSensitive;
+ return flags;
+}
+
+
+void QComboBoxPrivate::_q_editingFinished()
+{
+ Q_Q(QComboBox);
+ if (lineEdit && !lineEdit->text().isEmpty()) {
+ //here we just check if the current item was entered
+ const int index = q_func()->findText(lineEdit->text(), matchFlags());
+ if (index != -1 && itemText(currentIndex) != lineEdit->text()) {
+ q->setCurrentIndex(index);
+ emitActivated(currentIndex);
+ }
+ }
+
+}
+
void QComboBoxPrivate::_q_returnPressed()
{
Q_Q(QComboBox);
@@ -1123,13 +1149,7 @@ void QComboBoxPrivate::_q_returnPressed()
// check for duplicates (if not enabled) and quit
int index = -1;
if (!duplicatesEnabled) {
- // Base how duplicates are determined on the autocompletion case sensitivity
- Qt::MatchFlags flags = Qt::MatchFixedString;
-#ifndef QT_NO_COMPLETER
- if (!lineEdit->completer() || lineEdit->completer()->caseSensitivity() == Qt::CaseSensitive)
-#endif
- flags |= Qt::MatchCaseSensitive;
- index = q->findText(text, flags);
+ index = q->findText(text, matchFlags());
if (index != -1) {
q->setCurrentIndex(index);
emitActivated(currentIndex);
@@ -1664,6 +1684,7 @@ void QComboBox::setLineEdit(QLineEdit *edit)
if (d->lineEdit->parent() != this)
d->lineEdit->setParent(this);
connect(d->lineEdit, SIGNAL(returnPressed()), this, SLOT(_q_returnPressed()));
+ connect(d->lineEdit, SIGNAL(editingFinished()), this, SLOT(_q_editingFinished()));
connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(editTextChanged(QString)));
#ifdef QT3_SUPPORT
connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged(QString)));
@@ -1960,7 +1981,7 @@ void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi)
if (lineEdit) {
QString newText = q->itemText(currentIndex.row());
if (lineEdit->text() != newText)
- lineEdit->setText(q->itemText(currentIndex.row()));
+ lineEdit->setText(newText);
updateLineEditGeometry();
}
if (indexChanged) {
diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h
index 0652594..5d5ea21 100644
--- a/src/gui/widgets/qcombobox.h
+++ b/src/gui/widgets/qcombobox.h
@@ -304,6 +304,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_itemSelected(const QModelIndex &item))
Q_PRIVATE_SLOT(d_func(), void _q_emitHighlighted(const QModelIndex &))
Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentIndexChanged(const QModelIndex &index))
+ Q_PRIVATE_SLOT(d_func(), void _q_editingFinished())
Q_PRIVATE_SLOT(d_func(), void _q_returnPressed())
Q_PRIVATE_SLOT(d_func(), void _q_resetButton())
Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &, const QModelIndex &))
diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h
index fe42c47..f6ba57c 100644
--- a/src/gui/widgets/qcombobox_p.h
+++ b/src/gui/widgets/qcombobox_p.h
@@ -342,6 +342,8 @@ public:
void init();
QComboBoxPrivateContainer* viewContainer();
void updateLineEditGeometry();
+ Qt::MatchFlags matchFlags() const;
+ void _q_editingFinished();
void _q_returnPressed();
void _q_complete();
void _q_itemSelected(const QModelIndex &item);
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index 8f17e98..2914164 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -401,7 +401,8 @@ void QLineControl::moveCursor(int pos, bool mark)
void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
{
int priorState = 0;
- bool isGettingInput = !event->commitString().isEmpty() || !event->preeditString().isEmpty()
+ bool isGettingInput = !event->commitString().isEmpty()
+ || event->preeditString() != preeditAreaText()
|| event->replacementLength() > 0;
bool cursorPositionChanged = false;
@@ -1510,6 +1511,18 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
}
#endif // QT_NO_COMPLETER
+ if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
+ if (hasAcceptableInput() || fixup()) {
+ emit accepted();
+ emit editingFinished();
+ }
+ if (inlineCompletionAccepted)
+ event->accept();
+ else
+ event->ignore();
+ return;
+ }
+
if (echoMode() == QLineEdit::PasswordEchoOnEdit
&& !passwordEchoEditing()
&& !isReadOnly()
@@ -1530,17 +1543,6 @@ void QLineControl::processKeyEvent(QKeyEvent* event)
clear();
}
- if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
- if (hasAcceptableInput() || fixup()) {
- emit accepted();
- emit editingFinished();
- }
- if (inlineCompletionAccepted)
- event->accept();
- else
- event->ignore();
- return;
- }
bool unknown = false;
if (false) {
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index 1b5d1cd..cc39b7f 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -273,7 +273,7 @@ void QMenuPrivate::updateActionRects() const
for (int i = 0; i < actions.count(); ++i) {
QAction *action = actions.at(i);
- if (action->isSeparator() || !action->isVisible() || widgetItems.at(i))
+ if (action->isSeparator() || !action->isVisible() || widgetItems.contains(action))
continue;
//..and some members
hasCheckableItems |= action->isCheckable();
@@ -301,7 +301,7 @@ void QMenuPrivate::updateActionRects() const
const QFontMetrics &fm = opt.fontMetrics;
QSize sz;
- if (QWidget *w = widgetItems.at(i)) {
+ if (QWidget *w = widgetItems.value(action)) {
sz = w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize());
} else {
//calc what I think the size is..
@@ -370,7 +370,7 @@ void QMenuPrivate::updateActionRects() const
rect.setWidth(max_column_width); //uniform width
//we need to update the widgets geometry
- if (QWidget *widget = widgetItems.at(i)) {
+ if (QWidget *widget = widgetItems.value(actions.at(i))) {
widget->setGeometry(rect);
widget->setVisible(actions.at(i)->isVisible());
}
@@ -583,8 +583,7 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason
q->update(actionRect(action));
if (reason == SelectedFromKeyboard) {
- const int actionIndex = actions.indexOf(action);
- QWidget *widget = widgetItems.at(actionIndex);
+ QWidget *widget = widgetItems.value(action);
if (widget) {
if (widget->focusPolicy() != Qt::NoFocus)
widget->setFocus(Qt::TabFocusReason);
@@ -800,7 +799,7 @@ void QMenuPrivate::scrollMenu(QAction *action, QMenuScroller::ScrollLocation loc
current.moveTop(current.top() + delta);
//we need to update the widgets geometry
- if (QWidget *w = widgetItems.at(i))
+ if (QWidget *w = widgetItems.value(actions.at(i)))
w->setGeometry(current);
}
}
@@ -1392,11 +1391,12 @@ QMenu::QMenu(QMenuPrivate &dd, QWidget *parent)
QMenu::~QMenu()
{
Q_D(QMenu);
- for (int i = 0; i < d->widgetItems.count(); ++i) {
- if (QWidget *widget = d->widgetItems.at(i)) {
- QWidgetAction *action = static_cast<QWidgetAction *>(d->actions.at(i));
+ QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin();
+ for (; it != d->widgetItems.end(); ++it) {
+ if (QWidget *widget = it.value()) {
+ QWidgetAction *action = static_cast<QWidgetAction *>(it.key());
action->releaseWidget(widget);
- d->widgetItems[i] = 0;
+ *it = 0;
}
}
@@ -1878,9 +1878,11 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
if(snapToMouse) //position flowing left from the mouse
pos.setX(mouse.x()-size.width());
+#ifndef QT_NO_MENUBAR
//if in a menubar, it should be right-aligned
if (qobject_cast<QMenuBar*>(d->causedPopup.widget))
pos.rx() -= size.width();
+#endif //QT_NO_MENUBAR
if (pos.x() < screen.left()+desktopFrame)
pos.setX(qMax(p.x(), screen.left()+desktopFrame));
@@ -2151,7 +2153,7 @@ void QMenu::paintEvent(QPaintEvent *e)
QAction *action = d->actions.at(i);
QRect adjustedActionRect = d->actionRects.at(i);
if (!e->rect().intersects(adjustedActionRect)
- || d->widgetItems.at(i))
+ || d->widgetItems.value(action))
continue;
//set the clip region to be extra safe (and adjust for the scrollers)
QRegion adjustedActionReg(adjustedActionRect);
@@ -2862,25 +2864,20 @@ void QMenu::actionEvent(QActionEvent *e)
connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
}
- QWidget *widget = 0;
- if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action()))
- widget = wa->requestWidget(this);
-
- int index = d->actions.indexOf(e->action());
- Q_ASSERT(index != -1);
- d->widgetItems.insert(index, widget);
-
+ if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
+ QWidget *widget = wa->requestWidget(this);
+ if (widget)
+ d->widgetItems.insert(wa, widget);
+ }
} else if (e->type() == QEvent::ActionRemoved) {
e->action()->disconnect(this);
if (e->action() == d->currentAction)
d->currentAction = 0;
- int index = d->actions.indexOf(e->before()) + 1;
if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
- if (QWidget *widget = d->widgetItems.at(index))
+ if (QWidget *widget = d->widgetItems.value(wa))
wa->releaseWidget(widget);
}
- Q_ASSERT(index != -1);
- d->widgetItems.removeAt(index);
+ d->widgetItems.remove(e->action());
}
#ifdef Q_WS_MAC
diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm
index b238faf..9510cc6 100644
--- a/src/gui/widgets/qmenu_mac.mm
+++ b/src/gui/widgets/qmenu_mac.mm
@@ -1191,7 +1191,7 @@ QMenuPrivate::QMacMenuPrivate::addAction(QMacMenuAction *action, QMacMenuAction
#endif
}
- QWidget *widget = qmenu ? qmenu->widgetItems.value(qmenu->actions.indexOf(action->action)) : 0;
+ QWidget *widget = qmenu ? qmenu->widgetItems.value(action->action) : 0;
if (widget) {
#ifndef QT_MAC_USE_COCOA
ChangeMenuAttributes(action->menu, kMenuAttrDoNotCacheImage, 0);
diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h
index 9348f7b..a5bde7c 100644
--- a/src/gui/widgets/qmenu_p.h
+++ b/src/gui/widgets/qmenu_p.h
@@ -190,7 +190,7 @@ public:
QRect actionRect(QAction *) const;
mutable QVector<QRect> actionRects;
- mutable QWidgetList widgetItems;
+ mutable QHash<QAction *, QWidget *> widgetItems;
void updateActionRects() const;
QRect popupGeometry(const QWidget *widget) const;
QRect popupGeometry(int screen = -1) const;
diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp
index bb93546..0de7421 100644
--- a/src/gui/widgets/qplaintextedit.cpp
+++ b/src/gui/widgets/qplaintextedit.cpp
@@ -730,9 +730,6 @@ QPlainTextEditPrivate::QPlainTextEditPrivate()
backgroundVisible = false;
centerOnScroll = false;
inDrag = false;
-#ifdef Q_WS_WIN
- singleFingerPanEnabled = true;
-#endif
}
@@ -789,6 +786,9 @@ void QPlainTextEditPrivate::init(const QString &txt)
viewport->setCursor(Qt::IBeamCursor);
#endif
originalOffsetY = 0;
+#ifdef Q_WS_WIN
+ setSingleFingerPanEnabled(true);
+#endif
}
void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
@@ -1450,6 +1450,29 @@ bool QPlainTextEdit::event(QEvent *e)
d->sendControlEvent(e);
}
#endif
+ else if (e->type() == QEvent::Gesture) {
+ QGestureEvent *ge = static_cast<QGestureEvent *>(e);
+ QPanGesture *g = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture));
+ if (g) {
+ QScrollBar *hBar = horizontalScrollBar();
+ QScrollBar *vBar = verticalScrollBar();
+ if (g->state() == Qt::GestureStarted)
+ d->originalOffsetY = vBar->value();
+ QPointF offset = g->offset();
+ if (!offset.isNull()) {
+ if (QApplication::isRightToLeft())
+ offset.rx() *= -1;
+ // QPlainTextEdit scrolls by lines only in vertical direction
+ QFontMetrics fm(document()->defaultFont());
+ int lineHeight = fm.height();
+ int newX = hBar->value() - g->lastOffset().x();
+ int newY = d->originalOffsetY - offset.y()/lineHeight;
+ hBar->setValue(newX);
+ vBar->setValue(newY);
+ }
+ }
+ return true;
+ }
return QAbstractScrollArea::event(e);
}
@@ -2929,30 +2952,6 @@ QAbstractTextDocumentLayout::PaintContext QPlainTextEdit::getPaintContext() cons
(\a available is true) or unavailable (\a available is false).
*/
-//void QPlainTextEditPrivate::_q_gestureTriggered()
-//{
-// Q_Q(QPlainTextEdit);
-// QPanGesture *g = qobject_cast<QPanGesture*>(q->sender());
-// if (!g)
-// return;
-// QScrollBar *hBar = q->horizontalScrollBar();
-// QScrollBar *vBar = q->verticalScrollBar();
-// if (g->state() == Qt::GestureStarted)
-// originalOffsetY = vBar->value();
-// QSizeF totalOffset = g->totalOffset();
-// if (!totalOffset.isNull()) {
-// if (QApplication::isRightToLeft())
-// totalOffset.rwidth() *= -1;
-// // QPlainTextEdit scrolls by lines only in vertical direction
-// QFontMetrics fm(q->document()->defaultFont());
-// int lineHeight = fm.height();
-// int newX = hBar->value() - g->lastOffset().width();
-// int newY = originalOffsetY - totalOffset.height()/lineHeight;
-// hbar->setValue(newX);
-// vbar->setValue(newY);
-// }
-//}
-
QT_END_NAMESPACE
#include "moc_qplaintextedit.cpp"
diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp
index d995e0f..88502e3 100644
--- a/src/gui/widgets/qtextedit.cpp
+++ b/src/gui/widgets/qtextedit.cpp
@@ -116,9 +116,6 @@ QTextEditPrivate::QTextEditPrivate()
preferRichText = false;
showCursorOnInitialShow = true;
inDrag = false;
-#ifdef Q_WS_WIN
- setSingleFingerPanEnabled(true);
-#endif
}
void QTextEditPrivate::createAutoBulletList()
@@ -186,6 +183,9 @@ void QTextEditPrivate::init(const QString &html)
#ifndef QT_NO_CURSOR
viewport->setCursor(Qt::IBeamCursor);
#endif
+#ifdef Q_WS_WIN
+ setSingleFingerPanEnabled(true);
+#endif
}
void QTextEditPrivate::_q_repaintContents(const QRectF &contentsRect)
diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp
index bdd3c75..13ee346 100644
--- a/src/gui/widgets/qwidgetanimator.cpp
+++ b/src/gui/widgets/qwidgetanimator.cpp
@@ -88,8 +88,6 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo
const QRect final_geometry = _final_geometry.isValid() || widget->isWindow() ? _final_geometry :
QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size());
- if (r == final_geometry)
- return; //the widget is already where it should be
#ifndef QT_NO_ANIMATION
AnimationMap::const_iterator it = m_animation_map.constFind(widget);
if (it != m_animation_map.constEnd() && (*it)->endValue().toRect() == final_geometry)
@@ -116,9 +114,4 @@ bool QWidgetAnimator::animating() const
return !m_animation_map.isEmpty();
}
-bool QWidgetAnimator::animating(QWidget *widget) const
-{
- return m_animation_map.contains(widget);
-}
-
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h
index 68d9344..095380f 100644
--- a/src/gui/widgets/qwidgetanimator_p.h
+++ b/src/gui/widgets/qwidgetanimator_p.h
@@ -70,7 +70,6 @@ public:
QWidgetAnimator(QMainWindowLayout *layout);
void animate(QWidget *widget, const QRect &final_geometry, bool animate);
bool animating() const;
- bool animating(QWidget *widget) const;
void abort(QWidget *widget);