summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/dialogs/qcolordialog.cpp21
-rw-r--r--src/gui/dialogs/qcolordialog_mac.mm4
-rw-r--r--src/gui/dialogs/qcolordialog_p.h1
-rw-r--r--src/gui/dialogs/qdialog.cpp22
-rw-r--r--src/gui/dialogs/qfiledialog.cpp24
-rw-r--r--src/gui/dialogs/qfiledialog_mac.mm3
-rw-r--r--src/gui/dialogs/qfiledialog_p.h24
-rw-r--r--src/gui/dialogs/qfontdialog_mac.mm2
-rw-r--r--src/gui/dialogs/qprintdialog_mac.mm6
-rw-r--r--src/gui/dialogs/qprintdialog_win.cpp7
-rw-r--r--src/gui/effects/qgraphicseffect.cpp271
-rw-r--r--src/gui/effects/qgraphicseffect.h51
-rw-r--r--src/gui/effects/qgraphicseffect_p.h12
-rw-r--r--src/gui/egl/qeglproperties.cpp4
-rw-r--r--src/gui/embedded/qscreenvfb_qws.cpp8
-rw-r--r--src/gui/embedded/qsoundqss_qws.cpp11
-rw-r--r--src/gui/embedded/qvfbhdr.h35
-rw-r--r--src/gui/embedded/qwscommand_qws_p.h2
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.cpp19
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.h2
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.cpp600
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.h59
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp250
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h15
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h3
-rw-r--r--src/gui/graphicsview/qgraphicsproxywidget.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp279
-rw-r--r--src/gui/graphicsview/qgraphicsscene.h1
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h8
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp28
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp8
-rw-r--r--src/gui/graphicsview/qsimplex_p.cpp54
-rw-r--r--src/gui/graphicsview/qsimplex_p.h26
-rw-r--r--src/gui/image/qicon.cpp10
-rw-r--r--src/gui/image/qiconloader.cpp88
-rw-r--r--src/gui/image/qimage_p.h2
-rw-r--r--src/gui/image/qpixmap_s60.cpp64
-rw-r--r--src/gui/image/qpixmap_s60_p.h4
-rw-r--r--src/gui/image/qpixmap_x11.cpp47
-rw-r--r--src/gui/image/qpixmap_x11_p.h2
-rw-r--r--src/gui/image/qpixmapdata_p.h1
-rw-r--r--src/gui/image/qpixmapfilter.cpp18
-rw-r--r--src/gui/image/qpixmapfilter_p.h9
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp20
-rw-r--r--src/gui/inputmethod/qwininputcontext_p.h13
-rw-r--r--src/gui/inputmethod/qwininputcontext_win.cpp2
-rw-r--r--src/gui/inputmethod/qximinputcontext_x11.cpp2
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp43
-rw-r--r--src/gui/itemviews/qabstractitemview.h5
-rw-r--r--src/gui/itemviews/qabstractitemview_p.h9
-rw-r--r--src/gui/itemviews/qfileiconprovider.cpp20
-rw-r--r--src/gui/itemviews/qtableview.cpp608
-rw-r--r--src/gui/itemviews/qtableview.h4
-rw-r--r--src/gui/itemviews/qtableview_p.h25
-rw-r--r--src/gui/kernel/kernel.pri25
-rw-r--r--src/gui/kernel/qapplication.cpp156
-rw-r--r--src/gui/kernel/qapplication.h5
-rw-r--r--src/gui/kernel/qapplication_mac.mm38
-rw-r--r--src/gui/kernel/qapplication_p.h23
-rw-r--r--src/gui/kernel/qapplication_qws.cpp19
-rw-r--r--src/gui/kernel/qapplication_s60.cpp78
-rw-r--r--src/gui/kernel/qapplication_win.cpp133
-rw-r--r--src/gui/kernel/qapplication_x11.cpp51
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm20
-rw-r--r--src/gui/kernel/qcursor_s60.cpp24
-rw-r--r--src/gui/kernel/qdnd_s60.cpp4
-rw-r--r--src/gui/kernel/qdnd_x11.cpp4
-rw-r--r--src/gui/kernel/qevent.cpp132
-rw-r--r--src/gui/kernel/qevent.h34
-rw-r--r--src/gui/kernel/qeventdispatcher_mac.mm2
-rw-r--r--src/gui/kernel/qformlayout.cpp2
-rw-r--r--src/gui/kernel/qgesture.cpp446
-rw-r--r--src/gui/kernel/qgesture.h150
-rw-r--r--src/gui/kernel/qgesture_p.h76
-rw-r--r--src/gui/kernel/qgesturemanager.cpp467
-rw-r--r--src/gui/kernel/qgesturemanager_p.h125
-rw-r--r--src/gui/kernel/qgesturerecognizer.cpp194
-rw-r--r--src/gui/kernel/qgesturerecognizer.h93
-rw-r--r--src/gui/kernel/qguifunctions_wince.cpp13
-rw-r--r--src/gui/kernel/qguiplatformplugin.cpp296
-rw-r--r--src/gui/kernel/qguiplatformplugin_p.h126
-rw-r--r--src/gui/kernel/qkde.cpp33
-rw-r--r--src/gui/kernel/qkde_p.h9
-rw-r--r--src/gui/kernel/qkeymapper_win.cpp29
-rw-r--r--src/gui/kernel/qkeysequence.cpp4
-rw-r--r--src/gui/kernel/qmacgesturerecognizer_mac.mm267
-rw-r--r--src/gui/kernel/qmacgesturerecognizer_mac_p.h103
-rw-r--r--src/gui/kernel/qsoftkeymanager.cpp3
-rw-r--r--src/gui/kernel/qsoftkeymanager_p.h2
-rw-r--r--src/gui/kernel/qstandardgestures.cpp772
-rw-r--r--src/gui/kernel/qstandardgestures.h174
-rw-r--r--src/gui/kernel/qstandardgestures_p.h77
-rw-r--r--src/gui/kernel/qt_s60_p.h5
-rw-r--r--src/gui/kernel/qtooltip.cpp2
-rw-r--r--src/gui/kernel/qwhatsthis.cpp2
-rw-r--r--src/gui/kernel/qwidget.cpp50
-rw-r--r--src/gui/kernel/qwidget.h8
-rw-r--r--src/gui/kernel/qwidget_p.h6
-rw-r--r--src/gui/kernel/qwidget_s60.cpp118
-rw-r--r--src/gui/kernel/qwidget_win.cpp31
-rw-r--r--src/gui/kernel/qwidget_wince.cpp28
-rw-r--r--src/gui/kernel/qwinnativepangesturerecognizer_win.cpp124
-rw-r--r--src/gui/kernel/qwinnativepangesturerecognizer_win_p.h73
-rw-r--r--src/gui/painting/qcolor.cpp29
-rw-r--r--src/gui/painting/qdrawutil.cpp457
-rw-r--r--src/gui/painting/qdrawutil.h75
-rw-r--r--src/gui/painting/qpaintengine_s60.cpp2
-rw-r--r--src/gui/painting/qpaintengine_x11.cpp1
-rw-r--r--src/gui/painting/qpaintengineex.cpp25
-rw-r--r--src/gui/painting/qpaintengineex_p.h6
-rw-r--r--src/gui/painting/qpen.cpp14
-rw-r--r--src/gui/painting/qprintengine_pdf.cpp2
-rw-r--r--src/gui/painting/qprintengine_ps.cpp1
-rw-r--r--src/gui/painting/qtransform.cpp2
-rw-r--r--src/gui/painting/qwindowsurface_raster.cpp20
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp5
-rw-r--r--src/gui/painting/qwindowsurface_x11.cpp5
-rw-r--r--src/gui/s60framework/qs60mainapplication.cpp47
-rw-r--r--src/gui/s60framework/qs60mainappui.cpp65
-rw-r--r--src/gui/s60framework/qs60mainappui.h2
-rw-r--r--src/gui/s60framework/qs60maindocument.cpp44
-rw-r--r--src/gui/s60framework/qs60maindocument.h2
-rw-r--r--src/gui/statemachine/qguistatemachine.cpp346
-rw-r--r--src/gui/styles/gtksymbols.cpp31
-rw-r--r--src/gui/styles/gtksymbols_p.h29
-rw-r--r--src/gui/styles/qcommonstyle.cpp56
-rw-r--r--src/gui/styles/qcommonstyle_p.h1
-rw-r--r--src/gui/styles/qplastiquestyle.cpp2
-rw-r--r--src/gui/styles/qs60style.cpp11
-rw-r--r--src/gui/styles/qs60style_s60.cpp18
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp2
-rw-r--r--src/gui/styles/qwindowsvistastyle.cpp22
-rw-r--r--src/gui/styles/qwindowsvistastyle_p.h1
-rw-r--r--src/gui/text/qfont.h1
-rw-r--r--src/gui/text/qfontdatabase.cpp9
-rw-r--r--src/gui/text/qfontdatabase_x11.cpp26
-rw-r--r--src/gui/text/qfontengine.cpp2
-rw-r--r--src/gui/text/qfontengine_mac.mm7
-rw-r--r--src/gui/text/qfontengine_x11.cpp5
-rw-r--r--src/gui/text/qtextcontrol.cpp14
-rw-r--r--src/gui/text/qtextodfwriter.cpp4
-rw-r--r--src/gui/text/qtextoption.cpp6
-rw-r--r--src/gui/util/qdesktopservices_win.cpp75
-rw-r--r--src/gui/widgets/qabstractscrollarea.cpp56
-rw-r--r--src/gui/widgets/qabstractscrollarea.h4
-rw-r--r--src/gui/widgets/qabstractscrollarea_p.h3
-rw-r--r--src/gui/widgets/qabstractslider.cpp50
-rw-r--r--src/gui/widgets/qabstractslider_p.h1
-rw-r--r--src/gui/widgets/qcombobox.cpp5
-rw-r--r--src/gui/widgets/qcommandlinkbutton.cpp27
-rw-r--r--src/gui/widgets/qdialogbuttonbox.cpp18
-rw-r--r--src/gui/widgets/qlabel.cpp19
-rw-r--r--src/gui/widgets/qmainwindow.cpp6
-rw-r--r--src/gui/widgets/qmenu.h8
-rw-r--r--src/gui/widgets/qmenu_p.h7
-rw-r--r--src/gui/widgets/qmenu_symbian.cpp27
-rw-r--r--src/gui/widgets/qplaintextedit.cpp109
-rw-r--r--src/gui/widgets/qplaintextedit.h4
-rw-r--r--src/gui/widgets/qplaintextedit_p.h5
-rw-r--r--src/gui/widgets/qtextedit.cpp49
-rw-r--r--src/gui/widgets/qtoolbarextension_p.h2
161 files changed, 6333 insertions, 3053 deletions
diff --git a/src/gui/dialogs/qcolordialog.cpp b/src/gui/dialogs/qcolordialog.cpp
index a7df999..44a82ef 100644
--- a/src/gui/dialogs/qcolordialog.cpp
+++ b/src/gui/dialogs/qcolordialog.cpp
@@ -62,6 +62,7 @@
#include "qmime.h"
#include "qspinbox.h"
#include "qdialogbuttonbox.h"
+#include "private/qguiplatformplugin_p.h"
#ifdef Q_WS_S60
#include "private/qt_s60_p.h"
@@ -1454,6 +1455,8 @@ void QColorDialogPrivate::init(const QColor &initial)
q->setSizeGripEnabled(false);
q->setWindowTitle(QColorDialog::tr("Select Color"));
+ nativeDialogInUse = false;
+
nextCust = 0;
QVBoxLayout *mainLay = new QVBoxLayout(q);
// there's nothing in this dialog that benefits from sizing up
@@ -1719,6 +1722,8 @@ void QColorDialog::setCurrentColor(const QColor &color)
d->setCurrentQColor(color);
d->setCocoaPanelColor(color);
#endif
+ if (d->nativeDialogInUse)
+ qt_guiPlatformPlugin()->colorDialogSetCurrentColor(this, color);
}
QColor QColorDialog::currentColor() const
@@ -1871,6 +1876,17 @@ void QColorDialog::setVisible(bool visible)
setAttribute(Qt::WA_DontShowOnScreen, false);
}
}
+#else
+
+ if (!(d->opts & DontUseNativeDialog) && qt_guiPlatformPlugin()->colorDialogSetVisible(this, visible)) {
+ d->nativeDialogInUse = true;
+ // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
+ // updates the state correctly, but skips showing the non-native version:
+ setAttribute(Qt::WA_DontShowOnScreen);
+ } else {
+ d->nativeDialogInUse = false;
+ setAttribute(Qt::WA_DontShowOnScreen, false);
+ }
#endif
QDialog::setVisible(visible);
@@ -1970,8 +1986,8 @@ QRgb QColorDialog::getRgba(QRgb initial, bool *ok, QWidget *parent)
QColorDialog::~QColorDialog()
{
-#if defined(Q_WS_MAC)
Q_D(QColorDialog);
+#if defined(Q_WS_MAC)
if (d->delegate) {
d->releaseCocoaColorPanelDelegate();
QColorDialogPrivate::sharedColorPanelAvailable = true;
@@ -1985,6 +2001,9 @@ QColorDialog::~QColorDialog()
settings.setValue(QLatin1String("Qt/customColors/") + QString::number(i), cusrgb[i]);
}
#endif
+ if (d->nativeDialogInUse)
+ qt_guiPlatformPlugin()->colorDialogDelete(this);
+
}
diff --git a/src/gui/dialogs/qcolordialog_mac.mm b/src/gui/dialogs/qcolordialog_mac.mm
index f6b88bb..9e4fdd1 100644
--- a/src/gui/dialogs/qcolordialog_mac.mm
+++ b/src/gui/dialogs/qcolordialog_mac.mm
@@ -44,6 +44,7 @@
#include <qapplication.h>
#include <qtimer.h>
#include <qdialogbuttonbox.h>
+#include <qabstracteventdispatcher.h>
#include <private/qapplication_p.h>
#include <private/qt_mac_p.h>
#include <qdebug.h>
@@ -319,6 +320,7 @@ QT_USE_NAMESPACE
QMacCocoaAutoReleasePool pool;
mDialogIsExecuting = true;
[NSApp runModalForWindow:mColorPanel];
+ QAbstractEventDispatcher::instance()->interrupt();
if (mResultCode == NSCancelButton)
mPriv->colorDialog()->reject();
else
@@ -411,7 +413,7 @@ void QColorDialogPrivate::openCocoaColorPanel(const QColor &initial,
void QColorDialogPrivate::closeCocoaColorPanel()
{
- [[static_cast<QCocoaColorPanelDelegate *>(delegate) colorPanel] close];
+ [static_cast<QCocoaColorPanelDelegate *>(delegate) onCancelClicked];
}
void QColorDialogPrivate::releaseCocoaColorPanelDelegate()
diff --git a/src/gui/dialogs/qcolordialog_p.h b/src/gui/dialogs/qcolordialog_p.h
index c7cabfb..81df503 100644
--- a/src/gui/dialogs/qcolordialog_p.h
+++ b/src/gui/dialogs/qcolordialog_p.h
@@ -114,6 +114,7 @@ public:
QColorDialog::ColorDialogOptions opts;
QPointer<QObject> receiverToDisconnectOnClose;
QByteArray memberToDisconnectOnClose;
+ bool nativeDialogInUse;
#ifdef Q_WS_MAC
void openCocoaColorPanel(const QColor &initial,
diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp
index 7df49fa..ed2d676 100644
--- a/src/gui/dialogs/qdialog.cpp
+++ b/src/gui/dialogs/qdialog.cpp
@@ -673,28 +673,6 @@ void QDialog::keyPressEvent(QKeyEvent *e)
case Qt::Key_Escape:
reject();
break;
- case Qt::Key_Up:
- case Qt::Key_Left:
- if (focusWidget() &&
- (focusWidget()->focusPolicy() == Qt::StrongFocus ||
- focusWidget()->focusPolicy() == Qt::WheelFocus)) {
- e->ignore();
- break;
- }
- // call ours, since c++ blocks us from calling the one
- // belonging to focusWidget().
- focusNextPrevChild(false);
- break;
- case Qt::Key_Down:
- case Qt::Key_Right:
- if (focusWidget() &&
- (focusWidget()->focusPolicy() == Qt::StrongFocus ||
- focusWidget()->focusPolicy() == Qt::WheelFocus)) {
- e->ignore();
- break;
- }
- focusNextPrevChild(true);
- break;
default:
e->ignore();
return;
diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp
index 14f19f2..eab842f 100644
--- a/src/gui/dialogs/qfiledialog.cpp
+++ b/src/gui/dialogs/qfiledialog.cpp
@@ -317,6 +317,7 @@ QFileDialog::QFileDialog(QWidget *parent, Qt::WindowFlags f)
{
Q_D(QFileDialog);
d->init();
+ d->lineEdit()->selectAll();
}
/*!
@@ -334,6 +335,7 @@ QFileDialog::QFileDialog(QWidget *parent,
{
Q_D(QFileDialog);
d->init(directory, filter, caption);
+ d->lineEdit()->selectAll();
}
/*!
@@ -3020,6 +3022,12 @@ bool QFileDialogPrivate::itemViewKeyboardEvent(QKeyEvent *event) {
case Qt::Key_Escape:
q->hide();
return true;
+#ifdef QT_KEYPAD_NAVIGATION
+ case Qt::Key_Down:
+ case Qt::Key_Up:
+ return (QApplication::navigationMode() != Qt::NavigationModeKeypadTabOrder
+ && QApplication::navigationMode() != Qt::NavigationModeKeypadDirectional);
+#endif
default:
break;
}
@@ -3140,7 +3148,17 @@ void QFileDialogListView::keyPressEvent(QKeyEvent *e)
if (!d_ptr->itemViewKeyboardEvent(e)) {
QListView::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
}
QFileDialogTreeView::QFileDialogTreeView(QWidget *parent) : QTreeView(parent)
@@ -3187,7 +3205,11 @@ void QFileDialogLineEdit::keyPressEvent(QKeyEvent *e)
{
int key = e->key();
QLineEdit::keyPressEvent(e);
- if (key != Qt::Key_Escape)
+ if (key != Qt::Key_Escape
+#ifdef QT_KEYPAD_NAVIGATION
+ && QApplication::navigationMode() == Qt::NavigationModeNone
+#endif
+ )
e->accept();
if (hideOnEsc && (key == Qt::Key_Escape || key == Qt::Key_Return || key == Qt::Key_Enter)) {
e->accept();
diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm
index 3a4ecce..8e4c461 100644
--- a/src/gui/dialogs/qfiledialog_mac.mm
+++ b/src/gui/dialogs/qfiledialog_mac.mm
@@ -62,6 +62,7 @@
#include <qvarlengtharray.h>
#include <qdesktopwidget.h>
#include <stdlib.h>
+#include <qabstracteventdispatcher.h>
#include "ui_qfiledialog.h"
QT_BEGIN_NAMESPACE
@@ -245,6 +246,8 @@ QT_USE_NAMESPACE
mReturnCode = [mSavePanel
runModalForDirectory:mCurrentDir
file:selectable ? filename : @"untitled"];
+
+ QAbstractEventDispatcher::instance()->interrupt();
return (mReturnCode == NSOKButton);
}
diff --git a/src/gui/dialogs/qfiledialog_p.h b/src/gui/dialogs/qfiledialog_p.h
index 54fc0e0..32cd397 100644
--- a/src/gui/dialogs/qfiledialog_p.h
+++ b/src/gui/dialogs/qfiledialog_p.h
@@ -76,6 +76,8 @@
#include <qdebug.h>
#include "qsidebar_p.h"
#include "qfscompleter_p.h"
+#include "private/qguiplatformplugin_p.h"
+
#if defined (Q_OS_UNIX)
#include <unistd.h>
@@ -405,17 +407,17 @@ inline QString QFileDialogPrivate::rootPath() const {
#ifndef Q_WS_MAC
// Dummies for platforms that don't use native dialogs:
- inline void QFileDialogPrivate::deleteNativeDialog_sys() {}
- inline bool QFileDialogPrivate::setVisible_sys(bool) { return false; }
- inline QDialog::DialogCode QFileDialogPrivate::dialogResultCode_sys(){ return QDialog::Rejected; }
- inline void QFileDialogPrivate::setDirectory_sys(const QString &) {}
- inline QString QFileDialogPrivate::directory_sys() const { return QString(); }
- inline void QFileDialogPrivate::selectFile_sys(const QString &) {}
- inline QStringList QFileDialogPrivate::selectedFiles_sys() const { return QStringList(); }
- inline void QFileDialogPrivate::setFilter_sys() {}
- inline void QFileDialogPrivate::setNameFilters_sys(const QStringList &) {}
- inline void QFileDialogPrivate::selectNameFilter_sys(const QString &) {}
- inline QString QFileDialogPrivate::selectedNameFilter_sys() const { return QString(); }
+ inline void QFileDialogPrivate::deleteNativeDialog_sys() { qt_guiPlatformPlugin()->fileDialogDelete(q_func()); }
+ inline bool QFileDialogPrivate::setVisible_sys(bool visible) { return qt_guiPlatformPlugin()->fileDialogSetVisible(q_func(), visible); }
+ inline QDialog::DialogCode QFileDialogPrivate::dialogResultCode_sys(){ return qt_guiPlatformPlugin()->fileDialogResultCode(q_func()); }
+ inline void QFileDialogPrivate::setDirectory_sys(const QString &directory) { qt_guiPlatformPlugin()->fileDialogSetDirectory(q_func(), directory); }
+ inline QString QFileDialogPrivate::directory_sys() const { return qt_guiPlatformPlugin()->fileDialogDirectory(q_func()); }
+ inline void QFileDialogPrivate::selectFile_sys(const QString &filename) { qt_guiPlatformPlugin()->fileDialogSelectFile(q_func(), filename); }
+ inline QStringList QFileDialogPrivate::selectedFiles_sys() const { return qt_guiPlatformPlugin()->fileDialogSelectedFiles(q_func()); }
+ inline void QFileDialogPrivate::setFilter_sys() { qt_guiPlatformPlugin()->fileDialogSetFilter(q_func()); }
+ inline void QFileDialogPrivate::setNameFilters_sys(const QStringList &filters) { qt_guiPlatformPlugin()->fileDialogSetNameFilters(q_func(), filters); }
+ inline void QFileDialogPrivate::selectNameFilter_sys(const QString &filter) { qt_guiPlatformPlugin()->fileDialogSelectNameFilter(q_func(), filter); }
+ inline QString QFileDialogPrivate::selectedNameFilter_sys() const { return qt_guiPlatformPlugin()->fileDialogSelectedNameFilter(q_func()); }
#endif
QT_END_NAMESPACE
diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm
index dacb54c..5b0983b 100644
--- a/src/gui/dialogs/qfontdialog_mac.mm
+++ b/src/gui/dialogs/qfontdialog_mac.mm
@@ -628,7 +628,7 @@ void QFontDialogPrivate::setFont(void *delegate, const QFont &font)
nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(font.family())
traits:mask
weight:weight
- size:font.pointSize()];
+ size:QFontInfo(font).pointSize()];
}
[mgr setSelectedFont:nsFont isMultiple:NO];
diff --git a/src/gui/dialogs/qprintdialog_mac.mm b/src/gui/dialogs/qprintdialog_mac.mm
index a7587b1..667fc40 100644
--- a/src/gui/dialogs/qprintdialog_mac.mm
+++ b/src/gui/dialogs/qprintdialog_mac.mm
@@ -166,6 +166,12 @@ QT_USE_NAMESPACE
}
// Keep us in sync with file output
PMDestinationType dest;
+
+ // If the user selected print to file, the session has been
+ // changed behind our back and our d->ep->session object is a
+ // dangling pointer. Update it based on the "current" session
+ d->ep->session = static_cast<PMPrintSession>([d->ep->printInfo PMPrintSession]);
+
PMSessionGetDestinationType(d->ep->session, d->ep->settings, &dest);
if (dest == kPMDestinationFile) {
QCFType<CFURLRef> file;
diff --git a/src/gui/dialogs/qprintdialog_win.cpp b/src/gui/dialogs/qprintdialog_win.cpp
index f66c27f..843c4e2 100644
--- a/src/gui/dialogs/qprintdialog_win.cpp
+++ b/src/gui/dialogs/qprintdialog_win.cpp
@@ -52,6 +52,13 @@
#include <private/qprintengine_win_p.h>
#include <private/qprinter_p.h>
+#if defined(Q_CC_MINGW) && !defined(PD_NOCURRENTPAGE)
+#define PD_NOCURRENTPAGE 0x00800000
+#define PD_RESULT_PRINT 1
+#define PD_RESULT_APPLY 2
+#define START_PAGE_GENERAL 0XFFFFFFFF
+#endif
+
QT_BEGIN_NAMESPACE
extern void qt_win_eatMouseMove();
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp
index eee9bbf..ee01fdc 100644
--- a/src/gui/effects/qgraphicseffect.cpp
+++ b/src/gui/effects/qgraphicseffect.cpp
@@ -67,6 +67,7 @@
\o QGraphicsOpacityEffect - renders the item with an opacity
\o QGraphicsPixelizeEffect - pixelizes the item with any pixel size
\o QGraphicsGrayscaleEffect - renders the item in shades of gray
+ \o QGraphicsBloomEffect - applies a blooming / glowing effect
\endlist
\img graphicseffect-effects.png
@@ -565,7 +566,7 @@ QGraphicsColorizeEffect::~QGraphicsColorizeEffect()
\brief the color of the effect.
By default, the color is light blue (QColor(0, 0, 192)).
-*/;
+*/
QColor QGraphicsColorizeEffect::color() const
{
Q_D(const QGraphicsColorizeEffect);
@@ -795,7 +796,7 @@ QGraphicsBlurEffect::QGraphicsBlurEffect(QObject *parent)
: QGraphicsEffect(*new QGraphicsBlurEffectPrivate, parent)
{
Q_D(QGraphicsBlurEffect);
- d->filter->setBlurHint(QPixmapBlurFilter::PerformanceHint);
+ d->filter->setBlurHint(Qt::PerformanceHint);
}
/*!
@@ -839,48 +840,34 @@ void QGraphicsBlurEffect::setBlurRadius(int radius)
*/
/*!
- \enum QGraphicsBlurEffect::BlurHint
-
- \since 4.6
-
- This enum describes the hint of a blur graphics effect.
-
- \value PerformanceHint Using this value hints that performance is the
- most important factor, at the potential cost of lower quality.
-
- \value QualityHint Using this value hints that a higher quality blur is
- preferred over a fast blur.
-*/
-
-/*!
\property QGraphicsBlurEffect::blurHint
\brief the blur hint of the effect.
- Use the PerformanceHint blur hint to say that you want a faster blur,
- and the QualityHint blur hint to say that you prefer a higher quality blur.
+ 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 the PerformanceHint.
+ When animating the blur radius it's recommended to use Qt::PerformanceHint.
- By default, the blur hint is PerformanceHint.
+ By default, the blur hint is Qt::PerformanceHint.
*/
-QGraphicsBlurEffect::BlurHint QGraphicsBlurEffect::blurHint() const
+Qt::RenderHint QGraphicsBlurEffect::blurHint() const
{
Q_D(const QGraphicsBlurEffect);
- return BlurHint(d->filter->blurHint());
+ return d->filter->blurHint();
}
-void QGraphicsBlurEffect::setBlurHint(QGraphicsBlurEffect::BlurHint hint)
+void QGraphicsBlurEffect::setBlurHint(Qt::RenderHint hint)
{
Q_D(QGraphicsBlurEffect);
- if (BlurHint(d->filter->blurHint()) == hint)
+ if (d->filter->blurHint() == hint)
return;
- d->filter->setBlurHint(QPixmapBlurFilter::BlurHint(hint));
+ d->filter->setBlurHint(hint);
emit blurHintChanged(hint);
}
/*!
- \fn void QGraphicsBlurEffect::blurHintChanged(QGraphicsBlurEffect::BlurHint hint)
+ \fn void QGraphicsBlurEffect::blurHintChanged(Qt::RenderHint hint)
This signal is emitted whenever the effect's blur hint changes.
The \a hint parameter holds the effect's new blur hint.
@@ -1305,5 +1292,237 @@ void QGraphicsOpacityEffect::draw(QPainter *painter, QGraphicsEffectSource *sour
painter->restore();
}
+/*!
+ \class QGraphicsBloomEffect
+ \brief The QGraphicsBloomEffect class provides a bloom/glow effect.
+ \since 4.6
+
+ A bloom/glow effect adds fringes of light around bright areas in the source.
+
+ \img graphicseffect-bloom.png
+
+ \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsPixelizeEffect,
+ QGraphicsGrayscaleEffect, QGraphicsColorizeEffect
+*/
+
+/*!
+ Constructs a new QGraphicsBloomEffect instance.
+ The \a parent parameter is passed to QGraphicsEffect's constructor.
+*/
+QGraphicsBloomEffect::QGraphicsBloomEffect(QObject *parent)
+ : QGraphicsEffect(*new QGraphicsBloomEffectPrivate, parent)
+{
+ Q_D(QGraphicsBloomEffect);
+ for (int i = 0; i < 256; ++i)
+ d->colorTable[i] = qMin(i + d->brightness, 255);
+}
+
+/*!
+ Destroys the effect.
+*/
+QGraphicsBloomEffect::~QGraphicsBloomEffect()
+{
+}
+
+/*!
+ \reimp
+*/
+QRectF QGraphicsBloomEffect::boundingRectFor(const QRectF &rect) const
+{
+ Q_D(const QGraphicsBloomEffect);
+ const qreal delta = d->blurFilter.radius() * 2;
+ return rect.adjusted(-delta, -delta, delta, delta);
+}
+
+/*!
+ \property QGraphicsBloomEffect::blurRadius
+ \brief the blur radius in pixels of the effect.
+
+ Using a smaller radius results in a sharper appearance, whereas a bigger
+ radius results in a more blurred appearance.
+
+ By default, the blur radius is 5 pixels.
+
+ \sa strength(), brightness()
+*/
+int QGraphicsBloomEffect::blurRadius() const
+{
+ Q_D(const QGraphicsBloomEffect);
+ return d->blurFilter.radius();
+}
+
+void QGraphicsBloomEffect::setBlurRadius(int radius)
+{
+ Q_D(QGraphicsBloomEffect);
+ if (d->blurFilter.radius() == radius)
+ return;
+
+ d->blurFilter.setRadius(radius);
+ updateBoundingRect();
+ emit blurRadiusChanged(radius);
+}
+
+/*!
+ \fn void QGraphicsBloomEffect::blurRadiusChanged(int blurRadius)
+
+ This signal is emitted whenever the effect's blur radius changes.
+ The \a blurRadius parameter holds the effect's new blur radius.
+*/
+
+/*!
+ \property QGraphicsBloomEffect::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.
+
+ By default, the blur hint is Qt::PerformanceHint.
+*/
+Qt::RenderHint QGraphicsBloomEffect::blurHint() const
+{
+ Q_D(const QGraphicsBloomEffect);
+ return d->blurFilter.blurHint();
+}
+
+void QGraphicsBloomEffect::setBlurHint(Qt::RenderHint hint)
+{
+ Q_D(QGraphicsBloomEffect);
+ if (d->blurFilter.blurHint() == hint)
+ return;
+
+ d->blurFilter.setBlurHint(hint);
+ emit blurHintChanged(hint);
+}
+
+/*!
+ \fn void QGraphicsBloomEffect::blurHintChanged(Qt::RenderHint hint)
+
+ This signal is emitted whenever the effect's blur hint changes.
+ The \a hint parameter holds the effect's new blur hint.
+*/
+
+/*!
+ \property QGraphicsBloomEffect::brightness
+ \brief the brightness of the glow.
+
+ The value should be in the range of 0 to 255, where 0 is dark
+ and 255 is bright.
+
+ By default, the brightness is 70.
+
+ \sa strength(), blurRadius()
+*/
+int QGraphicsBloomEffect::brightness() const
+{
+ Q_D(const QGraphicsBloomEffect);
+ return d->brightness;
+}
+
+void QGraphicsBloomEffect::setBrightness(int brightness)
+{
+ Q_D(QGraphicsBloomEffect);
+ brightness = qBound(0, brightness, 255);
+ if (d->brightness == brightness)
+ return;
+
+ d->brightness = brightness;
+ for (int i = 0; i < 256; ++i)
+ d->colorTable[i] = qMin(i + brightness, 255);
+
+ update();
+ emit brightnessChanged(brightness);
+}
+
+/*!
+ \fn void QGraphicsBloomEffect::brightnessChanged(int brightness)
+
+ This signal is emitted whenever the effect's brightness changes.
+ The \a brightness parameter holds the effect's new brightness.
+*/
+
+/*!
+ \property QGraphicsBloomEffect::strength
+ \brief the strength of the effect.
+
+ A strength 0.0 equals to no effect, while 1.0 means maximum glow.
+
+ By default, the strength is 0.7.
+*/
+qreal QGraphicsBloomEffect::strength() const
+{
+ Q_D(const QGraphicsBloomEffect);
+ return d->strength;
+}
+
+void QGraphicsBloomEffect::setStrength(qreal strength)
+{
+ Q_D(QGraphicsBloomEffect);
+ strength = qBound(qreal(0.0), strength, qreal(1.0));
+ if (qFuzzyCompare(d->strength, strength))
+ return;
+
+ d->strength = strength;
+ update();
+ emit strengthChanged(strength);
+}
+
+/*!
+ \fn void QGraphicsBloomEffect::strengthChanged(qreal strength)
+
+ This signal is emitted whenever the effect's strength changes.
+ The \a strength parameter holds the effect's new strength.
+*/
+
+/*!
+ \reimp
+*/
+void QGraphicsBloomEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
+{
+ Q_D(QGraphicsBloomEffect);
+ if (d->strength < 0.001) {
+ source->draw(painter);
+ return;
+ }
+
+ const Qt::CoordinateSystem system = source->isPixmap()
+ ? Qt::LogicalCoordinates : Qt::DeviceCoordinates;
+ QPoint offset;
+ QPixmap pixmap = source->pixmap(system, &offset);
+ QImage result = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
+
+ // Blur.
+ QPainter blurPainter(&pixmap);
+ d->blurFilter.draw(&blurPainter, QPointF(), pixmap);
+ blurPainter.end();
+
+ // Brighten.
+ QImage overlay = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ const int numBits = overlay.width() * overlay.height();
+ QRgb *bits = reinterpret_cast<QRgb *>(overlay.bits());
+ for (int i = 0; i < numBits; ++i) {
+ const QRgb bit = bits[i];
+ bits[i] = qRgba(d->colorTable[qRed(bit)], d->colorTable[qGreen(bit)],
+ d->colorTable[qBlue(bit)], qAlpha(bit));
+ }
+
+ // Composite.
+ QPainter compPainter(&result);
+ compPainter.setCompositionMode(QPainter::CompositionMode_Overlay);
+ compPainter.setOpacity(d->strength);
+ compPainter.drawImage(0, 0, overlay);
+ compPainter.end();
+
+ if (system == Qt::DeviceCoordinates) {
+ QTransform restoreTransform = painter->worldTransform();
+ painter->setWorldTransform(QTransform());
+ painter->drawImage(offset, result);
+ painter->setWorldTransform(restoreTransform);
+ } else {
+ painter->drawImage(offset, result);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/effects/qgraphicseffect.h b/src/gui/effects/qgraphicseffect.h
index c256381..c5d3ede 100644
--- a/src/gui/effects/qgraphicseffect.h
+++ b/src/gui/effects/qgraphicseffect.h
@@ -224,27 +224,22 @@ class Q_GUI_EXPORT QGraphicsBlurEffect: public QGraphicsEffect
{
Q_OBJECT
Q_PROPERTY(int blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged)
- Q_PROPERTY(BlurHint blurHint READ blurHint WRITE setBlurHint NOTIFY blurHintChanged)
+ Q_PROPERTY(Qt::RenderHint blurHint READ blurHint WRITE setBlurHint NOTIFY blurHintChanged)
public:
- enum BlurHint {
- PerformanceHint,
- QualityHint
- };
-
QGraphicsBlurEffect(QObject *parent = 0);
~QGraphicsBlurEffect();
QRectF boundingRectFor(const QRectF &rect) const;
int blurRadius() const;
- BlurHint blurHint() const;
+ Qt::RenderHint blurHint() const;
public Q_SLOTS:
void setBlurRadius(int blurRadius);
- void setBlurHint(BlurHint blurHint);
+ void setBlurHint(Qt::RenderHint hint);
Q_SIGNALS:
void blurRadiusChanged(int blurRadius);
- void blurHintChanged(BlurHint blurHint);
+ void blurHintChanged(Qt::RenderHint hint);
protected:
void draw(QPainter *painter, QGraphicsEffectSource *source);
@@ -339,6 +334,44 @@ private:
Q_DISABLE_COPY(QGraphicsOpacityEffect)
};
+class QGraphicsBloomEffectPrivate;
+class Q_GUI_EXPORT QGraphicsBloomEffect: public QGraphicsEffect
+{
+ Q_OBJECT
+ Q_PROPERTY(int blurRadius READ blurRadius WRITE setBlurRadius NOTIFY blurRadiusChanged)
+ Q_PROPERTY(Qt::RenderHint blurHint READ blurHint WRITE setBlurHint NOTIFY blurHintChanged)
+ Q_PROPERTY(int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged)
+ Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged)
+public:
+ QGraphicsBloomEffect(QObject *parent = 0);
+ ~QGraphicsBloomEffect();
+
+ QRectF boundingRectFor(const QRectF &rect) const;
+ int blurRadius() const;
+ Qt::RenderHint blurHint() const;
+ int brightness() const;
+ qreal strength() const;
+
+public Q_SLOTS:
+ void setBlurRadius(int blurRadius);
+ void setBlurHint(Qt::RenderHint hint);
+ void setBrightness(int brightness);
+ void setStrength(qreal strength);
+
+Q_SIGNALS:
+ void blurRadiusChanged(int blurRadius);
+ void blurHintChanged(Qt::RenderHint hint);
+ void brightnessChanged(int brightness);
+ void strengthChanged(qreal strength);
+
+protected:
+ void draw(QPainter *painter, QGraphicsEffectSource *source);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsBloomEffect)
+ Q_DISABLE_COPY(QGraphicsBloomEffect)
+};
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/gui/effects/qgraphicseffect_p.h b/src/gui/effects/qgraphicseffect_p.h
index e109790..ff2fb85 100644
--- a/src/gui/effects/qgraphicseffect_p.h
+++ b/src/gui/effects/qgraphicseffect_p.h
@@ -185,6 +185,18 @@ public:
uint hasOpacityMask : 1;
};
+class QGraphicsBloomEffectPrivate : public QGraphicsEffectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsBlurEffect)
+public:
+ QGraphicsBloomEffectPrivate() : brightness(70), strength(qreal(0.7)) {}
+
+ QPixmapBlurFilter blurFilter;
+ int colorTable[256];
+ int brightness;
+ qreal strength;
+};
+
QT_END_NAMESPACE
#endif // QGRAPHICSEFFECT_P_H
diff --git a/src/gui/egl/qeglproperties.cpp b/src/gui/egl/qeglproperties.cpp
index 02ae729..c61e1d3 100644
--- a/src/gui/egl/qeglproperties.cpp
+++ b/src/gui/egl/qeglproperties.cpp
@@ -313,7 +313,7 @@ QString QEglProperties::toString() const
int alpha = value(EGL_ALPHA_SIZE);
int bufferSize = value(EGL_BUFFER_SIZE);
if (bufferSize == (red + green + blue + alpha))
- bufferSize = EGL_DONT_CARE;
+ bufferSize = 0;
str += QLatin1String(" rgba=");
str += QString::number(red);
str += QLatin1Char(',');
@@ -322,7 +322,7 @@ QString QEglProperties::toString() const
str += QString::number(blue);
str += QLatin1Char(',');
str += QString::number(alpha);
- if (bufferSize != EGL_DONT_CARE) {
+ if (bufferSize != 0) {
// Only report buffer size if different than r+g+b+a.
str += QLatin1String(" buffer-size=");
str += QString::number(bufferSize);
diff --git a/src/gui/embedded/qscreenvfb_qws.cpp b/src/gui/embedded/qscreenvfb_qws.cpp
index 19d4fa8..d71336d 100644
--- a/src/gui/embedded/qscreenvfb_qws.cpp
+++ b/src/gui/embedded/qscreenvfb_qws.cpp
@@ -196,7 +196,7 @@ bool QVFbScreen::connect(const QString &displaySpec)
if (displayArgs.contains(QLatin1String("Gray")))
grayscale = true;
- key_t key = ftok(QByteArray(QT_VFB_MOUSE_PIPE).replace("%1", QByteArray::number(displayId)), 'b');
+ key_t key = ftok(QT_VFB_MOUSE_PIPE(displayId).toLocal8Bit(), 'b');
if (key == -1)
return false;
@@ -330,8 +330,7 @@ void QVFbScreen::disconnect()
bool QVFbScreen::initDevice()
{
#ifndef QT_NO_QWS_MOUSE_QVFB
- const QString mouseDev = QString::fromLatin1(QT_VFB_MOUSE_PIPE)
- .arg(displayId);
+ const QString mouseDev = QT_VFB_MOUSE_PIPE(displayId);
d_ptr->mouse = new QVFbMouseHandler(QLatin1String("QVFbMouse"), mouseDev);
qwsServer->setDefaultMouse("None");
if (d_ptr->mouse)
@@ -339,8 +338,7 @@ bool QVFbScreen::initDevice()
#endif
#if !defined(QT_NO_QWS_KBD_QVFB) && !defined(QT_NO_QWS_KEYBOARD)
- const QString keyboardDev = QString::fromLatin1(QT_VFB_KEYBOARD_PIPE)
- .arg(displayId);
+ const QString keyboardDev = QT_VFB_KEYBOARD_PIPE(displayId);
d_ptr->keyboard = new QVFbKeyboardHandler(keyboardDev);
qwsServer->setDefaultKeyboard("None");
#endif
diff --git a/src/gui/embedded/qsoundqss_qws.cpp b/src/gui/embedded/qsoundqss_qws.cpp
index 6bac8dc..b859be5 100644
--- a/src/gui/embedded/qsoundqss_qws.cpp
+++ b/src/gui/embedded/qsoundqss_qws.cpp
@@ -67,6 +67,8 @@
#include <qdebug.h>
+#include <qvfbhdr.h>
+
extern int errno;
QT_BEGIN_NAMESPACE
@@ -79,7 +81,6 @@ QT_BEGIN_NAMESPACE
static int sound_speed = 44100;
#ifndef QT_NO_QWS_SOUNDSERVER
extern int qws_display_id;
-#define SOUND_PIPE "/tmp/.qt_soundserver-%1"
#endif
static char *zeroMem = 0;
@@ -708,7 +709,7 @@ protected:
#ifndef QT_NO_QWS_SOUNDSERVER
QWSSoundServerSocket::QWSSoundServerSocket(QObject *parent) :
- QWSServerSocket(QString::fromLatin1(SOUND_PIPE).arg(qws_display_id), parent)
+ QWSServerSocket(QT_VFB_SOUND_PIPE(qws_display_id), parent)
{
connect(this, SIGNAL(newConnection()), this, SLOT(newConnection()));
}
@@ -716,7 +717,7 @@ QWSSoundServerSocket::QWSSoundServerSocket(QObject *parent) :
#ifdef QT3_SUPPORT
QWSSoundServerSocket::QWSSoundServerSocket(QObject *parent, const char *name) :
- QWSServerSocket(QString::fromLatin1(SOUND_PIPE).arg(qws_display_id), parent)
+ QWSServerSocket(QT_VFB_SOUND_PIPE(qws_display_id), parent)
{
if (name)
setObjectName(QString::fromAscii(name));
@@ -1395,7 +1396,7 @@ void QWSSoundServer::translateSoundCompleted( int, int sid )
QWSSoundClient::QWSSoundClient(QObject* parent) :
QWSSocket(parent)
{
- connectToLocalFile(QString::fromLatin1(SOUND_PIPE).arg(qws_display_id));
+ connectToLocalFile(QT_VFB_SOUND_PIPE(qws_display_id));
QObject::connect(this,SIGNAL(readyRead()),
this,SLOT(tryReadCommand()));
if( state() == QWS_SOCK_BASE::ConnectedState ) QTimer::singleShot(1, this, SIGNAL(connected()));
@@ -1409,7 +1410,7 @@ QWSSoundClient::~QWSSoundClient( )
void QWSSoundClient::reconnect()
{
- connectToLocalFile(QString::fromLatin1(SOUND_PIPE).arg(qws_display_id));
+ connectToLocalFile(QT_VFB_SOUND_PIPE(qws_display_id));
if( state() == QWS_SOCK_BASE::ConnectedState ) emit connected();
else emit error( QTcpSocket::ConnectionRefusedError );
}
diff --git a/src/gui/embedded/qvfbhdr.h b/src/gui/embedded/qvfbhdr.h
index 73e08e0..73b13d3 100644
--- a/src/gui/embedded/qvfbhdr.h
+++ b/src/gui/embedded/qvfbhdr.h
@@ -52,9 +52,38 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
-#define QT_VFB_MOUSE_PIPE "/tmp/.qtvfb_mouse-%1"
-#define QT_VFB_KEYBOARD_PIPE "/tmp/.qtvfb_keyboard-%1"
-#define QT_VFB_MAP "/tmp/.qtvfb_map-%1"
+#ifndef QT_QWS_TEMP_DIR
+#define QT_QWS_TEMP_DIR "/tmp"
+#endif
+
+#ifdef QT_PRIVATE_QWS
+#define QT_VFB_DATADIR(DISPLAY) QString("%1/qtembedded-%2-%3") \
+ .arg(QT_QWS_TEMP_DIR).arg(getuid()).arg(DISPLAY)
+
+#define QT_VFB_MOUSE_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
+ .append("/qtvfb_mouse")
+#define QT_VFB_KEYBOARD_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
+ .append("/qtvfb_keyboard")
+#define QT_VFB_MAP(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
+ .append("/qtvfb_map")
+#define QT_VFB_SOUND_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
+ .append("/qt_soundserver")
+#define QTE_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
+ .append("/QtEmbedded")
+#define QTE_PIPE_QVFB(DISPLAY) QTE_PIPE(DISPLAY)
+#else
+#define QT_VFB_DATADIR(DISPLAY) QString("%1/qtembedded-%2") \
+ .arg(QT_QWS_TEMP_DIR).arg(DISPLAY)
+#define QT_VFB_MOUSE_PIPE(DISPLAY) QString("/tmp/.qtvfb_mouse-%1").arg(DISPLAY)
+#define QT_VFB_KEYBOARD_PIPE(DISPLAY) QString("/tmp/.qtvfb_keyboard-%1").arg(DISPLAY)
+#define QT_VFB_MAP(DISPLAY) QString("/tmp/.qtvfb_map-%1").arg(DISPLAY)
+#define QT_VFB_SOUND_PIPE(DISPLAY) QString("/tmp/.qt_soundserver-%1").arg(DISPLAY)
+#define QTE_PIPE(DISPLAY) QT_VFB_DATADIR(DISPLAY) \
+ .append("/QtEmbedded-%1") \
+ .arg(DISPLAY)
+#define QTE_PIPE_QVFB(DISPLAY) QString("/tmp/qtembedded-%1/QtEmbedded-%1") \
+ .arg(DISPLAY)
+#endif
struct QVFbHeader
{
diff --git a/src/gui/embedded/qwscommand_qws_p.h b/src/gui/embedded/qwscommand_qws_p.h
index d92c6af..f986a9d 100644
--- a/src/gui/embedded/qwscommand_qws_p.h
+++ b/src/gui/embedded/qwscommand_qws_p.h
@@ -75,8 +75,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
-#define QTE_PIPE "QtEmbedded-%1"
-
class QRect;
/*********************************************************************
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
index fdb1708..ffbb67c 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
@@ -118,9 +118,13 @@ QGraphicsAnchor::~QGraphicsAnchor()
}
/*!
- Set the spacing for the anchor to \a spacing.
+ \property QGraphicsAnchor::spacing
+ \brief the space between items in the QGraphicsAnchorLayout.
- \sa spacing(), unsetSpacing()
+ Depending on the anchor type, the default spacing is either
+ 0 or a value returned from the style.
+
+ \sa QGraphicsAnchorLayout::anchor()
*/
void QGraphicsAnchor::setSpacing(qreal spacing)
{
@@ -128,23 +132,12 @@ void QGraphicsAnchor::setSpacing(qreal spacing)
d->setSpacing(spacing);
}
-/*!
- Returns the spacing for the anchor
-
- \sa setSpacing()
-*/
qreal QGraphicsAnchor::spacing() const
{
Q_D(const QGraphicsAnchor);
return d->spacing();
}
-/*!
- Resets the spacing of the anchor point to be the default spacing. Depending on the anchor type,
- the default spacing is either 0 or a value returned from the style.
-
- \sa setSpacing(), spacing(), QGraphicsAnchorLayout::anchor()
-*/
void QGraphicsAnchor::unsetSpacing()
{
Q_D(QGraphicsAnchor);
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.h b/src/gui/graphicsview/qgraphicsanchorlayout.h
index d9a87ba..99dbf92 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout.h
+++ b/src/gui/graphicsview/qgraphicsanchorlayout.h
@@ -61,7 +61,7 @@ class QGraphicsAnchorLayoutPrivate;
class Q_GUI_EXPORT QGraphicsAnchor : public QObject
{
Q_OBJECT
- Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing)
+ Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing RESET unsetSpacing)
public:
void setSpacing(qreal spacing);
void unsetSpacing();
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
index f75118b..f9b5c8c 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
@@ -92,87 +92,118 @@ qreal QGraphicsAnchorPrivate::spacing() const
}
+static void sizeHintsFromItem(QGraphicsLayoutItem *item,
+ const QGraphicsAnchorLayoutPrivate::Orientation orient,
+ qreal *minSize, qreal *prefSize,
+ qreal *expSize, qreal *maxSize)
+{
+ QSizePolicy::Policy policy;
+ qreal minSizeHint;
+ qreal prefSizeHint;
+ qreal maxSizeHint;
+
+ if (orient == QGraphicsAnchorLayoutPrivate::Horizontal) {
+ policy = item->sizePolicy().horizontalPolicy();
+ minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).width();
+ prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).width();
+ maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).width();
+ } else {
+ policy = item->sizePolicy().verticalPolicy();
+ minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).height();
+ prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).height();
+ maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).height();
+ }
+
+ // minSize, prefSize and maxSize are initialized
+ // with item's preferred Size: this is QSizePolicy::Fixed.
+ //
+ // Then we check each flag to find the resultant QSizePolicy,
+ // according to the following table:
+ //
+ // constant value
+ // QSizePolicy::Fixed 0
+ // QSizePolicy::Minimum GrowFlag
+ // QSizePolicy::Maximum ShrinkFlag
+ // QSizePolicy::Preferred GrowFlag | ShrinkFlag
+ // QSizePolicy::Ignored GrowFlag | ShrinkFlag | IgnoreFlag
+
+ if (policy & QSizePolicy::ShrinkFlag)
+ *minSize = minSizeHint;
+ else
+ *minSize = prefSizeHint;
+
+ if (policy & QSizePolicy::GrowFlag)
+ *maxSize = maxSizeHint;
+ else
+ *maxSize = prefSizeHint;
+
+ // Note that these two initializations are affected by the previous flags
+ if (policy & QSizePolicy::IgnoreFlag)
+ *prefSize = *maxSize;
+ else
+ *prefSize = prefSizeHint;
+
+ if (policy & QSizePolicy::ExpandFlag)
+ *expSize = *maxSize;
+ else
+ *expSize = *prefSize;
+}
+
void AnchorData::refreshSizeHints(qreal effectiveSpacing)
{
- if (!isLayoutAnchor && from->m_item == to->m_item) {
- QGraphicsLayoutItem *item = from->m_item;
+ const bool isInternalAnchor = from->m_item == to->m_item;
- const QGraphicsAnchorLayoutPrivate::Orientation orient = QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge);
- const Qt::AnchorPoint centerEdge = QGraphicsAnchorLayoutPrivate::pickEdge(Qt::AnchorHorizontalCenter, orient);
+ if (isInternalAnchor) {
+ const QGraphicsAnchorLayoutPrivate::Orientation orient =
+ QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge);
- QSizePolicy::Policy policy;
- qreal minSizeHint, prefSizeHint, maxSizeHint;
- if (orient == QGraphicsAnchorLayoutPrivate::Horizontal) {
- policy = item->sizePolicy().horizontalPolicy();
- minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).width();
- prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).width();
- maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).width();
+ if (isLayoutAnchor) {
+ minSize = 0;
+ prefSize = 0;
+ expSize = 0;
+ maxSize = QWIDGETSIZE_MAX;
} else {
- policy = item->sizePolicy().verticalPolicy();
- minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).height();
- prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).height();
- maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).height();
+ QGraphicsLayoutItem *item = from->m_item;
+ sizeHintsFromItem(item, orient, &minSize, &prefSize, &expSize, &maxSize);
}
- // minSize, prefSize and maxSize are initialized
- // with item's preferred Size: this is QSizePolicy::Fixed.
- //
- // Then we check each flag to find the resultant QSizePolicy,
- // according to the following table:
- //
- // constant value
- // QSizePolicy::Fixed 0
- // QSizePolicy::Minimum GrowFlag
- // QSizePolicy::Maximum ShrinkFlag
- // QSizePolicy::Preferred GrowFlag | ShrinkFlag
- // QSizePolicy::Ignored GrowFlag | ShrinkFlag | IgnoreFlag
- prefSize = prefSizeHint;
- minSize = prefSize;
- maxSize = prefSize;
-
- if (policy & QSizePolicy::GrowFlag)
- maxSize = maxSizeHint;
-
- if (policy & QSizePolicy::ShrinkFlag)
- minSize = minSizeHint;
-
- if (policy & QSizePolicy::IgnoreFlag)
- prefSize = minSize;
+ const Qt::AnchorPoint centerEdge =
+ QGraphicsAnchorLayoutPrivate::pickEdge(Qt::AnchorHorizontalCenter, orient);
bool hasCenter = (from->m_edge == centerEdge || to->m_edge == centerEdge);
if (hasCenter) {
minSize /= 2;
prefSize /= 2;
+ expSize /= 2;
maxSize /= 2;
}
- // Set the anchor effective sizes to preferred.
- //
- // Note: The idea here is that all items should remain at their
- // preferred size unless where that's impossible. In cases where
- // the item is subject to restrictions (anchored to the layout
- // edges, for instance), the simplex solver will be run to
- // recalculate and override the values we set here.
- sizeAtMinimum = prefSize;
- sizeAtPreferred = prefSize;
- sizeAtMaximum = prefSize;
-
} else if (!hasSize) {
// Anchor has no size defined, use given default information
minSize = effectiveSpacing;
prefSize = effectiveSpacing;
+ expSize = effectiveSpacing;
maxSize = effectiveSpacing;
-
- sizeAtMinimum = prefSize;
- sizeAtPreferred = prefSize;
- sizeAtMaximum = prefSize;
}
+
+ // Set the anchor effective sizes to preferred.
+ //
+ // Note: The idea here is that all items should remain at their
+ // preferred size unless where that's impossible. In cases where
+ // the item is subject to restrictions (anchored to the layout
+ // edges, for instance), the simplex solver will be run to
+ // recalculate and override the values we set here.
+ sizeAtMinimum = prefSize;
+ sizeAtPreferred = prefSize;
+ sizeAtExpanding = prefSize;
+ sizeAtMaximum = prefSize;
}
void ParallelAnchorData::updateChildrenSizes()
{
firstEdge->sizeAtMinimum = secondEdge->sizeAtMinimum = sizeAtMinimum;
firstEdge->sizeAtPreferred = secondEdge->sizeAtPreferred = sizeAtPreferred;
+ firstEdge->sizeAtExpanding = secondEdge->sizeAtExpanding = sizeAtExpanding;
firstEdge->sizeAtMaximum = secondEdge->sizeAtMaximum = sizeAtMaximum;
firstEdge->updateChildrenSizes();
@@ -181,9 +212,16 @@ void ParallelAnchorData::updateChildrenSizes()
void ParallelAnchorData::refreshSizeHints(qreal effectiveSpacing)
{
- // First refresh children information
- firstEdge->refreshSizeHints(effectiveSpacing);
- secondEdge->refreshSizeHints(effectiveSpacing);
+ refreshSizeHints_helper(effectiveSpacing);
+}
+
+void ParallelAnchorData::refreshSizeHints_helper(qreal effectiveSpacing,
+ bool refreshChildren)
+{
+ if (refreshChildren) {
+ firstEdge->refreshSizeHints(effectiveSpacing);
+ secondEdge->refreshSizeHints(effectiveSpacing);
+ }
// ### should we warn if the parallel connection is invalid?
// e.g. 1-2-3 with 10-20-30, the minimum of the latter is
@@ -192,12 +230,16 @@ void ParallelAnchorData::refreshSizeHints(qreal effectiveSpacing)
minSize = qMax(firstEdge->minSize, secondEdge->minSize);
maxSize = qMin(firstEdge->maxSize, secondEdge->maxSize);
+ expSize = qMax(firstEdge->expSize, secondEdge->expSize);
+ expSize = qMin(expSize, maxSize);
+
prefSize = qMax(firstEdge->prefSize, secondEdge->prefSize);
- prefSize = qMin(prefSize, maxSize);
+ prefSize = qMin(prefSize, expSize);
// See comment in AnchorData::refreshSizeHints() about sizeAt* values
sizeAtMinimum = prefSize;
sizeAtPreferred = prefSize;
+ sizeAtExpanding = prefSize;
sizeAtMaximum = prefSize;
}
@@ -233,6 +275,21 @@ static qreal getFactor(qreal value, qreal min, qreal pref, qreal max)
}
}
+static qreal getExpandingFactor(const qreal &expSize, const qreal &sizeAtPreferred,
+ const qreal &sizeAtExpanding, const qreal &sizeAtMaximum)
+{
+ const qreal lower = qMin(sizeAtPreferred, sizeAtMaximum);
+ const qreal upper = qMax(sizeAtPreferred, sizeAtMaximum);
+ const qreal boundedExpSize = qBound(lower, expSize, upper);
+
+ const qreal bandSize = sizeAtMaximum - boundedExpSize;
+ if (bandSize == 0) {
+ return 0;
+ } else {
+ return (sizeAtExpanding - boundedExpSize) / bandSize;
+ }
+}
+
void SequentialAnchorData::updateChildrenSizes()
{
// ### REMOVE ME
@@ -242,15 +299,18 @@ void SequentialAnchorData::updateChildrenSizes()
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));
// Band here refers if the value is in the Minimum To Preferred
// band (the lower band) or the Preferred To Maximum (the upper band).
- qreal minFactor = getFactor(sizeAtMinimum, minSize, prefSize, maxSize);
- qreal prefFactor = getFactor(sizeAtPreferred, minSize, prefSize, maxSize);
- qreal maxFactor = getFactor(sizeAtMaximum, minSize, prefSize, maxSize);
+ const qreal minFactor = getFactor(sizeAtMinimum, minSize, prefSize, maxSize);
+ const qreal prefFactor = getFactor(sizeAtPreferred, minSize, prefSize, maxSize);
+ const qreal maxFactor = getFactor(sizeAtMaximum, minSize, prefSize, maxSize);
+ const qreal expFactor = getExpandingFactor(expSize, sizeAtPreferred, sizeAtExpanding, sizeAtMaximum);
for (int i = 0; i < m_edges.count(); ++i) {
AnchorData *e = m_edges.at(i);
@@ -264,30 +324,45 @@ void SequentialAnchorData::updateChildrenSizes()
bandSize = maxFactor > 0 ? e->maxSize - e->prefSize : e->prefSize - e->minSize;
e->sizeAtMaximum = e->prefSize + bandSize * maxFactor;
+ const qreal lower = qMin(e->sizeAtPreferred, e->sizeAtMaximum);
+ const qreal upper = qMax(e->sizeAtPreferred, e->sizeAtMaximum);
+ const qreal edgeBoundedExpSize = qBound(lower, e->expSize, upper);
+ e->sizeAtExpanding = edgeBoundedExpSize + expFactor * (e->sizeAtMaximum - edgeBoundedExpSize);
+
e->updateChildrenSizes();
}
}
void SequentialAnchorData::refreshSizeHints(qreal effectiveSpacing)
{
+ refreshSizeHints_helper(effectiveSpacing);
+}
+
+void SequentialAnchorData::refreshSizeHints_helper(qreal effectiveSpacing,
+ bool refreshChildren)
+{
minSize = 0;
prefSize = 0;
+ expSize = 0;
maxSize = 0;
for (int i = 0; i < m_edges.count(); ++i) {
AnchorData *edge = m_edges.at(i);
- // First refresh children information
- edge->refreshSizeHints(effectiveSpacing);
+ // If it's the case refresh children information first
+ if (refreshChildren)
+ edge->refreshSizeHints(effectiveSpacing);
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;
}
@@ -357,6 +432,12 @@ QGraphicsAnchorLayoutPrivate::QGraphicsAnchorLayoutPrivate()
: calculateGraphCacheDirty(1)
{
for (int i = 0; i < NOrientations; ++i) {
+ 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;
@@ -422,39 +503,21 @@ static bool simplifySequentialChunk(Graph<AnchorVertex, AnchorData> *graph,
qDebug("simplifying [%s] to [%s - %s]", qPrintable(strPath), qPrintable(before->toString()), qPrintable(after->toString()));
#endif
- qreal min = 0;
- qreal pref = 0;
- qreal max = 0;
-
SequentialAnchorData *sequence = new SequentialAnchorData;
AnchorVertex *prev = before;
AnchorData *data;
for (i = 0; i <= vertices.count(); ++i) {
AnchorVertex *next = (i < vertices.count()) ? vertices.at(i) : after;
data = graph->takeEdge(prev, next);
- min += data->minSize;
- pref += data->prefSize;
- max = checkAdd(max, data->maxSize);
sequence->m_edges.append(data);
prev = next;
}
-
- // insert new
- sequence->minSize = min;
- sequence->prefSize = pref;
- sequence->maxSize = max;
-
- // Unless these values are overhidden by the simplex solver later-on,
- // anchors will keep their own preferred size.
- sequence->sizeAtMinimum = pref;
- sequence->sizeAtPreferred = pref;
- sequence->sizeAtMaximum = pref;
-
sequence->setVertices(vertices);
-
sequence->from = before;
sequence->to = after;
+ sequence->refreshSizeHints_helper(0, false);
+
// data here is the last edge in the sequence
// ### this seems to be here for supporting reverse order sequences,
// but doesnt seem to be used right now
@@ -469,25 +532,11 @@ static bool simplifySequentialChunk(Graph<AnchorVertex, AnchorData> *graph,
AnchorData *newAnchor = sequence;
if (AnchorData *oldAnchor = graph->takeEdge(before, after)) {
- newAnchor = new ParallelAnchorData(oldAnchor, sequence);
-
- newAnchor->isLayoutAnchor = (oldAnchor->isLayoutAnchor
+ ParallelAnchorData *parallel = new ParallelAnchorData(oldAnchor, sequence);
+ parallel->isLayoutAnchor = (oldAnchor->isLayoutAnchor
|| sequence->isLayoutAnchor);
-
- min = qMax(oldAnchor->minSize, sequence->minSize);
- max = qMin(oldAnchor->maxSize, sequence->maxSize);
-
- pref = qMax(oldAnchor->prefSize, sequence->prefSize);
- pref = qMin(pref, max);
-
- newAnchor->minSize = min;
- newAnchor->prefSize = pref;
- newAnchor->maxSize = max;
-
- // Same as above, by default, keep preferred size.
- newAnchor->sizeAtMinimum = pref;
- newAnchor->sizeAtPreferred = pref;
- newAnchor->sizeAtMaximum = pref;
+ parallel->refreshSizeHints_helper(0, false);
+ newAnchor = parallel;
}
graph->createEdge(before, after, newAnchor);
@@ -817,9 +866,10 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges()
QGraphicsLayoutItem *layout = q;
// Horizontal
- AnchorData *data = new AnchorData(0, 0, QWIDGETSIZE_MAX);
+ AnchorData *data = new AnchorData;
addAnchor_helper(layout, Qt::AnchorLeft, layout,
- Qt::AnchorRight, data);
+ Qt::AnchorRight, data);
+ data->maxSize = QWIDGETSIZE_MAX;
data->skipInPreferred = 1;
// Set the Layout Left edge as the root of the horizontal graph.
@@ -827,9 +877,10 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges()
graph[Horizontal].setRootVertex(v);
// Vertical
- data = new AnchorData(0, 0, QWIDGETSIZE_MAX);
+ data = new AnchorData;
addAnchor_helper(layout, Qt::AnchorTop, layout,
- Qt::AnchorBottom, data);
+ Qt::AnchorBottom, data);
+ data->maxSize = QWIDGETSIZE_MAX;
data->skipInPreferred = 1;
// Set the Layout Top edge as the root of the vertical graph.
@@ -856,19 +907,15 @@ void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item)
items.append(item);
- QSizeF minSize = item->effectiveSizeHint(Qt::MinimumSize);
- QSizeF prefSize = item->effectiveSizeHint(Qt::PreferredSize);
- QSizeF maxSize = item->effectiveSizeHint(Qt::MaximumSize);
-
- // Horizontal
- AnchorData *data = new AnchorData(minSize.width(), prefSize.width(), maxSize.width());
- addAnchor_helper(item, Qt::AnchorLeft, item,
- Qt::AnchorRight, data);
+ // Create horizontal and vertical internal anchors for the item and
+ // refresh its size hint / policy values.
+ AnchorData *data = new AnchorData;
+ addAnchor_helper(item, Qt::AnchorLeft, item, Qt::AnchorRight, data);
+ data->refreshSizeHints(0); // 0 = effectiveSpacing, will not be used
- // Vertical
- data = new AnchorData(minSize.height(), prefSize.height(), maxSize.height());
- addAnchor_helper(item, Qt::AnchorTop, item,
- Qt::AnchorBottom, data);
+ data = new AnchorData;
+ addAnchor_helper(item, Qt::AnchorTop, item, Qt::AnchorBottom, data);
+ data->refreshSizeHints(0); // 0 = effectiveSpacing, will not be used
}
/*!
@@ -921,20 +968,17 @@ void QGraphicsAnchorLayoutPrivate::createCenterAnchors(
Q_ASSERT(first && last);
// Create new anchors
- AnchorData *oldData = graph[orientation].edgeData(first, last);
-
- qreal minimumSize = oldData->minSize / 2;
- qreal preferredSize = oldData->prefSize / 2;
- qreal maximumSize = oldData->maxSize / 2;
-
QSimplexConstraint *c = new QSimplexConstraint;
- AnchorData *data = new AnchorData(minimumSize, preferredSize, maximumSize);
+
+ AnchorData *data = new AnchorData;
c->variables.insert(data, 1.0);
addAnchor_helper(item, firstEdge, item, centerEdge, data);
+ data->refreshSizeHints(0);
- data = new AnchorData(minimumSize, preferredSize, maximumSize);
+ data = new AnchorData;
c->variables.insert(data, -1.0);
addAnchor_helper(item, centerEdge, item, lastEdge, data);
+ data->refreshSizeHints(0);
itemCenterConstraints[orientation].append(c);
@@ -995,14 +1039,9 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
if (substitute) {
// Create the new anchor that should substitute the left-center-right anchors.
- AnchorData *oldData = g.edgeData(first, center);
-
- qreal minimumSize = oldData->minSize * 2;
- qreal preferredSize = oldData->prefSize * 2;
- qreal maximumSize = oldData->maxSize * 2;
-
- AnchorData *data = new AnchorData(minimumSize, preferredSize, maximumSize);
+ AnchorData *data = new AnchorData;
addAnchor_helper(item, firstEdge, item, lastEdge, data);
+ data->refreshSizeHints(0);
// Remove old anchors
removeAnchor_helper(first, center);
@@ -1120,7 +1159,7 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *fi
// Use heuristics to find out what the user meant with this anchor.
correctEdgeDirection(firstItem, firstEdge, secondItem, secondEdge);
- AnchorData *data;
+ AnchorData *data = new AnchorData;
if (!spacing) {
// If firstItem or secondItem is the layout itself, the spacing will default to 0.
// Otherwise, the following matrix is used (questionmark means that the spacing
@@ -1130,22 +1169,25 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *fi
// Left 0 0 ?
// HCenter 0 0 0
// Right ? 0 0
- if (firstItem != q
- && secondItem != q
- && pickEdge(firstEdge, Horizontal) != Qt::AnchorHorizontalCenter
- && oppositeEdge(firstEdge) == secondEdge) {
- data = new AnchorData; // ask the style later
+ if (firstItem == q
+ || secondItem == q
+ || pickEdge(firstEdge, Horizontal) == Qt::AnchorHorizontalCenter
+ || oppositeEdge(firstEdge) != secondEdge) {
+ data->setFixedSize(0);
} else {
- data = new AnchorData(0); // spacing should be 0
+ data->unsetSize();
}
addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data);
+
} else if (*spacing >= 0) {
- data = new AnchorData(*spacing);
+ data->setFixedSize(*spacing);
addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data);
+
} else {
- data = new AnchorData(-*spacing);
+ data->setFixedSize(-*spacing);
addAnchor_helper(secondItem, secondEdge, firstItem, firstEdge, data);
}
+
return acquireGraphicsAnchor(data);
}
@@ -1622,11 +1664,18 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
qreal min, max;
feasible = solveMinMax(trunkConstraints, trunkPath, &min, &max);
- // Solve for preferred. The objective function is calculated from the constraints
- // and variables internally.
- feasible &= solvePreferred(trunkConstraints);
-
if (feasible) {
+ // Solve for preferred. The objective function is calculated from the constraints
+ // and variables internally.
+ solvePreferred(trunkConstraints);
+
+ // remove sizeHintConstraints from trunkConstraints
+ trunkConstraints = parts[0];
+
+ // Solve for expanding. The objective function and the constraints from items
+ // are calculated internally.
+ solveExpanding(trunkConstraints);
+
// Propagate the new sizes down the simplified graph, ie. tell the
// group anchors to set their children anchors sizes.
@@ -1636,19 +1685,23 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
for (int i = 0; i < trunkVariables.count(); ++i)
trunkVariables.at(i)->updateChildrenSizes();
- // Calculate and set the preferred size for the layout from the edge sizes that
- // were calculated above.
+ // Calculate and set the preferred and expanding sizes for the layout,
+ // from the edge sizes that were calculated above.
qreal pref(0.0);
+ qreal expanding(0.0);
foreach (const AnchorData *ad, trunkPath.positives) {
pref += ad->sizeAtPreferred;
+ expanding += ad->sizeAtExpanding;
}
foreach (const AnchorData *ad, trunkPath.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;
}
} else {
#if 0
@@ -1664,6 +1717,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
AnchorData *ad = trunkPath.positives.toList()[0];
ad->sizeAtMinimum = ad->minSize;
ad->sizeAtPreferred = ad->prefSize;
+ ad->sizeAtExpanding = ad->expSize;
ad->sizeAtMaximum = ad->maxSize;
// Propagate
@@ -1672,6 +1726,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
sizeHints[orientation][Qt::MinimumSize] = ad->sizeAtMinimum;
sizeHints[orientation][Qt::PreferredSize] = ad->sizeAtPreferred;
sizeHints[orientation][Qt::MaximumSize] = ad->sizeAtMaximum;
+ sizeAtExpanding[orientation] = ad->sizeAtExpanding;
}
// Delete the constraints, we won't use them anymore.
@@ -1701,6 +1756,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
AnchorData *ad = partVariables[j];
Q_ASSERT(ad);
ad->sizeAtMinimum = ad->sizeAtPreferred;
+ ad->sizeAtExpanding = ad->sizeAtPreferred;
ad->sizeAtMaximum = ad->sizeAtPreferred;
ad->updateChildrenSizes();
}
@@ -1785,6 +1841,11 @@ void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation)
queue.enqueue(qMakePair(pair.second, v));
}
}
+
+ // We will walk through every reachable items (non-float) store them in a temporary set.
+ // We them create a set of all items and subtract the non-floating items from the set in
+ // order to get the floating items. The floating items is then stored in m_floatItems
+ identifyFloatItems(visited, orientation);
}
/*!
@@ -1943,6 +2004,52 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
}
/*!
+ \internal
+
+ Use all visited Anchors on findPaths() so we can identify non-float Items.
+*/
+void QGraphicsAnchorLayoutPrivate::identifyFloatItems(const QSet<AnchorData *> &visited, Orientation orientation)
+{
+ QSet<QGraphicsLayoutItem *> nonFloating;
+
+ foreach (const AnchorData *ad, visited)
+ identifyNonFloatItems_helper(ad, &nonFloating);
+
+ QSet<QGraphicsLayoutItem *> allItems;
+ foreach (QGraphicsLayoutItem *item, items)
+ allItems.insert(item);
+ m_floatItems[orientation] = allItems - nonFloating;
+}
+
+
+/*!
+ \internal
+
+ Given an anchor, if it is an internal anchor and Normal we must mark it's item as non-float.
+ If the anchor is Sequential or Parallel, we must iterate on its children recursively until we reach
+ internal anchors (items).
+*/
+void QGraphicsAnchorLayoutPrivate::identifyNonFloatItems_helper(const AnchorData *ad, QSet<QGraphicsLayoutItem *> *nonFloatingItemsIdentifiedSoFar)
+{
+ Q_Q(QGraphicsAnchorLayout);
+
+ switch(ad->type) {
+ case AnchorData::Normal:
+ if (ad->from->m_item == ad->to->m_item && ad->to->m_item != q)
+ nonFloatingItemsIdentifiedSoFar->insert(ad->to->m_item);
+ break;
+ case AnchorData::Sequential:
+ foreach (const AnchorData *d, static_cast<const SequentialAnchorData *>(ad)->m_edges)
+ identifyNonFloatItems_helper(d, nonFloatingItemsIdentifiedSoFar);
+ break;
+ case AnchorData::Parallel:
+ identifyNonFloatItems_helper(static_cast<const ParallelAnchorData *>(ad)->firstEdge, nonFloatingItemsIdentifiedSoFar);
+ identifyNonFloatItems_helper(static_cast<const ParallelAnchorData *>(ad)->secondEdge, nonFloatingItemsIdentifiedSoFar);
+ break;
+ }
+}
+
+/*!
\internal
Use the current vertices distance to calculate and set the geometry of
@@ -1967,22 +2074,35 @@ void QGraphicsAnchorLayoutPrivate::setItemsGeometries(const QRectF &geom)
right = geom.right() - right;
foreach (QGraphicsLayoutItem *item, items) {
- firstH = internalVertex(item, Qt::AnchorLeft);
- secondH = internalVertex(item, Qt::AnchorRight);
- firstV = internalVertex(item, Qt::AnchorTop);
- secondV = internalVertex(item, Qt::AnchorBottom);
-
QRectF newGeom;
- newGeom.setTop(top + firstV->distance);
- newGeom.setBottom(top + secondV->distance);
+ QSizeF itemPreferredSize = item->effectiveSizeHint(Qt::PreferredSize);
+ if (m_floatItems[Horizontal].contains(item)) {
+ newGeom.setLeft(0);
+ newGeom.setRight(itemPreferredSize.width());
+ } else {
+ firstH = internalVertex(item, Qt::AnchorLeft);
+ secondH = internalVertex(item, Qt::AnchorRight);
+
+ if (visualDir == Qt::LeftToRight) {
+ newGeom.setLeft(left + firstH->distance);
+ newGeom.setRight(left + secondH->distance);
+ } else {
+ newGeom.setLeft(right - secondH->distance);
+ newGeom.setRight(right - firstH->distance);
+ }
+ }
- if (visualDir == Qt::LeftToRight) {
- newGeom.setLeft(left + firstH->distance);
- newGeom.setRight(left + secondH->distance);
+ if (m_floatItems[Vertical].contains(item)) {
+ newGeom.setTop(0);
+ newGeom.setBottom(itemPreferredSize.height());
} else {
- newGeom.setLeft(right - secondH->distance);
- newGeom.setRight(right - firstH->distance);
+ firstV = internalVertex(item, Qt::AnchorTop);
+ secondV = internalVertex(item, Qt::AnchorBottom);
+
+ newGeom.setTop(top + firstV->distance);
+ newGeom.setBottom(top + secondV->distance);
}
+
item->setGeometry(newGeom);
}
}
@@ -2058,9 +2178,13 @@ void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation(
interpolationInterval[orientation] = MinToPreferred;
lower = sizeHints[orientation][Qt::MinimumSize];
upper = sizeHints[orientation][Qt::PreferredSize];
- } else {
- interpolationInterval[orientation] = PreferredToMax;
+ } else if (current < sizeAtExpanding[orientation]) {
+ interpolationInterval[orientation] = PreferredToExpanding;
lower = sizeHints[orientation][Qt::PreferredSize];
+ upper = sizeAtExpanding[orientation];
+ } else {
+ interpolationInterval[orientation] = ExpandingToMax;
+ lower = sizeAtExpanding[orientation];
upper = sizeHints[orientation][Qt::MaximumSize];
}
@@ -2075,11 +2199,12 @@ void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation(
\internal
Calculate the current Edge size based on the current Layout size and the
- size the edge is supposed to have when:
+ size the edge is supposed to have when the layout is at its:
- - the layout is at its minimum size.
- - the layout is at its preferred size.
- - the layout is at its maximum size.
+ - minimum size,
+ - preferred size,
+ - size when all expanding anchors are expanded,
+ - maximum size.
These three key values are calculated in advance using linear
programming (more expensive) or the simplification algorithm, then
@@ -2099,8 +2224,11 @@ void QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorVertex *base,
if (interpolationInterval[orientation] == MinToPreferred) {
lower = edge->sizeAtMinimum;
upper = edge->sizeAtPreferred;
- } else {
+ } else if (interpolationInterval[orientation] == PreferredToExpanding) {
lower = edge->sizeAtPreferred;
+ upper = edge->sizeAtExpanding;
+ } else {
+ lower = edge->sizeAtExpanding;
upper = edge->sizeAtMaximum;
}
@@ -2289,6 +2417,139 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList<QSimplexConstraint *> co
/*!
\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(QList<QSimplexConstraint *> constraints)
+{
+ QList<AnchorData *> variables = getVariables(constraints);
+ 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) {
+ // 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.
@@ -2298,7 +2559,10 @@ bool QGraphicsAnchorLayoutPrivate::hasConflicts() const
{
QGraphicsAnchorLayoutPrivate *that = const_cast<QGraphicsAnchorLayoutPrivate*>(this);
that->calculateGraphs();
- return graphHasConflicts[0] || graphHasConflicts[1];
+
+ bool floatConflict = !m_floatItems[0].isEmpty() || !m_floatItems[1].isEmpty();
+
+ return graphHasConflicts[0] || graphHasConflicts[1] || floatConflict;
}
#ifdef QT_DEBUG
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
index c86bfa3..9ac0e19 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
@@ -149,30 +149,14 @@ struct AnchorData : public QSimplexVariable {
Sequential,
Parallel
};
- AnchorData(qreal minimumSize, qreal preferredSize, qreal maximumSize)
- : QSimplexVariable(), from(0), to(0),
- minSize(minimumSize), prefSize(preferredSize),
- maxSize(maximumSize), sizeAtMinimum(preferredSize),
- sizeAtPreferred(preferredSize), sizeAtMaximum(preferredSize),
- graphicsAnchor(0),
- skipInPreferred(0), type(Normal), hasSize(true),
- isLayoutAnchor(false) {}
-
- AnchorData(qreal size)
- : QSimplexVariable(), from(0), to(0),
- minSize(size), prefSize(size), maxSize(size),
- sizeAtMinimum(size), sizeAtPreferred(size), sizeAtMaximum(size),
- graphicsAnchor(0),
- skipInPreferred(0), type(Normal), hasSize(true),
- isLayoutAnchor(false) {}
AnchorData()
: QSimplexVariable(), from(0), to(0),
- minSize(0), prefSize(0), maxSize(0),
- sizeAtMinimum(0), sizeAtPreferred(0), sizeAtMaximum(0),
- graphicsAnchor(0),
- skipInPreferred(0), type(Normal), hasSize(false),
- isLayoutAnchor(false) {}
+ minSize(0), prefSize(0), expSize(0), maxSize(0),
+ sizeAtMinimum(0), sizeAtPreferred(0),
+ sizeAtExpanding(0), sizeAtMaximum(0),
+ graphicsAnchor(0), skipInPreferred(0),
+ type(Normal), hasSize(true), isLayoutAnchor(false) {}
virtual void updateChildrenSizes() {}
virtual void refreshSizeHints(qreal effectiveSpacing);
@@ -189,9 +173,11 @@ struct AnchorData : public QSimplexVariable {
{
minSize = size;
prefSize = size;
+ expSize = size;
maxSize = size;
sizeAtMinimum = size;
sizeAtPreferred = size;
+ sizeAtExpanding = size;
sizeAtMaximum = size;
hasSize = true;
}
@@ -211,6 +197,7 @@ 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
@@ -218,6 +205,7 @@ 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;
@@ -225,15 +213,6 @@ struct AnchorData : public QSimplexVariable {
uint type : 2; // either Normal, Sequential or Parallel
uint hasSize : 1; // if false, get size from style.
uint isLayoutAnchor : 1; // if this anchor is connected to a layout 'edge'
-protected:
- AnchorData(Type type, qreal size = 0)
- : QSimplexVariable(), from(0), to(0),
- minSize(size), prefSize(size),
- maxSize(size), sizeAtMinimum(size),
- sizeAtPreferred(size), sizeAtMaximum(size),
- graphicsAnchor(0),
- skipInPreferred(0), type(type), hasSize(true),
- isLayoutAnchor(false) {}
};
#ifdef QT_DEBUG
@@ -245,8 +224,9 @@ inline QString AnchorData::toString() const
struct SequentialAnchorData : public AnchorData
{
- SequentialAnchorData() : AnchorData(AnchorData::Sequential)
+ SequentialAnchorData() : AnchorData()
{
+ type = AnchorData::Sequential;
#ifdef QT_DEBUG
name = QLatin1String("SequentialAnchorData");
#endif
@@ -255,6 +235,8 @@ struct SequentialAnchorData : public AnchorData
virtual void updateChildrenSizes();
virtual void refreshSizeHints(qreal effectiveSpacing);
+ void refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true);
+
void setVertices(const QVector<AnchorVertex*> &vertices)
{
m_children = vertices;
@@ -270,9 +252,10 @@ struct SequentialAnchorData : public AnchorData
struct ParallelAnchorData : public AnchorData
{
ParallelAnchorData(AnchorData *first, AnchorData *second)
- : AnchorData(AnchorData::Parallel),
- firstEdge(first), secondEdge(second)
+ : AnchorData(), firstEdge(first), secondEdge(second)
{
+ type = AnchorData::Parallel;
+
// ### 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);
@@ -287,6 +270,8 @@ struct ParallelAnchorData : public AnchorData
virtual void updateChildrenSizes();
virtual void refreshSizeHints(qreal effectiveSpacing);
+ void refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true);
+
AnchorData* firstEdge;
AnchorData* secondEdge;
};
@@ -355,7 +340,8 @@ public:
// Interval represents which interpolation interval are we operating in.
enum Interval {
MinToPreferred = 0,
- PreferredToMax
+ PreferredToExpanding,
+ ExpandingToMax
};
// Several structures internal to the layout are duplicated to handle
@@ -457,6 +443,8 @@ public:
void constraintsFromPaths(Orientation orientation);
QList<QSimplexConstraint *> constraintsFromSizeHints(const QList<AnchorData *> &anchors);
QList<QList<QSimplexConstraint *> > getGraphParts(Orientation orientation);
+ void identifyFloatItems(const QSet<AnchorData *> &visited, Orientation orientation);
+ void identifyNonFloatItems_helper(const AnchorData *ad, QSet<QGraphicsLayoutItem *> *nonFloatingItemsIdentifiedSoFar);
inline AnchorVertex *internalVertex(const QPair<QGraphicsLayoutItem*, Qt::AnchorPoint> &itemEdge) const
{
@@ -486,6 +474,7 @@ public:
bool solveMinMax(QList<QSimplexConstraint *> constraints,
GraphPath path, qreal *min, qreal *max);
bool solvePreferred(QList<QSimplexConstraint *> constraints);
+ void solveExpanding(QList<QSimplexConstraint *> constraints);
bool hasConflicts() const;
#ifdef QT_DEBUG
@@ -496,6 +485,7 @@ public:
qreal spacings[NOrientations];
// Size hints from simplex engine
qreal sizeHints[2][3];
+ qreal sizeAtExpanding[2];
// Items
QVector<QGraphicsLayoutItem *> items;
@@ -521,6 +511,7 @@ public:
// ###
bool graphSimplified[2];
bool graphHasConflicts[2];
+ QSet<QGraphicsLayoutItem *> m_floatItems[2];
uint calculateGraphCacheDirty : 1;
};
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index d7a7bd2..45627f6 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -186,6 +186,49 @@
high z-values. Stacking order applies to sibling items; parents are always
drawn before their children.
+ \section1 Sorting
+
+ All items are drawn in a defined, stable order, and this same order decides
+ which items will receive mouse input first when you click on the scene.
+ Normally you don't have to worry about sorting, as the items follow a
+ "natural order", following the logical structure of the scene.
+
+ An item's children are stacked on top of the parent, and sibling items are
+ stacked by insertion order (i.e., in the same order that they were either
+ added to the scene, or added to the same parent). If you add item A, and
+ then B, then B will be on top of A. If you then add C, the items' stacking
+ order will be A, then B, then C.
+
+ \image graphicsview-zorder.png
+
+ This example shows the stacking order of all limbs of the robot from the
+ \l{graphicsview/dragdroprobot}{Drag and Drop Robot} example. The torso is
+ the root item (all other items are children or descendants of the torso),
+ so it is drawn first. Next, the head is drawn, as it is the first item in
+ the torso's list of children. Then the upper left arm is drawn. As the
+ lower arm is a child of the upper arm, the lower arm is then drawn,
+ followed by the upper arm's next sibling, which is the upper right arm, and
+ so on.
+
+ For advanced users, there are ways to alter how your items are sorted:
+
+ \list
+ \o You can call setZValue() on an item to explicitly stack it on top of, or
+ under, other sibling items. The default Z value for an item is 0. Items
+ with the same Z value are stacked by insertion order.
+
+ \o You can call stackBefore() to reorder the list of children. This will
+ directly modify the insertion order.
+
+ \o You can set the ItemStacksBehindParent flag to stack a child item behind
+ its parent.
+ \endlist
+
+ The stacking order of two sibling items also counts for each item's
+ children and descendant items. So if one item is on top of another, then
+ all its children will also be on top of all the other item's children as
+ well.
+
\section1 Events
QGraphicsItem receives events from QGraphicsScene through the virtual
@@ -564,6 +607,22 @@
supportsExtension() and setExtension().
*/
+/*!
+ \enum QGraphicsItem::PanelModality
+ \since 4.6
+
+ This enum specifies the behavior of a modal panel. A modal panel
+ is one that blocks input to other panels. Note that items that
+ are children of a modal panel are not blocked.
+
+ The values are:
+ \value NonModal The panel is not modal and does not block input to other panels.
+ \value PanelModal The panel is modal to a single item hierarchy and blocks input to its parent pane, all grandparent panels, and all siblings of its parent and grandparent panels.
+ \value SceneModal The window is modal to the entire scene and blocks input to all panels.
+
+ \sa QGraphicsItem::setPanelModality(), QGraphicsItem::panelModality(), QGraphicsItem::ItemIsPanel
+*/
+
#include "qgraphicsitem.h"
#ifndef QT_NO_GRAPHICSVIEW
@@ -604,6 +663,8 @@
#include <private/qpixmap_x11_p.h>
#endif
+#include <private/qgesturemanager_p.h>
+
#include <math.h>
QT_BEGIN_NAMESPACE
@@ -1472,10 +1533,12 @@ QList<QGraphicsItem *> QGraphicsItem::children() const
/*!
\since 4.4
- Returns a list of this item's children. The items are returned in no
- particular order.
+ Returns a list of this item's children.
- \sa setParentItem()
+ The items are sorted by stacking order. This takes into account both the
+ items' insertion order and their Z-values.
+
+ \sa setParentItem(), zValue(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsItem::childItems() const
{
@@ -1649,6 +1712,16 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
setFlag(ItemStacksBehindParent, d_ptr->z < qreal(0.0));
}
+ if ((d_ptr->panelModality != NonModal)
+ && d_ptr->scene
+ && (flags & ItemIsPanel) != (oldFlags & ItemIsPanel)) {
+ // update the panel's modal state
+ if (flags & ItemIsPanel)
+ d_ptr->scene->d_func()->enterModal(this);
+ else
+ d_ptr->scene->d_func()->leaveModal(this);
+ }
+
if (d_ptr->scene) {
d_ptr->scene->d_func()->markDirty(this, QRectF(),
/*invalidateChildren=*/true,
@@ -1725,6 +1798,87 @@ void QGraphicsItem::setCacheMode(CacheMode mode, const QSize &logicalCacheSize)
update();
}
+/*!
+ \since 4.6
+
+ Returns the modality for this item.
+*/
+QGraphicsItem::PanelModality QGraphicsItem::panelModality() const
+{
+ return d_ptr->panelModality;
+}
+
+/*!
+ \since 4.6
+
+ Sets the modality for this item to \a panelModality.
+
+ Changing the modality of a visible item takes effect immediately.
+*/
+void QGraphicsItem::setPanelModality(PanelModality panelModality)
+{
+ if (d_ptr->panelModality == panelModality)
+ return;
+
+ PanelModality previousModality = d_ptr->panelModality;
+ bool enterLeaveModal = (isPanel() && d_ptr->scene && isVisible());
+ if (enterLeaveModal && panelModality == NonModal)
+ d_ptr->scene->d_func()->leaveModal(this);
+ d_ptr->panelModality = panelModality;
+ if (enterLeaveModal && d_ptr->panelModality != NonModal)
+ d_ptr->scene->d_func()->enterModal(this, previousModality);
+}
+
+/*!
+ \since 4.6
+
+ Returns true if this item is blocked by a modal panel, false otherwise. If \a blockingPanel is
+ non-zero, \a blockingPanel will be set to the modal panel that is blocking this item. If this
+ item is not blocked, \a blockingPanel will not be set by this function.
+
+ This function always returns false for items not in a scene.
+
+ \sa panelModality() setPanelModality() PanelModality
+*/
+bool QGraphicsItem::isBlockedByModalPanel(QGraphicsItem **blockingPanel) const
+{
+ if (!d_ptr->scene)
+ return false;
+
+
+ QGraphicsItem *dummy = 0;
+ if (!blockingPanel)
+ blockingPanel = &dummy;
+
+ QGraphicsScenePrivate *scene_d = d_ptr->scene->d_func();
+ if (scene_d->modalPanels.isEmpty())
+ return false;
+
+ // ###
+ if (!scene_d->popupWidgets.isEmpty() && scene_d->popupWidgets.first() == this)
+ return false;
+
+ for (int i = 0; i < scene_d->modalPanels.count(); ++i) {
+ QGraphicsItem *modalPanel = scene_d->modalPanels.at(i);
+ if (modalPanel->panelModality() == QGraphicsItem::SceneModal) {
+ // Scene modal panels block all non-descendents.
+ if (modalPanel != this && !modalPanel->isAncestorOf(this)) {
+ *blockingPanel = modalPanel;
+ return true;
+ }
+ } else {
+ // Window modal panels block ancestors and siblings/cousins.
+ if (modalPanel != this
+ && !modalPanel->isAncestorOf(this)
+ && commonAncestorItem(modalPanel)) {
+ *blockingPanel = modalPanel;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
#ifndef QT_NO_TOOLTIP
/*!
Returns the item's tool tip, or an empty QString if no tool tip has been
@@ -1934,6 +2088,8 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
q->ungrabMouse();
if (scene->d_func()->keyboardGrabberItems.contains(q))
q->ungrabKeyboard();
+ if (q->isPanel() && panelModality != QGraphicsItem::NonModal)
+ scene->d_func()->leaveModal(q_ptr);
}
if (q_ptr->hasFocus() && scene) {
// Hiding the closest non-panel ancestor of the focus item
@@ -1955,10 +2111,15 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
} else {
geometryChanged = 1;
paintedViewBoundingRectsNeedRepaint = 1;
- if (isWidget && scene) {
- QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
- if (widget->windowType() == Qt::Popup)
- scene->d_func()->addPopup(widget);
+ if (scene) {
+ if (isWidget) {
+ QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
+ if (widget->windowType() == Qt::Popup)
+ scene->d_func()->addPopup(widget);
+ }
+ if (q->isPanel() && panelModality != QGraphicsItem::NonModal) {
+ scene->d_func()->enterModal(q_ptr);
+ }
}
}
@@ -2781,7 +2942,7 @@ bool QGraphicsItem::hasFocus() const
the preferred focus item for its subtree of items, should it later become
visible.
- As a result of calling this function, this item will receive a
+ As a result of calling this function, this item will receive a
\l{focusInEvent()}{focus in event} with \a focusReason. If another item
already has focus, that item will first receive a \l{focusOutEvent()}
{focus out event} indicating that it has lost input focus.
@@ -3299,7 +3460,7 @@ QMatrix QGraphicsItem::matrix() const
The transformation matrix is combined with the item's rotation(), scale()
and transformations() into a combined transformations for the item.
-
+
The default transformation matrix is an identity matrix.
\sa setTransform(), sceneTransform()
@@ -3780,7 +3941,7 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
// Update and set the new transformation.
d_ptr->setTransformHelper(newTransform);
-
+
// Send post-notification.
itemChange(ItemTransformHasChanged, qVariantFromValue<QTransform>(newTransform));
}
@@ -3914,7 +4075,7 @@ void QGraphicsItem::scale(qreal sx, qreal sy)
/*!
\obsolete
- Use
+ Use
\code
setTransform(QTransform().shear(sh, sv), true);
@@ -3936,7 +4097,7 @@ void QGraphicsItem::shear(qreal sh, qreal sv)
Use setPos() or setTransformOriginPoint() instead. For identical
behavior, use
-
+
\code
setTransform(QTransform::fromTranslate(dx, dy), true);
\endcode
@@ -3977,12 +4138,12 @@ void QGraphicsItem::advance(int phase)
}
/*!
- Returns the Z-value, or the elevation, of the item. The Z-value decides
- the stacking order of sibling (neighboring) items.
+ Returns the Z-value of the item. The Z-value affects the stacking order of
+ sibling (neighboring) items.
The default Z-value is 0.
- \sa setZValue()
+ \sa setZValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
*/
qreal QGraphicsItem::zValue() const
{
@@ -3990,33 +4151,18 @@ qreal QGraphicsItem::zValue() const
}
/*!
- Sets the Z-value, or the elevation, of the item, to \a z. The elevation
- decides the stacking order of sibling (neighboring) items. An item of high
- Z-value will be drawn on top of an item with a lower Z-value if they share
- the same parent item. In addition, children of an item will always be
- drawn on top of the parent, regardless of the child's Z-value. Sibling
- items that share the same Z-value will be drawn in order of insertion; the
- last inserted child is stacked above previous children.
-
- \img graphicsview-zorder.png
+ Sets the Z-value of the item to \a z. The Z value decides the stacking
+ order of sibling (neighboring) items. A sibling item of high Z value will
+ always be drawn on top of another sibling item with a lower Z value.
- Children of different parents are stacked according to the Z-value of
- each item's ancestor item which is an immediate child of the two
- items' closest common ancestor. For example, a robot item might
- define a torso item as the parent of a head item, two arm items,
- and two upper-leg items. The upper-leg items would each be parents
- of one lower-leg item, and each lower-leg item would be parents of
- one foot item. The stacking order of the feet is the same as the
- stacking order of each foot's ancestor that is an immediate child
- of the two feet's common ancestor (i.e., the torso item); so the
- feet are stacked in the same order as the upper-leg items,
- regardless of each foot's Z-value.
+ If you restore the Z value, the item's insertion order will decide its
+ stacking order.
The Z-value does not affect the item's size in any way.
The default Z-value is 0.
- \sa zValue()
+ \sa zValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
*/
void QGraphicsItem::setZValue(qreal z)
{
@@ -4079,12 +4225,13 @@ void QGraphicsItemPrivate::ensureSequentialSiblingIndex()
The \a sibling must have the same Z value as this item, otherwise calling
this function will have no effect.
- By default, all items are stacked by insertion order (i.e., the first item
- you add is drawn before the next item you add). If two items' Z values are
- different, then the item with the highest Z value is drawn on top. When the
- Z values are the same, the insertion order will decide the stacking order.
+ By default, all sibling items are stacked by insertion order (i.e., the
+ first item you add is drawn before the next item you add). If two items' Z
+ values are different, then the item with the highest Z value is drawn on
+ top. When the Z values are the same, the insertion order will decide the
+ stacking order.
- \sa setZValue(), ItemStacksBehindParent
+ \sa setZValue(), ItemStacksBehindParent, {QGraphicsItem#Sorting}{Sorting}
*/
void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
{
@@ -4446,7 +4593,7 @@ bool QGraphicsItem::collidesWithItem(const QGraphicsItem *other, Qt::ItemSelecti
Note that this function checks whether the item's shape or
bounding rectangle (depending on \a mode) is contained within \a
path, and not whether \a path is contained within the items shape
- or bounding rectangle.
+ or bounding rectangle.
\sa collidesWithItem(), contains(), shape()
*/
@@ -6595,7 +6742,7 @@ void QGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
if (d_ptr->isWidget) {
// Qt::Popup closes when you click outside.
QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
- if (w->windowFlags() & Qt::Popup) {
+ if ((w->windowFlags() & Qt::Popup) == Qt::Popup) {
event->accept();
if (!w->rect().contains(event->pos()))
w->close();
@@ -7020,7 +7167,7 @@ void QGraphicsItem::prepareGeometryChange()
// if someone is connected to the changed signal or the scene has no views.
// Note that this has to be done *after* markDirty to ensure that
// _q_processDirtyItems is called before _q_emitUpdated.
- if (scenePrivate->isSignalConnected(scenePrivate->changedSignalIndex)
+ if (scenePrivate->isSignalConnected(scenePrivate->changedSignalIndex)
|| scenePrivate->views.isEmpty()) {
if (d_ptr->hasTranslateOnlySceneTransform()) {
d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(),
@@ -7141,6 +7288,19 @@ QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent
}
/*!
+ Subscribes the graphics object to the given \a gesture for the specified \a context.
+
+ \sa QGestureEvent
+*/
+
+void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureContext context)
+{
+ QGraphicsItemPrivate * const d = QGraphicsItem::d_func();
+ d->gestureContext.insert(gesture, context);
+ (void)QGestureManager::instance(); // create a gesture manager
+}
+
+/*!
\property QGraphicsObject::parent
\brief the parent of the item
@@ -10524,7 +10684,7 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
effectRect.setRight(deviceWidth - 1);
if (bottom + 1 > deviceHeight)
effectRect.setBottom(deviceHeight -1);
-
+
}
if (effectRect.isEmpty())
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index 99d2e12..2665235 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -146,6 +146,13 @@ public:
DeviceCoordinateCache
};
+ enum PanelModality
+ {
+ NonModal,
+ PanelModal,
+ SceneModal
+ };
+
QGraphicsItem(QGraphicsItem *parent = 0
#ifndef Q_QDOC
// ### obsolete argument
@@ -183,6 +190,10 @@ public:
CacheMode cacheMode() const;
void setCacheMode(CacheMode mode, const QSize &cacheSize = QSize());
+ PanelModality panelModality() const;
+ void setPanelModality(PanelModality panelModality);
+ bool isBlockedByModalPanel(QGraphicsItem **blockingPanel = 0) const;
+
#ifndef QT_NO_TOOLTIP
QString toolTip() const;
void setToolTip(const QString &toolTip);
@@ -453,6 +464,7 @@ private:
friend class QGraphicsSceneBspTree;
friend class QGraphicsView;
friend class QGraphicsViewPrivate;
+ friend class QGraphicsObject;
friend class QGraphicsWidget;
friend class QGraphicsWidgetPrivate;
friend class QGraphicsProxyWidgetPrivate;
@@ -462,6 +474,7 @@ private:
friend class QGraphicsSceneBspTreeIndexPrivate;
friend class QGraphicsItemEffectSourcePrivate;
friend class QGraphicsTransformPrivate;
+ friend class QGestureManager;
friend class ::tst_QGraphicsItem;
friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *);
friend bool qt_closestItemFirst(const QGraphicsItem *, const QGraphicsItem *);
@@ -542,6 +555,8 @@ public:
using QObject::children;
#endif
+ void grabGesture(Qt::GestureType type, Qt::GestureContext context = Qt::WidgetWithChildrenGesture);
+
Q_SIGNALS:
void parentChanged();
void opacityChanged();
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 3feccdc..6550362 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -131,6 +131,7 @@ public:
subFocusItem(0),
focusScopeItem(0),
imHints(Qt::ImhNone),
+ panelModality(QGraphicsItem::NonModal),
acceptedMouseButtons(0x1f),
visible(1),
explicitlyHidden(0),
@@ -448,6 +449,8 @@ public:
QGraphicsItem *subFocusItem;
QGraphicsItem *focusScopeItem;
Qt::InputMethodHints imHints;
+ QGraphicsItem::PanelModality panelModality;
+ QMap<Qt::GestureType, Qt::GestureContext> gestureContext;
// Packed 32 bits
quint32 acceptedMouseButtons : 5;
diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp
index 15b9ff3..b7a3962 100644
--- a/src/gui/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp
@@ -973,7 +973,7 @@ void QGraphicsProxyWidget::hideEvent(QHideEvent *event)
void QGraphicsProxyWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
Q_D(QGraphicsProxyWidget);
- if (!event || !d->widget || !d->widget->isVisible())
+ if (!event || !d->widget || !d->widget->isVisible() || !hasFocus())
return;
// Find widget position and receiver.
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 4b74b67..0773559 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -254,6 +254,8 @@
QT_BEGIN_NAMESPACE
+bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
+
static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent)
{
hover->setWidget(mouseEvent->widget());
@@ -418,8 +420,12 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item)
*/
void QGraphicsScenePrivate::_q_polishItems()
{
+ QSet<QGraphicsItem *>::Iterator it;
const QVariant booleanTrueVariant(true);
- foreach (QGraphicsItem *item, unpolishedItems) {
+ while (!unpolishedItems.isEmpty()) {
+ it = unpolishedItems.begin();
+ QGraphicsItem *item = *it;
+ unpolishedItems.erase(it);
if (!item->d_ptr->explicitlyHidden) {
item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant);
item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant);
@@ -429,7 +435,6 @@ void QGraphicsScenePrivate::_q_polishItems()
QApplication::sendEvent((QGraphicsWidget *)item, &event);
}
}
- unpolishedItems.clear();
}
void QGraphicsScenePrivate::_q_processDirtyItems()
@@ -547,7 +552,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
selectedItems.remove(item);
hoverItems.removeAll(item);
cachedItemsUnderMouse.removeAll(item);
- unpolishedItems.removeAll(item);
+ unpolishedItems.remove(item);
resetDirtyItem(item);
//We remove all references of item from the sceneEventFilter arrays
@@ -565,6 +570,9 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
q->removeItem(item->d_ptr->children.at(i));
}
+ if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal)
+ leaveModal(item);
+
// Reset the mouse grabber and focus item data.
if (mouseGrabberItems.contains(item))
ungrabMouse(item, /* item is dying */ item->d_ptr->inDestructor);
@@ -1048,7 +1056,15 @@ bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event)
return false;
if (filterDescendantEvent(item, event))
return false;
- return (item && item->isEnabled() ? item->sceneEvent(event) : false);
+ if (!item || !item->isEnabled())
+ return false;
+ if (QGraphicsObject *o = item->toGraphicsObject()) {
+ bool spont = event->spontaneous();
+ if (spont ? qt_sendSpontaneousEvent(o, event) : QApplication::sendEvent(o, event))
+ return true;
+ event->spont = spont;
+ }
+ return item->sceneEvent(event);
}
/*!
@@ -1111,6 +1127,9 @@ void QGraphicsScenePrivate::sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent)
}
QGraphicsItem *item = mouseGrabberItems.last();
+ if (item->isBlockedByModalPanel())
+ return;
+
for (int i = 0x1; i <= 0x10; i <<= 1) {
Qt::MouseButton button = Qt::MouseButton(i);
mouseEvent->setButtonDownPos(button, mouseGrabberButtonDownPos.value(button, item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget())));
@@ -1134,6 +1153,8 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou
// Deliver to any existing mouse grabber.
if (!mouseGrabberItems.isEmpty()) {
+ if (mouseGrabberItems.last()->isBlockedByModalPanel())
+ return;
// The event is ignored by default, but we disregard the event's
// accepted state after delivery; the mouse is grabbed, after all.
sendMouseEvent(mouseEvent);
@@ -1151,12 +1172,22 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou
// Update window activation.
QGraphicsItem *topItem = cachedItemsUnderMouse.value(0);
QGraphicsWidget *newActiveWindow = topItem ? topItem->window() : 0;
+ if (newActiveWindow && newActiveWindow->isBlockedByModalPanel(&topItem)) {
+ // pass activation to the blocking modal window
+ newActiveWindow = topItem ? topItem->window() : 0;
+ }
+
if (newActiveWindow != q->activeWindow())
q->setActiveWindow(newActiveWindow);
// Set focus on the topmost enabled item that can take focus.
bool setFocus = false;
foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
+ if (item->isBlockedByModalPanel()) {
+ // Make sure we don't clear focus.
+ setFocus = true;
+ break;
+ }
if (item->isEnabled() && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
setFocus = true;
@@ -1165,12 +1196,27 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou
break;
}
}
+ if (item->isPanel())
+ break;
+ }
+
+ // Check for scene modality.
+ bool sceneModality = false;
+ for (int i = 0; i < modalPanels.size(); ++i) {
+ if (modalPanels.at(i)->panelModality() == QGraphicsItem::SceneModal) {
+ sceneModality = true;
+ break;
+ }
}
// If nobody could take focus, clear it.
- if (!stickyFocus && !setFocus)
+ if (!stickyFocus && !setFocus && !sceneModality)
q->setFocusItem(0, Qt::MouseFocusReason);
+ // Any item will do.
+ if (sceneModality && cachedItemsUnderMouse.isEmpty())
+ cachedItemsUnderMouse << modalPanels.first();
+
// Find a mouse grabber by sending mouse press events to all mouse grabber
// candidates one at a time, until the event is accepted. It's accepted by
// default, so the receiver has to explicitly ignore it for it to pass
@@ -1181,6 +1227,10 @@ void QGraphicsScenePrivate::mousePressEventHandler(QGraphicsSceneMouseEvent *mou
continue;
}
+ // Check if this item is blocked by a modal panel and deliver the mouse event to the
+ // blocking panel instead of this item if blocked.
+ (void) item->isBlockedByModalPanel(&item);
+
grabMouse(item, /* implicit = */ true);
mouseEvent->accept();
@@ -1723,9 +1773,9 @@ QRectF QGraphicsScene::itemsBoundingRect() const
}
/*!
- Returns a list of all items on the scene, in no particular order.
+ Returns a list of all items in the scene in descending stacking order.
- \sa addItem(), removeItem()
+ \sa addItem(), removeItem(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsScene::items() const
{
@@ -1735,9 +1785,9 @@ QList<QGraphicsItem *> QGraphicsScene::items() const
/*!
Returns an ordered list of all items on the scene. \a order decides the
- sorting.
+ stacking order.
- \sa addItem(), removeItem()
+ \sa addItem(), removeItem(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsScene::items(Qt::SortOrder order) const
{
@@ -1756,7 +1806,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(Qt::SortOrder order) const
contains items that ignore transformations. Use the overload that takes
a QTransform instead.
- \sa itemAt()
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos) const
{
@@ -1778,7 +1828,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos) const
contains items that ignore transformations. Use the overload that takes
a QTransform instead.
- \sa itemAt()
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rectangle, Qt::ItemSelectionMode mode) const
{
@@ -1799,20 +1849,20 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rectangle, Qt::ItemSe
*/
/*!
- \fn QList<QGraphicsItem *> QGraphicsScene::items(qreal x, qreal y, qreal w, qreal h,
- Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
\overload
\since 4.6
- Returns all visible items that, depending on \a mode, are either inside or
- intersect with the rectangle defined by \a x, \a y, \a w and \a h, in a list
- sorted using \a order.
+ \brief Returns all visible items that, depending on \a mode, are
+ either inside or intersect with the rectangle defined by \a x, \a y,
+ \a w and \a h, in a list sorted using \a order.
\a deviceTransform is the transformation that applies to the view, and needs to
be provided if the scene contains items that ignore transformations.
*/
/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode) const
\overload
\obsolete
@@ -1826,7 +1876,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rectangle, Qt::ItemSe
contains items that ignore transformations. Use the overload that takes
a QTransform instead.
- \sa itemAt()
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode) const
{
@@ -1835,6 +1885,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemS
}
/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const
\overload
\obsolete
@@ -1848,7 +1899,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemS
contains items that ignore transformations. Use the overload that takes
a QTransform instead.
- \sa itemAt()
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const
{
@@ -1857,10 +1908,11 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemS
}
/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
\since 4.6
- Returns all visible items that, depending on \a mode, are at the specified \a pos
- in a list sorted using \a order.
+ \brief Returns all visible items that, depending on \a mode, are at
+ the specified \a pos in a list sorted using \a order.
The default value for \a mode is Qt::IntersectsItemShape; all items whose
exact shape intersects with \a pos are returned.
@@ -1868,7 +1920,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemS
\a deviceTransform is the transformation that applies to the view, and needs to
be provided if the scene contains items that ignore transformations.
- \sa itemAt()
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode,
Qt::SortOrder order, const QTransform &deviceTransform) const
@@ -1878,11 +1930,13 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos, Qt::ItemSelecti
}
/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
\overload
\since 4.6
- Returns all visible items that, depending on \a mode, are either inside or
- intersect with the specified \a rect and return a list sorted using \a order.
+ \brief Returns all visible items that, depending on \a mode, are
+ either inside or intersect with the specified \a rect and return a
+ list sorted using \a order.
The default value for \a mode is Qt::IntersectsItemShape; all items whose
exact shape intersects with or is contained by \a rect are returned.
@@ -1890,7 +1944,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos, Qt::ItemSelecti
\a deviceTransform is the transformation that applies to the view, and needs to
be provided if the scene contains items that ignore transformations.
- \sa itemAt()
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode,
Qt::SortOrder order, const QTransform &deviceTransform) const
@@ -1900,11 +1954,13 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelecti
}
/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
\overload
\since 4.6
- Returns all visible items that, depending on \a mode, are either inside or
- intersect with the specified \a polygon and return a list sorted using \a order.
+ \brief Returns all visible items that, depending on \a mode, are
+ either inside or intersect with the specified \a polygon and return
+ a list sorted using \a order.
The default value for \a mode is Qt::IntersectsItemShape; all items whose
exact shape intersects with or is contained by \a polygon are returned.
@@ -1912,7 +1968,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelecti
\a deviceTransform is the transformation that applies to the view, and needs to
be provided if the scene contains items that ignore transformations.
- \sa itemAt()
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode,
Qt::SortOrder order, const QTransform &deviceTransform) const
@@ -1922,11 +1978,13 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemS
}
/*!
+ \fn QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform) const
\overload
\since 4.6
- Returns all visible items that, depending on \a mode, are either inside or
- intersect with the specified \a path and return a list sorted using \a order.
+ \brief Returns all visible items that, depending on \a mode, are
+ either inside or intersect with the specified \a path and return a
+ list sorted using \a order.
The default value for \a mode is Qt::IntersectsItemShape; all items whose
exact shape intersects with or is contained by \a path are returned.
@@ -1934,7 +1992,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemS
\a deviceTransform is the transformation that applies to the view, and needs to
be provided if the scene contains items that ignore transformations.
- \sa itemAt()
+ \sa itemAt(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode,
Qt::SortOrder order, const QTransform &deviceTransform) const
@@ -1949,10 +2007,11 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemS
detection is determined by \a mode. By default, all items whose shape
intersects \a item or is contained inside \a item's shape are returned.
- The items are returned in descending Z order (i.e., the first item in the
- list is the top-most item, and the last item is the bottom-most item).
+ The items are returned in descending stacking order (i.e., the first item
+ in the list is the uppermost item, and the last item is the lowermost
+ item).
- \sa items(), itemAt(), QGraphicsItem::collidesWithItem()
+ \sa items(), itemAt(), QGraphicsItem::collidesWithItem(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsScene::collidingItems(const QGraphicsItem *item,
Qt::ItemSelectionMode mode) const
@@ -1979,13 +2038,11 @@ QList<QGraphicsItem *> QGraphicsScene::collidingItems(const QGraphicsItem *item,
Returns the topmost visible item at the specified \a position, or 0 if
there are no items at this position.
- \note The topmost item is the one with the highest Z-value.
-
This function is deprecated and returns incorrect results if the scene
contains items that ignore transformations. Use the overload that takes
a QTransform instead.
- \sa items(), collidingItems(), QGraphicsItem::setZValue()
+ \sa items(), collidingItems(), {QGraphicsItem#Sorting}{Sorting}
*/
QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position) const
{
@@ -2002,10 +2059,8 @@ QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position) const
\a deviceTransform is the transformation that applies to the view, and needs to
be provided if the scene contains items that ignore transformations.
- \note The topmost item is the one with the highest Z-value.
-
- \sa items(), collidingItems(), QGraphicsItem::setZValue()
- */
+ \sa items(), collidingItems(), {QGraphicsItem#Sorting}{Sorting}
+*/
QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform &deviceTransform) const
{
QList<QGraphicsItem *> itemsAtPoint = items(position, Qt::IntersectsItemShape,
@@ -2026,8 +2081,6 @@ QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform
This convenience function is equivalent to calling \c
{itemAt(QPointF(x, y), deviceTransform)}.
-
- \note The topmost item is the one with the highest Z-value.
*/
/*!
@@ -2044,8 +2097,6 @@ QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform
This function is deprecated and returns incorrect results if the scene
contains items that ignore transformations. Use the overload that takes
a QTransform instead.
-
- \note The topmost item is the one with the highest Z-value.
*/
/*!
@@ -2324,7 +2375,7 @@ void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group)
in the scene, then the item will be activated.
\sa removeItem(), addEllipse(), addLine(), addPath(), addPixmap(),
- addRect(), addText(), addWidget()
+ addRect(), addText(), addWidget(), {QGraphicsItem#Sorting}{Sorting}
*/
void QGraphicsScene::addItem(QGraphicsItem *item)
{
@@ -2403,6 +2454,8 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
d->selectedItems << item;
if (item->isWidget() && item->isVisible() && static_cast<QGraphicsWidget *>(item)->windowType() == Qt::Popup)
d->addPopup(static_cast<QGraphicsWidget *>(item));
+ if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal)
+ d->enterModal(item);
// Update creation order focus chain. Make sure to leave the widget's
// internal tab order intact.
@@ -2434,7 +2487,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
if (!item->d_ptr->explicitlyHidden) {
if (d->unpolishedItems.isEmpty())
QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection);
- d->unpolishedItems << item;
+ d->unpolishedItems.insert(item);
}
// Reenable selectionChanged() for individual items
@@ -3205,8 +3258,12 @@ bool QGraphicsScene::event(QEvent *event)
}
return false;
case QEvent::GraphicsSceneMouseMove:
- mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
+ {
+ QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
+ d->lastSceneMousePos = mouseEvent->scenePos();
+ mouseMoveEvent(mouseEvent);
break;
+ }
case QEvent::GraphicsSceneMousePress:
mousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
break;
@@ -3228,8 +3285,12 @@ bool QGraphicsScene::event(QEvent *event)
case QEvent::GraphicsSceneHoverEnter:
case QEvent::GraphicsSceneHoverLeave:
case QEvent::GraphicsSceneHoverMove:
- d->dispatchHoverEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
+ {
+ QGraphicsSceneHoverEvent *hoverEvent = static_cast<QGraphicsSceneHoverEvent *>(event);
+ d->lastSceneMousePos = hoverEvent->scenePos();
+ d->dispatchHoverEvent(hoverEvent);
break;
+ }
case QEvent::Leave:
d->leaveScene();
break;
@@ -3599,8 +3660,10 @@ void QGraphicsScene::helpEvent(QGraphicsSceneHelpEvent *helpEvent)
bool QGraphicsScenePrivate::itemAcceptsHoverEvents_helper(const QGraphicsItem *item) const
{
- return item->acceptHoverEvents()
- || (item->isWidget() && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration());
+ return (!item->isBlockedByModalPanel() &&
+ (item->acceptHoverEvents()
+ || (item->isWidget()
+ && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration())));
}
/*!
@@ -3674,7 +3737,9 @@ bool QGraphicsScenePrivate::dispatchHoverEvent(QGraphicsSceneHoverEvent *hoverEv
}
// Generate a move event for the item itself
- if (item && !hoverItems.isEmpty() && item == hoverItems.last()) {
+ if (item
+ && !hoverItems.isEmpty()
+ && item == hoverItems.last()) {
sendHoverEvent(QEvent::GraphicsSceneHoverMove, item, hoverEvent);
return true;
}
@@ -3708,8 +3773,7 @@ void QGraphicsScenePrivate::leaveScene()
while (!hoverItems.isEmpty()) {
QGraphicsItem *lastItem = hoverItems.takeLast();
- if (lastItem->acceptHoverEvents()
- || (lastItem->isWidget() && static_cast<QGraphicsWidget*>(lastItem)->d_func()->hasDecoration()))
+ if (itemAcceptsHoverEvents_helper(lastItem))
sendHoverEvent(QEvent::GraphicsSceneHoverLeave, lastItem, &hoverEvent);
}
}
@@ -3736,6 +3800,8 @@ void QGraphicsScene::keyPressEvent(QKeyEvent *keyEvent)
keyEvent->accept();
// Send it; QGraphicsItem::keyPressEvent ignores it. If the event
// is filtered out, stop propagating it.
+ if (p->isBlockedByModalPanel())
+ break;
if (!d->sendEvent(p, keyEvent))
break;
} while (!keyEvent->isAccepted() && !p->isPanel() && (p = p->parentItem()));
@@ -3766,6 +3832,8 @@ void QGraphicsScene::keyReleaseEvent(QKeyEvent *keyEvent)
keyEvent->accept();
// Send it; QGraphicsItem::keyPressEvent ignores it. If the event
// is filtered out, stop propagating it.
+ if (p->isBlockedByModalPanel())
+ break;
if (!d->sendEvent(p, keyEvent))
break;
} while (!keyEvent->isAccepted() && !p->isPanel() && (p = p->parentItem()));
@@ -5410,16 +5478,18 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent)
}
if (itemsNeedingEvents.isEmpty()) {
- sceneTouchEvent->ignore();
+ sceneTouchEvent->accept();
return;
}
- bool acceptSceneTouchEvent = false;
+ bool ignoreSceneTouchEvent = true;
QHash<QGraphicsItem *, StatesAndTouchPoints>::ConstIterator it = itemsNeedingEvents.constBegin();
const QHash<QGraphicsItem *, StatesAndTouchPoints>::ConstIterator end = itemsNeedingEvents.constEnd();
for (; it != end; ++it) {
QGraphicsItem *item = it.key();
+ (void) item->isBlockedByModalPanel(&item);
+
// determine event type from the state mask
QEvent::Type eventType;
switch (it.value().first) {
@@ -5455,19 +5525,20 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent)
item->d_ptr->acceptedTouchBeginEvent = true;
bool res = sendTouchBeginEvent(item, &touchEvent)
&& touchEvent.isAccepted();
- acceptSceneTouchEvent = acceptSceneTouchEvent || res;
+ if (!res)
+ ignoreSceneTouchEvent = false;
break;
}
default:
if (item->d_ptr->acceptedTouchBeginEvent) {
updateTouchPointsForItem(item, &touchEvent);
(void) sendEvent(item, &touchEvent);
- acceptSceneTouchEvent = true;
+ ignoreSceneTouchEvent = false;
}
break;
}
}
- sceneTouchEvent->setAccepted(acceptSceneTouchEvent);
+ sceneTouchEvent->setAccepted(ignoreSceneTouchEvent);
}
bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEvent *touchEvent)
@@ -5493,6 +5564,8 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve
break;
}
}
+ if (item->isPanel())
+ break;
}
// If nobody could take focus, clear it.
@@ -5518,6 +5591,8 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve
}
break;
}
+ if (item->isPanel())
+ break;
}
touchEvent->setAccepted(eventAccepted);
@@ -5536,6 +5611,94 @@ void QGraphicsScenePrivate::updateInputMethodSensitivityInViews()
views.at(i)->d_func()->updateInputMethodSensitivity();
}
+void QGraphicsScenePrivate::enterModal(QGraphicsItem *panel, QGraphicsItem::PanelModality previousModality)
+{
+ Q_Q(QGraphicsScene);
+ Q_ASSERT(panel && panel->isPanel());
+
+ QGraphicsItem::PanelModality panelModality = panel->d_ptr->panelModality;
+ if (previousModality != QGraphicsItem::NonModal) {
+ // the panel is changing from one modality type to another... temporarily set it back so
+ // that blockedPanels is populated correctly
+ panel->d_ptr->panelModality = previousModality;
+ }
+
+ QSet<QGraphicsItem *> blockedPanels;
+ QList<QGraphicsItem *> items = q->items(); // ### store panels separately
+ for (int i = 0; i < items.count(); ++i) {
+ QGraphicsItem *item = items.at(i);
+ if (item->isPanel() && item->isBlockedByModalPanel())
+ blockedPanels.insert(item);
+ }
+ // blockedPanels contains all currently blocked panels
+
+ if (previousModality != QGraphicsItem::NonModal) {
+ // reset the modality to the proper value, since we changed it above
+ panel->d_ptr->panelModality = panelModality;
+ // remove this panel so that it will be reinserted at the front of the stack
+ modalPanels.removeAll(panel);
+ }
+
+ modalPanels.prepend(panel);
+
+ if (!hoverItems.isEmpty()) {
+ // send GraphicsSceneHoverLeave events to newly blocked hoverItems
+ QGraphicsSceneHoverEvent hoverEvent;
+ hoverEvent.setScenePos(lastSceneMousePos);
+ dispatchHoverEvent(&hoverEvent);
+ }
+
+ if (!mouseGrabberItems.isEmpty() && lastMouseGrabberItemHasImplicitMouseGrab) {
+ QGraphicsItem *item = mouseGrabberItems.last();
+ if (item->isBlockedByModalPanel())
+ ungrabMouse(item, /*itemIsDying =*/ false);
+ }
+
+ QEvent windowBlockedEvent(QEvent::WindowBlocked);
+ QEvent windowUnblockedEvent(QEvent::WindowUnblocked);
+ for (int i = 0; i < items.count(); ++i) {
+ QGraphicsItem *item = items.at(i);
+ if (item->isPanel()) {
+ if (!blockedPanels.contains(item) && item->isBlockedByModalPanel()) {
+ // send QEvent::WindowBlocked to newly blocked panels
+ sendEvent(item, &windowBlockedEvent);
+ } else if (blockedPanels.contains(item) && !item->isBlockedByModalPanel()) {
+ // send QEvent::WindowUnblocked to unblocked panels when downgrading
+ // a panel from SceneModal to PanelModal
+ sendEvent(item, &windowUnblockedEvent);
+ }
+ }
+ }
+}
+
+void QGraphicsScenePrivate::leaveModal(QGraphicsItem *panel)
+{
+ Q_Q(QGraphicsScene);
+ Q_ASSERT(panel && panel->isPanel());
+
+ QSet<QGraphicsItem *> blockedPanels;
+ QList<QGraphicsItem *> items = q->items(); // ### same as above
+ for (int i = 0; i < items.count(); ++i) {
+ QGraphicsItem *item = items.at(i);
+ if (item->isPanel() && item->isBlockedByModalPanel())
+ blockedPanels.insert(item);
+ }
+
+ modalPanels.removeAll(panel);
+
+ QEvent e(QEvent::WindowUnblocked);
+ for (int i = 0; i < items.count(); ++i) {
+ QGraphicsItem *item = items.at(i);
+ if (item->isPanel() && blockedPanels.contains(item) && !item->isBlockedByModalPanel())
+ sendEvent(item, &e);
+ }
+
+ // send GraphicsSceneHoverEnter events to newly unblocked items
+ QGraphicsSceneHoverEvent hoverEvent;
+ hoverEvent.setScenePos(lastSceneMousePos);
+ dispatchHoverEvent(&hoverEvent);
+}
+
QT_END_NAMESPACE
#include "moc_qgraphicsscene.cpp"
diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h
index ba47530..d6d48d7 100644
--- a/src/gui/graphicsview/qgraphicsscene.h
+++ b/src/gui/graphicsview/qgraphicsscene.h
@@ -311,6 +311,7 @@ private:
friend class QGraphicsSceneBspTreeIndex;
friend class QGraphicsSceneBspTreeIndexPrivate;
friend class QGraphicsItemEffectSourcePrivate;
+ friend class QGesture;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsScene::SceneLayers)
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 46917ce..8073695 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -108,7 +108,7 @@ public:
QPainterPath selectionArea;
int selectionChanging;
QSet<QGraphicsItem *> selectedItems;
- QList<QGraphicsItem *> unpolishedItems;
+ QSet<QGraphicsItem *> unpolishedItems;
QList<QGraphicsItem *> topLevelItems;
bool needSortTopLevelItems;
bool holesInTopLevelSiblingIndex;
@@ -160,6 +160,7 @@ public:
Qt::DropAction lastDropAction;
QList<QGraphicsItem *> cachedItemsUnderMouse;
QList<QGraphicsItem *> hoverItems;
+ QPointF lastSceneMousePos;
bool allItemsIgnoreHoverEvents;
bool allItemsUseDefaultCursor;
void enableMouseTrackingOnViews();
@@ -282,6 +283,11 @@ public:
void enableTouchEventsOnViews();
void updateInputMethodSensitivityInViews();
+
+ QList<QGraphicsItem *> modalPanels;
+ void enterModal(QGraphicsItem *item,
+ QGraphicsItem::PanelModality panelModality = QGraphicsItem::NonModal);
+ void leaveModal(QGraphicsItem *item);
};
// QRectF::intersects() returns false always if either the source or target
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 98b2c9c..32747cc 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -2016,9 +2016,11 @@ void QGraphicsView::render(QPainter *painter, const QRectF &target, const QRect
}
/*!
- Returns a list of all the items in the associated scene.
+ Returns a list of all the items in the associated scene, in descending
+ stacking order (i.e., the first item in the returned list is the uppermost
+ item).
- \sa QGraphicsScene::items()
+ \sa QGraphicsScene::items(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsView::items() const
{
@@ -2030,9 +2032,9 @@ QList<QGraphicsItem *> QGraphicsView::items() const
/*!
Returns a list of all the items at the position \a pos in the view. The
- items are listed in descending Z order (i.e., the first item in the list
- is the top-most item, and the last item is the bottom-most item). \a pos
- is in viewport coordinates.
+ items are listed in descending stacking order (i.e., the first item in the
+ list is the uppermost item, and the last item is the lowermost item). \a
+ pos is in viewport coordinates.
This function is most commonly called from within mouse event handlers in
a subclass in QGraphicsView. \a pos is in untransformed viewport
@@ -2040,7 +2042,7 @@ QList<QGraphicsItem *> QGraphicsView::items() const
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 5
- \sa QGraphicsScene::items(), QGraphicsItem::zValue()
+ \sa QGraphicsScene::items(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsView::items(const QPoint &pos) const
{
@@ -2082,7 +2084,10 @@ QList<QGraphicsItem *> QGraphicsView::items(const QPoint &pos) const
The default value for \a mode is Qt::IntersectsItemShape; all items whose
exact shape intersects with or is contained by \a rect are returned.
- \sa itemAt(), items(), mapToScene()
+ The items are sorted in descending stacking order (i.e., the first item in
+ the returned list is the uppermost item).
+
+ \sa itemAt(), items(), mapToScene(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsView::items(const QRect &rect, Qt::ItemSelectionMode mode) const
{
@@ -2110,7 +2115,10 @@ QList<QGraphicsItem *> QGraphicsView::items(const QRect &rect, Qt::ItemSelection
The default value for \a mode is Qt::IntersectsItemShape; all items whose
exact shape intersects with or is contained by \a polygon are returned.
- \sa itemAt(), items(), mapToScene()
+ The items are sorted by descending stacking order (i.e., the first item in
+ the returned list is the uppermost item).
+
+ \sa itemAt(), items(), mapToScene(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsView::items(const QPolygon &polygon, Qt::ItemSelectionMode mode) const
{
@@ -2130,7 +2138,7 @@ QList<QGraphicsItem *> QGraphicsView::items(const QPolygon &polygon, Qt::ItemSel
The default value for \a mode is Qt::IntersectsItemShape; all items whose
exact shape intersects with or is contained by \a path are returned.
- \sa itemAt(), items(), mapToScene()
+ \sa itemAt(), items(), mapToScene(), {QGraphicsItem#Sorting}{Sorting}
*/
QList<QGraphicsItem *> QGraphicsView::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const
{
@@ -2149,7 +2157,7 @@ QList<QGraphicsItem *> QGraphicsView::items(const QPainterPath &path, Qt::ItemSe
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp 6
- \sa items()
+ \sa items(), {QGraphicsItem#Sorting}{Sorting}
*/
QGraphicsItem *QGraphicsView::itemAt(const QPoint &pos) const
{
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index 224f50b..35a3c13 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -168,8 +168,6 @@ QT_BEGIN_NAMESPACE
\sa QGraphicsProxyWidget, QGraphicsItem, {Widgets and Layouts}
*/
-bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
-
/*!
Constructs a QGraphicsWidget instance. The optional \a parent argument is
passed to QGraphicsItem's constructor. The optional \a wFlags argument
@@ -349,7 +347,7 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
// setPos triggers ItemPositionChange, which can adjust position
wd->inSetGeometry = 1;
- wd->setPosHelper(newGeom.topLeft());
+ setPos(newGeom.topLeft());
wd->inSetGeometry = 0;
newGeom.moveTopLeft(pos());
@@ -1103,10 +1101,6 @@ QVariant QGraphicsWidget::propertyChange(const QString &propertyName, const QVar
*/
bool QGraphicsWidget::sceneEvent(QEvent *event)
{
- bool spont = event->spontaneous();
- if (spont ? qt_sendSpontaneousEvent(this, event) : QApplication::sendEvent(this, event))
- return true;
- event->spont = spont;
return QGraphicsItem::sceneEvent(event);
}
diff --git a/src/gui/graphicsview/qsimplex_p.cpp b/src/gui/graphicsview/qsimplex_p.cpp
index 1ece8b1..b8f8fb4 100644
--- a/src/gui/graphicsview/qsimplex_p.cpp
+++ b/src/gui/graphicsview/qsimplex_p.cpp
@@ -75,15 +75,24 @@ QT_BEGIN_NAMESPACE
3.c) Run simplex to optimize the original problem towards its optimal solution.
*/
+/*!
+ \internal
+*/
QSimplex::QSimplex() : objective(0), rows(0), columns(0), firstArtificial(0), matrix(0)
{
}
+/*!
+ \internal
+*/
QSimplex::~QSimplex()
{
clearDataStructures();
}
+/*!
+ \internal
+*/
void QSimplex::clearDataStructures()
{
if (matrix == 0)
@@ -276,24 +285,6 @@ bool QSimplex::setConstraints(const QList<QSimplexConstraint *> newConstraints)
// anymore.
clearColumns(firstArtificial, columns - 2);
- #ifdef QT_DEBUG
- // Ensure that at the end of the simplex each row should either:
- // - Have a positive value on the column associated to its variable, or
- // - Have zero values in all columns.
- //
- // This avoids a regression where restrictions would be lost
- // due to randomness in the pivotRowForColumn method.
- for (int i = 1; i < rows; ++i) {
- int variableIndex = valueAt(i, 0);
- if (valueAt(i, variableIndex) > 0)
- continue;
-
- for (int j = 1; j < columns; ++j) {
- Q_ASSERT(valueAt(i, j) == 0);
- }
- }
- #endif
-
return true;
}
@@ -312,11 +303,17 @@ void QSimplex::solveMaxHelper()
while (iterate()) ;
}
+/*!
+ \internal
+*/
void QSimplex::setObjective(QSimplexConstraint *newObjective)
{
objective = newObjective;
}
+/*!
+ \internal
+*/
void QSimplex::clearRow(int rowIndex)
{
qreal *item = matrix + rowIndex * columns;
@@ -324,6 +321,9 @@ void QSimplex::clearRow(int rowIndex)
item[i] = 0.0;
}
+/*!
+ \internal
+*/
void QSimplex::clearColumns(int first, int last)
{
for (int i = 0; i < rows; ++i) {
@@ -333,6 +333,9 @@ void QSimplex::clearColumns(int first, int last)
}
}
+/*!
+ \internal
+*/
void QSimplex::dumpMatrix()
{
qDebug("---- Simplex Matrix ----\n");
@@ -352,6 +355,9 @@ void QSimplex::dumpMatrix()
qDebug("------------------------\n");
}
+/*!
+ \internal
+*/
void QSimplex::combineRows(int toIndex, int fromIndex, qreal factor)
{
if (!factor)
@@ -375,6 +381,9 @@ void QSimplex::combineRows(int toIndex, int fromIndex, qreal factor)
}
}
+/*!
+ \internal
+*/
int QSimplex::findPivotColumn()
{
qreal min = 0;
@@ -429,6 +438,9 @@ int QSimplex::pivotRowForColumn(int column)
return minIndex;
}
+/*!
+ \internal
+*/
void QSimplex::reducedRowEchelon()
{
for (int i = 1; i < rows; ++i) {
@@ -507,6 +519,12 @@ qreal QSimplex::solver(solverFactor factor)
solveMaxHelper();
collectResults();
+#ifdef QT_DEBUG
+ for (int i = 0; i < constraints.size(); ++i) {
+ Q_ASSERT(constraints[i]->isSatisfied());
+ }
+#endif
+
return factor * valueAt(0, columns - 1);
}
diff --git a/src/gui/graphicsview/qsimplex_p.h b/src/gui/graphicsview/qsimplex_p.h
index 54b080d..51991a9 100644
--- a/src/gui/graphicsview/qsimplex_p.h
+++ b/src/gui/graphicsview/qsimplex_p.h
@@ -94,8 +94,32 @@ struct QSimplexConstraint
QPair<QSimplexVariable *, qreal> helper;
QSimplexVariable * artificial;
-};
+#ifdef QT_DEBUG
+ bool isSatisfied() {
+ qreal leftHandSide(0);
+
+ QHash<QSimplexVariable *, qreal>::const_iterator iter;
+ for (iter = variables.constBegin(); iter != variables.constEnd(); ++iter) {
+ leftHandSide += iter.value() * iter.key()->result;
+ }
+
+ Q_ASSERT(constant > 0 || qFuzzyCompare(1, 1 + constant));
+
+ if (qFuzzyCompare(1000 + leftHandSide, 1000 + constant))
+ return true;
+
+ switch (ratio) {
+ case LessOrEqual:
+ return leftHandSide < constant;
+ case MoreOrEqual:
+ return leftHandSide > constant;
+ default:
+ return false;
+ }
+ }
+#endif
+};
class QSimplex
{
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index fce4508..e0779a0 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -54,6 +54,7 @@
#include "qvariant.h"
#include "qcache.h"
#include "qdebug.h"
+#include "private/qguiplatformplugin_p.h"
#ifdef Q_WS_MAC
#include <private/qt_mac_p.h>
@@ -961,19 +962,10 @@ QString QIcon::themeName()
*/
QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)
{
-
static QCache <QString, QIcon> iconCache;
QIcon icon;
-#ifdef Q_WS_X11
- if (X11->desktopEnvironment == DE_KDE) {
- icon = QKde::kdeIcon(name);
- if (!icon.isNull())
- return icon;
- }
-#endif
-
if (iconCache.contains(name)) {
icon = *iconCache.object(name);
} else {
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index adc2967..5412e11 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -43,7 +43,7 @@
#include <private/qapplication_p.h>
#include <private/qicon_p.h>
-#include <private/qkde_p.h>
+#include <private/qguiplatformplugin_p.h>
#include <QtGui/QIconEnginePlugin>
#include <QtGui/QPixmapCache>
@@ -68,47 +68,25 @@ QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance)
+/* Theme to use in last resort, if the theme does not have the icon, neither the parents */
static QString fallbackTheme()
{
- QString defaultTheme;
-#ifdef Q_WS_X11
- if (X11->desktopEnvironment == DE_GNOME)
- defaultTheme = QLatin1String("gnome");
- else if (X11->desktopEnvironment == DE_KDE)
- defaultTheme = X11->desktopVersion >= 4 ?
- QString::fromLatin1("oxygen") :
- QString::fromLatin1("crystalsvg");
-#endif
- return defaultTheme;
-}
-
-static QString systemThemeName()
-{
- QString result = fallbackTheme();
#ifdef Q_WS_X11
if (X11->desktopEnvironment == DE_GNOME) {
-#ifndef QT_NO_STYLE_GTK
- result = QGtk::getGConfString(QLatin1String("/desktop/gnome/interface/icon_theme"),
- result);
-#endif
+ return QLatin1String("gnome");
} else if (X11->desktopEnvironment == DE_KDE) {
- QSettings settings(QKde::kdeHome() +
- QLatin1String("/share/config/kdeglobals"),
- QSettings::IniFormat);
-
- settings.beginGroup(QLatin1String("Icons"));
-
- result = settings.value(QLatin1String("Theme"), result).toString();
+ return X11->desktopVersion >= 4
+ ? QString::fromLatin1("oxygen")
+ : QString::fromLatin1("crystalsvg");
}
#endif
- return result;
+ return QString();
}
-
QIconLoader::QIconLoader() :
m_themeKey(1), m_supportsSvg(false)
{
- m_systemTheme = systemThemeName();
+ m_systemTheme = qt_guiPlatformPlugin()->systemIconThemeName();
QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterfaceV2_iid,
QLatin1String("/iconengines"),
@@ -128,7 +106,7 @@ void QIconLoader::updateSystemTheme()
{
// Only change if this is not explicitly set by the user
if (m_userTheme.isEmpty()) {
- QString theme = systemThemeName();
+ QString theme = qt_guiPlatformPlugin()->systemIconThemeName();
if (theme != m_systemTheme) {
m_systemTheme = theme;
invalidateKey();
@@ -152,51 +130,7 @@ void QIconLoader::setThemeSearchPath(const QStringList &searchPaths)
QStringList QIconLoader::themeSearchPaths() const
{
if (m_iconDirs.isEmpty()) {
-
-#if defined(Q_WS_X11)
-
- QString xdgDirString = QFile::decodeName(getenv("XDG_DATA_DIRS"));
- if (xdgDirString.isEmpty())
- xdgDirString = QLatin1String("/usr/local/share/:/usr/share/");
-
- QStringList xdgDirs = xdgDirString.split(QLatin1Char(':'));
-
- for (int i = 0 ; i < xdgDirs.size() ; ++i) {
- QDir dir(xdgDirs[i]);
- if (dir.exists())
- m_iconDirs.append(dir.path() +
- QLatin1String("/icons"));
- }
-
- if (X11->desktopEnvironment == DE_KDE) {
-
- m_iconDirs << QLatin1Char(':') +
- QKde::kdeHome() +
- QLatin1String("/share/icons");
- QStringList kdeDirs =
- QFile::decodeName(getenv("KDEDIRS")).split(QLatin1Char(':'));
-
- for (int i = 0 ; i< kdeDirs.count() ; ++i) {
- QDir dir(QLatin1Char(':') + kdeDirs.at(i) +
- QLatin1String("/share/icons"));
- if (dir.exists())
- m_iconDirs.append(dir.path());
- }
- }
-
- // Add home directory first in search path
- QDir homeDir(QDir::homePath() + QLatin1String("/.icons"));
- if (homeDir.exists())
- m_iconDirs.prepend(homeDir.path());
-#endif
-
-#if defined(Q_WS_WIN)
- m_iconDirs.append(qApp->applicationDirPath() +
- QLatin1String("/icons"));
-#elif defined(Q_WS_MAC)
- m_iconDirs.append(qApp->applicationDirPath() +
- QLatin1String("/../Resources/icons"));
-#endif
+ m_iconDirs = qt_guiPlatformPlugin()->iconThemeSearchPaths();
// Allways add resource directory as search path
m_iconDirs.append(QLatin1String(":/icons"));
}
@@ -291,7 +225,7 @@ QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName,
if (!theme.isValid()) {
theme = QIconTheme(themeName);
if (!theme.isValid())
- theme = fallbackTheme();
+ theme = QIconTheme(fallbackTheme());
themeList.insert(themeName, theme);
}
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 4f44109..bea1e8d 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -63,7 +63,7 @@
QT_BEGIN_NAMESPACE
-struct QImageData { // internal image data
+struct Q_GUI_EXPORT QImageData { // internal image data
QImageData();
~QImageData();
static QImageData *create(const QSize &size, QImage::Format format, int numColors = 0);
diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp
index dccc691..9ae8d72 100644
--- a/src/gui/image/qpixmap_s60.cpp
+++ b/src/gui/image/qpixmap_s60.cpp
@@ -64,7 +64,7 @@ const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80 };
-/*!
+/*
\class QSymbianFbsClient
\since 4.6
\internal
@@ -145,7 +145,7 @@ void QSymbianFbsHeapLock::relock()
qt_symbianFbsClient()->lockHeap();
}
-/*!
+/*
\class QSymbianBitmapDataAccess
\since 4.6
\internal
@@ -229,24 +229,15 @@ static CFbsBitmap* uncompress(CFbsBitmap* bitmap)
lock.relock();
- CBitmapContext *bitmapContext = 0;
CFbsBitmapDevice* bitmapDevice = 0;
+ CFbsBitGc *bitmapGc = 0;
QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(uncompressed));
- TInt err = bitmapDevice->CreateBitmapContext(bitmapContext);
- if (err != KErrNone) {
- delete bitmap;
- delete bitmapDevice;
- bitmap = 0;
- bitmapDevice = 0;
+ QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
+ bitmapGc->Activate(bitmapDevice);
- lock.relock();
-
- return bitmap;
- }
+ bitmapGc->DrawBitmap(TPoint(), bitmap);
- bitmapContext->DrawBitmap(TPoint(), bitmap);
-
- delete bitmapContext;
+ delete bitmapGc;
delete bitmapDevice;
return uncompressed;
@@ -355,7 +346,7 @@ QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type),
symbianBitmapDataAccess(new QSymbianBitmapDataAccess),
cfbsBitmap(0),
bitmapDevice(0),
- bitmapContext(0),
+ bitmapGc(0),
pengine(0),
bytes(0)
{
@@ -365,6 +356,7 @@ QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type),
QS60PixmapData::~QS60PixmapData()
{
release();
+ delete symbianBitmapDataAccess;
}
void QS60PixmapData::resize(int width, int height)
@@ -391,6 +383,8 @@ void QS60PixmapData::resize(int width, int height)
if(cfbsBitmap->SizeInPixels() != newSize) {
cfbsBitmap->Resize(TSize(width, height));
+ bitmapDevice->Resize(TSize(width, height));
+ bitmapGc->Resized();
if(pengine) {
delete pengine;
pengine = 0;
@@ -404,12 +398,9 @@ void QS60PixmapData::resize(int width, int height)
bool QS60PixmapData::initSymbianBitmapContext()
{
QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(cfbsBitmap));
- TInt err = bitmapDevice->CreateBitmapContext(bitmapContext);
- if (err != KErrNone) {
- delete bitmapDevice;
- bitmapDevice = 0;
- return false;
- }
+ QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
+ bitmapGc->Activate(bitmapDevice);
+
return true;
}
@@ -417,7 +408,7 @@ void QS60PixmapData::release()
{
if (cfbsBitmap) {
QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
- delete bitmapContext;
+ delete bitmapGc;
delete bitmapDevice;
delete cfbsBitmap;
lock.relock();
@@ -426,7 +417,7 @@ void QS60PixmapData::release()
delete pengine;
image = QImage();
cfbsBitmap = 0;
- bitmapContext = 0;
+ bitmapGc = 0;
bitmapDevice = 0;
pengine = 0;
bytes = 0;
@@ -476,9 +467,9 @@ void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags
sourceImage = img.convertToFormat(QImage::Format_MonoLSB);
} else {
if (img.depth() == 1) {
- image = img.hasAlphaChannel()
- ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied)
- : img.convertToFormat(QImage::Format_RGB32);
+ sourceImage = img.hasAlphaChannel()
+ ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied)
+ : img.convertToFormat(QImage::Format_RGB32);
} else {
QImage::Format opaqueFormat = QNativeImage::systemFormat();
@@ -559,13 +550,15 @@ void QS60PixmapData::copy(const QPixmapData *data, const QRect &rect)
resize(rect.width(), rect.height());
cfbsBitmap->SetDisplayMode(s60Data->cfbsBitmap->DisplayMode());
- bitmapContext->BitBlt(TPoint(0, 0), s60Data->cfbsBitmap, qt_QRect2TRect(rect));
+ bitmapGc->BitBlt(TPoint(0, 0), s60Data->cfbsBitmap, qt_QRect2TRect(rect));
}
bool QS60PixmapData::scroll(int dx, int dy, const QRect &rect)
{
- bitmapContext->CopyRect(TPoint(dx, dy), qt_QRect2TRect(rect));
- return true;
+ beginDataAccess();
+ bool res = QRasterPixmapData::scroll(dx, dy, rect);
+ endDataAccess();
+ return res;
}
int QS60PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
@@ -664,7 +657,12 @@ void QS60PixmapData::setAlphaChannel(const QPixmap &alphaChannel)
QImage QS60PixmapData::toImage() const
{
- return image;
+ QS60PixmapData *that = const_cast<QS60PixmapData*>(this);
+ that->beginDataAccess();
+ QImage copy = that->image.copy();
+ that->endDataAccess();
+
+ return copy;
}
QPaintEngine* QS60PixmapData::paintEngine() const
@@ -718,6 +716,8 @@ void QS60PixmapData::beginDataAccess()
void QS60PixmapData::endDataAccess(bool readOnly) const
{
+ Q_UNUSED(readOnly);
+
if(!cfbsBitmap)
return;
diff --git a/src/gui/image/qpixmap_s60_p.h b/src/gui/image/qpixmap_s60_p.h
index 4498c05..b23961a 100644
--- a/src/gui/image/qpixmap_s60_p.h
+++ b/src/gui/image/qpixmap_s60_p.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
class CFbsBitmap;
class CFbsBitmapDevice;
-class CBitmapContext;
+class CFbsBitGc;
class QSymbianBitmapDataAccess;
@@ -114,7 +114,7 @@ private:
CFbsBitmap *cfbsBitmap;
CFbsBitmapDevice *bitmapDevice;
- CBitmapContext *bitmapContext;
+ CFbsBitGc *bitmapGc;
QPaintEngine *pengine;
uchar* bytes;
diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp
index f77d200..74543a0 100644
--- a/src/gui/image/qpixmap_x11.cpp
+++ b/src/gui/image/qpixmap_x11.cpp
@@ -67,6 +67,7 @@
#include <private/qt_x11_p.h>
#include "qx11info_x11.h"
#include <private/qdrawhelper_p.h>
+#include <private/qimage_p.h>
#include <stdlib.h>
@@ -369,6 +370,37 @@ void QX11PixmapData::resize(int width, int height)
#endif // QT_NO_XRENDER
}
+struct QX11AlphaDetector
+{
+ bool hasAlpha() const {
+ if (checked)
+ return has;
+ // Will implicitly also check format and return quickly for opaque types...
+ checked = true;
+ has = const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels();
+ return has;
+ }
+
+ bool hasXRenderAndAlpha() const {
+ if (!X11->use_xrender)
+ return false;
+ return hasAlpha();
+ }
+
+ QX11AlphaDetector(const QImage *i, Qt::ImageConversionFlags flags)
+ : image(i), checked(false), has(false)
+ {
+ if (flags & Qt::NoOpaqueDetection) {
+ checked = true;
+ has = image->hasAlphaChannel();
+ }
+ }
+
+ const QImage *image;
+ mutable bool checked;
+ mutable bool has;
+};
+
void QX11PixmapData::fromImage(const QImage &img,
Qt::ImageConversionFlags flags)
{
@@ -402,7 +434,9 @@ void QX11PixmapData::fromImage(const QImage &img,
return;
}
- int dd = X11->use_xrender && img.hasAlphaChannel() ? 32 : xinfo.depth();
+ QX11AlphaDetector alphaCheck(&img, flags);
+ int dd = alphaCheck.hasXRenderAndAlpha() ? 32 : xinfo.depth();
+
if (qt_x11_preferred_pixmap_depth)
dd = qt_x11_preferred_pixmap_depth;
@@ -454,7 +488,7 @@ void QX11PixmapData::fromImage(const QImage &img,
uchar *newbits= 0;
#ifndef QT_NO_XRENDER
- if (X11->use_xrender && image.hasAlphaChannel()) {
+ if (alphaCheck.hasXRenderAndAlpha()) {
const QImage &cimage = image;
d = 32;
@@ -1091,7 +1125,7 @@ void QX11PixmapData::fromImage(const QImage &img,
}
#endif
- if (image.hasAlphaChannel()) {
+ if (alphaCheck.hasAlpha()) {
QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags));
setMask(m);
}
@@ -1225,8 +1259,11 @@ void QX11PixmapData::release()
QPixmap QX11PixmapData::alphaChannel() const
{
- if (!hasAlphaChannel())
- return QPixmap();
+ if (!hasAlphaChannel()) {
+ QPixmap pm(w, h);
+ pm.fill(Qt::white);
+ return pm;
+ }
QImage im(toImage());
return QPixmap::fromImage(im.alphaChannel(), Qt::OrderedDither);
}
diff --git a/src/gui/image/qpixmap_x11_p.h b/src/gui/image/qpixmap_x11_p.h
index ed8678d..e34e690 100644
--- a/src/gui/image/qpixmap_x11_p.h
+++ b/src/gui/image/qpixmap_x11_p.h
@@ -100,6 +100,8 @@ private:
friend class QX11WindowSurface;
friend class QRasterWindowSurface;
friend class QGLContextPrivate; // Needs to access xinfo, gl_surface & flags
+ friend class QEglContext; // Needs gl_surface
+ friend bool qt_createEGLSurfaceForPixmap(QPixmapData*, bool); // Needs gl_surface
void release();
diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h
index 3e85236..c26fba3 100644
--- a/src/gui/image/qpixmapdata_p.h
+++ b/src/gui/image/qpixmapdata_p.h
@@ -134,6 +134,7 @@ private:
friend class QS60PixmapData;
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 ba9a1e2..df445db 100644
--- a/src/gui/image/qpixmapfilter.cpp
+++ b/src/gui/image/qpixmapfilter.cpp
@@ -504,10 +504,10 @@ void QPixmapConvolutionFilter::draw(QPainter *painter, const QPointF &p, const Q
class QPixmapBlurFilterPrivate : public QPixmapFilterPrivate
{
public:
- QPixmapBlurFilterPrivate() : radius(5), hint(QPixmapBlurFilter::PerformanceHint) {}
+ QPixmapBlurFilterPrivate() : radius(5), hint(Qt::PerformanceHint) {}
int radius;
- QPixmapBlurFilter::BlurHint hint;
+ Qt::RenderHint hint;
};
@@ -561,7 +561,7 @@ int QPixmapBlurFilter::radius() const
\internal
*/
-void QPixmapBlurFilter::setBlurHint(QPixmapBlurFilter::BlurHint hint)
+void QPixmapBlurFilter::setBlurHint(Qt::RenderHint hint)
{
Q_D(QPixmapBlurFilter);
d->hint = hint;
@@ -572,7 +572,7 @@ void QPixmapBlurFilter::setBlurHint(QPixmapBlurFilter::BlurHint hint)
\internal
*/
-QPixmapBlurFilter::BlurHint QPixmapBlurFilter::blurHint() const
+Qt::RenderHint QPixmapBlurFilter::blurHint() const
{
Q_D(const QPixmapBlurFilter);
return d->hint;
@@ -1074,6 +1074,16 @@ void QPixmapDropShadowFilter::draw(QPainter *p,
const QRectF &src) const
{
Q_D(const QPixmapDropShadowFilter);
+ QPixmapFilter *filter = p->paintEngine() && p->paintEngine()->isExtended() ?
+ static_cast<QPaintEngineEx *>(p->paintEngine())->pixmapFilter(type(), this) : 0;
+ QPixmapDropShadowFilter *dropShadowFilter = static_cast<QPixmapDropShadowFilter*>(filter);
+ if (dropShadowFilter) {
+ dropShadowFilter->setColor(d->color);
+ dropShadowFilter->setBlurRadius(d->blurFilter->radius());
+ dropShadowFilter->setOffset(d->offset);
+ dropShadowFilter->draw(p, pos, px, src);
+ return;
+ }
QImage tmp = src.isNull() ? px.toImage() : px.copy(src.toRect()).toImage();
QPainter tmpPainter(&tmp);
diff --git a/src/gui/image/qpixmapfilter_p.h b/src/gui/image/qpixmapfilter_p.h
index 92c8e56..8a2207a 100644
--- a/src/gui/image/qpixmapfilter_p.h
+++ b/src/gui/image/qpixmapfilter_p.h
@@ -126,19 +126,14 @@ class Q_GUI_EXPORT QPixmapBlurFilter : public QPixmapFilter
Q_DECLARE_PRIVATE(QPixmapBlurFilter)
public:
- enum BlurHint {
- PerformanceHint,
- QualityHint
- };
-
QPixmapBlurFilter(QObject *parent = 0);
~QPixmapBlurFilter();
void setRadius(int radius);
- void setBlurHint(BlurHint hint);
+ void setBlurHint(Qt::RenderHint hint);
int radius() const;
- BlurHint blurHint() const;
+ Qt::RenderHint blurHint() const;
QRectF boundingRectFor(const QRectF &rect) const;
void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index fc55a0f..c4d17ff 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -222,7 +222,7 @@ void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event)
TCoeInputCapabilities QCoeFepInputContext::inputCapabilities()
{
- if (m_inDestruction) {
+ if (m_inDestruction || !focusWidget()) {
return TCoeInputCapabilities(TCoeInputCapabilities::ENone, 0, 0);
}
@@ -554,8 +554,10 @@ void QCoeFepInputContext::SetCursorSelectionForFepL(const TCursorSelection& aCur
void QCoeFepInputContext::GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const
{
QWidget *w = focusWidget();
- if (!w)
+ if (!w) {
+ aCursorSelection.SetSelection(0,0);
return;
+ }
int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt() + m_preeditString.size();
int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt() + m_preeditString.size();
@@ -567,8 +569,10 @@ void QCoeFepInputContext::GetEditorContentForFep(TDes& aEditorContent, TInt aDoc
TInt aLengthToRetrieve) const
{
QWidget *w = focusWidget();
- if (!w)
+ if (!w) {
+ aEditorContent.FillZ(aLengthToRetrieve);
return;
+ }
QString text = w->inputMethodQuery(Qt::ImSurroundingText).value<QString>();
// FEP expects the preedit string to be part of the editor content, so let's mix it in.
@@ -580,8 +584,10 @@ void QCoeFepInputContext::GetEditorContentForFep(TDes& aEditorContent, TInt aDoc
void QCoeFepInputContext::GetFormatForFep(TCharFormat& aFormat, TInt /* aDocumentPosition */) const
{
QWidget *w = focusWidget();
- if (!w)
+ if (!w) {
+ aFormat = TCharFormat();
return;
+ }
QFont font = w->inputMethodQuery(Qt::ImFont).value<QFont>();
QFontMetrics metrics(font);
@@ -595,8 +601,12 @@ void QCoeFepInputContext::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLin
TInt& aAscent, TInt /* aDocumentPosition */) const
{
QWidget *w = focusWidget();
- if (!w)
+ if (!w) {
+ aLeftSideOfBaseLine = TPoint(0,0);
+ aHeight = 0;
+ aAscent = 0;
return;
+ }
QRect rect = w->inputMethodQuery(Qt::ImMicroFocus).value<QRect>();
aLeftSideOfBaseLine.iX = rect.left();
diff --git a/src/gui/inputmethod/qwininputcontext_p.h b/src/gui/inputmethod/qwininputcontext_p.h
index 39d50fd..dd0490d 100644
--- a/src/gui/inputmethod/qwininputcontext_p.h
+++ b/src/gui/inputmethod/qwininputcontext_p.h
@@ -56,6 +56,19 @@
#include "QtGui/qinputcontext.h"
#include "QtCore/qt_windows.h"
+#if defined(Q_CC_MINGW) && !defined(IMR_RECONVERTSTRING)
+typedef struct tagRECONVERTSTRING {
+ DWORD dwSize;
+ DWORD dwVersion;
+ DWORD dwStrLen;
+ DWORD dwStrOffset;
+ DWORD dwCompStrLen;
+ DWORD dwCompStrOffset;
+ DWORD dwTargetStrLen;
+ DWORD dwTargetStrOffset;
+} RECONVERTSTRING, *PRECONVERTSTRING;
+#endif
+
QT_BEGIN_NAMESPACE
class QWinInputContext : public QInputContext
diff --git a/src/gui/inputmethod/qwininputcontext_win.cpp b/src/gui/inputmethod/qwininputcontext_win.cpp
index 4a160d7..e9ab870 100644
--- a/src/gui/inputmethod/qwininputcontext_win.cpp
+++ b/src/gui/inputmethod/qwininputcontext_win.cpp
@@ -701,7 +701,7 @@ void QWinInputContext::updateImeStatus(QWidget *w, bool hasFocus)
if (!focusProxyWidget)
focusProxyWidget = w;
bool e = w->testAttribute(Qt::WA_InputMethodEnabled) && w->isEnabled()
- && !(focusProxyWidget->inputMethodHints() & Qt::ImhExclusiveInputMask);
+ && !(focusProxyWidget->inputMethodHints() & (Qt::ImhExclusiveInputMask | Qt::ImhHiddenText));
bool hasIme = e && hasFocus;
#ifdef Q_IME_DEBUG
qDebug("%s HasFocus = %d hasIme = %d e = %d ", w->className(), hasFocus, hasIme, e);
diff --git a/src/gui/inputmethod/qximinputcontext_x11.cpp b/src/gui/inputmethod/qximinputcontext_x11.cpp
index bee3ce8..b46b162 100644
--- a/src/gui/inputmethod/qximinputcontext_x11.cpp
+++ b/src/gui/inputmethod/qximinputcontext_x11.cpp
@@ -612,7 +612,7 @@ void QXIMInputContext::setFocusWidget(QWidget *w)
QInputContext::setFocusWidget(w);
- if (!w || w->inputMethodHints() & Qt::ImhExclusiveInputMask)
+ if (!w || w->inputMethodHints() & (Qt::ImhExclusiveInputMask | Qt::ImhHiddenText))
return;
ICData *data = ximData.value(w->effectiveWinId());
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index 303f45b..268e78e 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -87,6 +87,7 @@ QAbstractItemViewPrivate::QAbstractItemViewPrivate()
dragDropMode(QAbstractItemView::NoDragDrop),
overwrite(false),
dropIndicatorPosition(QAbstractItemView::OnItem),
+ defaultDropAction(Qt::IgnoreAction),
#endif
#ifdef QT_SOFTKEYS_ENABLED
doneSoftKey(0),
@@ -750,7 +751,6 @@ void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *delegate)
}
}
-
if (delegate) {
if (d->delegateRefCount(delegate) == 0) {
connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
@@ -761,6 +761,7 @@ void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *delegate)
}
}
d->itemDelegate = delegate;
+ viewport()->update();
}
/*!
@@ -825,6 +826,7 @@ void QAbstractItemView::setItemDelegateForRow(int row, QAbstractItemDelegate *de
}
d->rowDelegates.insert(row, delegate);
}
+ viewport()->update();
}
/*!
@@ -881,6 +883,7 @@ void QAbstractItemView::setItemDelegateForColumn(int column, QAbstractItemDelega
}
d->columnDelegates.insert(column, delegate);
}
+ viewport()->update();
}
/*!
@@ -1371,6 +1374,28 @@ QAbstractItemView::DragDropMode QAbstractItemView::dragDropMode() const
return NoDragDrop;
}
+/*!
+ \property QAbstractItemView::defaultDropAction
+ \brief the drop action that will be used by default in QAbstractItemView::drag()
+
+ If the property is not set, the drop action is CopyAction when the supported
+ actions support CopyAction.
+
+ \since 4.6
+ \sa showDropIndicator dragDropOverwriteMode
+*/
+void QAbstractItemView::setDefaultDropAction(Qt::DropAction dropAction)
+{
+ Q_D(QAbstractItemView);
+ d->defaultDropAction = dropAction;
+}
+
+Qt::DropAction QAbstractItemView::defaultDropAction() const
+{
+ Q_D(const QAbstractItemView);
+ return d->defaultDropAction;
+}
+
#endif // QT_NO_DRAGANDDROP
/*!
@@ -2160,6 +2185,9 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
} else {
d->selectionModel->setCurrentIndex(newCurrent, command);
d->pressedPosition = visualRect(newCurrent).center() + d->offset();
+ // We copy the same behaviour as for mousePressEvent().
+ QRect rect(d->pressedPosition - d->offset(), QSize(1, 1));
+ setSelection(rect, command);
}
return;
}
@@ -3297,7 +3325,9 @@ void QAbstractItemView::startDrag(Qt::DropActions supportedActions)
drag->setMimeData(data);
drag->setHotSpot(d->pressedPosition - rect.topLeft());
Qt::DropAction defaultDropAction = Qt::IgnoreAction;
- if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
+ if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction))
+ defaultDropAction = d->defaultDropAction;
+ else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
defaultDropAction = Qt::CopyAction;
if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction)
d->clearOrRemove();
@@ -3626,12 +3656,13 @@ QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::extendedSelectionC
case Qt::Key_PageUp:
case Qt::Key_PageDown:
case Qt::Key_Tab:
+ if (modifiers & Qt::ControlModifier
#ifdef QT_KEYPAD_NAVIGATION
- return QItemSelectionModel::NoUpdate;
-#else
- if (modifiers & Qt::ControlModifier)
- return QItemSelectionModel::NoUpdate;
+ // Preserve historical tab order navigation behavior
+ || QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
#endif
+ )
+ return QItemSelectionModel::NoUpdate;
break;
case Qt::Key_Select:
return QItemSelectionModel::Toggle|selectionBehaviorFlags();
diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h
index 7d5c765..b4f0957 100644
--- a/src/gui/itemviews/qabstractitemview.h
+++ b/src/gui/itemviews/qabstractitemview.h
@@ -74,6 +74,7 @@ class Q_GUI_EXPORT QAbstractItemView : public QAbstractScrollArea
Q_PROPERTY(bool dragEnabled READ dragEnabled WRITE setDragEnabled)
Q_PROPERTY(bool dragDropOverwriteMode READ dragDropOverwriteMode WRITE setDragDropOverwriteMode)
Q_PROPERTY(DragDropMode dragDropMode READ dragDropMode WRITE setDragDropMode)
+ Q_PROPERTY(Qt::DropAction defaultDropAction READ defaultDropAction WRITE setDefaultDropAction)
#endif
Q_PROPERTY(bool alternatingRowColors READ alternatingRowColors WRITE setAlternatingRowColors)
Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
@@ -181,7 +182,11 @@ public:
void setDragDropMode(DragDropMode behavior);
DragDropMode dragDropMode() const;
+
+ void setDefaultDropAction(Qt::DropAction dropAction);
+ Qt::DropAction defaultDropAction() const;
#endif
+
void setAlternatingRowColors(bool enable);
bool alternatingRowColors() const;
diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h
index 84c0892..fcf381a 100644
--- a/src/gui/itemviews/qabstractitemview_p.h
+++ b/src/gui/itemviews/qabstractitemview_p.h
@@ -117,7 +117,7 @@ public:
virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end);
virtual void _q_modelDestroyed();
virtual void _q_layoutChanged();
-
+
void fetchMore();
bool shouldEdit(QAbstractItemView::EditTrigger trigger, const QModelIndex &index) const;
@@ -315,7 +315,7 @@ public:
}
return ref;
}
-
+
/**
* return true if the index is registered as a QPersistentModelIndex
*/
@@ -356,8 +356,8 @@ public:
Qt::KeyboardModifiers pressedModifiers;
QPoint pressedPosition;
bool pressedAlreadySelected;
-
- //forces the next mouseMoveEvent to send the viewportEntered signal
+
+ //forces the next mouseMoveEvent to send the viewportEntered signal
//if the mouse is over the viewport and not over an item
bool viewportEnteredNeeded;
@@ -377,6 +377,7 @@ public:
QAbstractItemView::DragDropMode dragDropMode;
bool overwrite;
QAbstractItemView::DropIndicatorPosition dropIndicatorPosition;
+ Qt::DropAction defaultDropAction;
#endif
#ifdef QT_SOFTKEYS_ENABLED
diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp
index 4abdef9..e3d17ad 100644
--- a/src/gui/itemviews/qfileiconprovider.cpp
+++ b/src/gui/itemviews/qfileiconprovider.cpp
@@ -54,7 +54,14 @@
#elif defined(Q_WS_MAC)
#include <private/qt_cocoa_helpers_mac_p.h>
#endif
+
+#if defined(Q_WS_X11) && !defined(Q_NO_STYLE_GTK)
+#include <private/qt_x11_p.h>
+#include <private/gtksymbols_p.h>
+#endif
+
#include <private/qfunctions_p.h>
+#include <private/qguiplatformplugin_p.h>
#ifndef SHGFI_ADDOVERLAYS
#define SHGFI_ADDOVERLAYS 0x000000020
@@ -378,6 +385,19 @@ QIcon QFileIconProviderPrivate::getMacIcon(const QFileInfo &fi) const
QIcon QFileIconProvider::icon(const QFileInfo &info) const
{
Q_D(const QFileIconProvider);
+
+ QIcon platformIcon = qt_guiPlatformPlugin()->fileSystemIcon(info);
+ if (!platformIcon.isNull())
+ return platformIcon;
+
+#if defined(Q_WS_X11) && !defined(QT_NO_STYLE_GTK)
+ if (X11->desktopEnvironment == DE_GNOME) {
+ QIcon gtkIcon = QGtk::getFilesystemIcon(info);
+ if (!gtkIcon.isNull())
+ return gtkIcon;
+ }
+#endif
+
#ifdef Q_WS_MAC
QIcon retIcon = d->getMacIcon(info);
if (!retIcon.isNull())
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index f1ffaa6..2d98258 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -191,6 +191,359 @@ QList<QSpanCollection::Span *> QSpanCollection::spansInRect(int x, int y, int w,
return list.toList();
}
+#undef DEBUG_SPAN_UPDATE
+
+#ifdef DEBUG_SPAN_UPDATE
+QDebug operator<<(QDebug str, const QSpanCollection::Span &span)
+{
+ str << "(" << span.top() << "," << span.left() << "," << span.bottom() << "," << span.right() << ")";
+ return str;
+}
+#endif
+
+/** \internal
+* Updates the span collection after row insertion.
+*/
+void QSpanCollection::updateInsertedRows(int start, int end)
+{
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug() << Q_FUNC_INFO;
+ qDebug() << start << end;
+ qDebug() << index;
+#endif
+ if (spans.isEmpty())
+ return;
+
+ int delta = end - start + 1;
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug("Before");
+#endif
+ for (SpanList::iterator it = spans.begin(); it != spans.end(); ++it) {
+ Span *span = *it;
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug() << span << *span;
+#endif
+ if (span->m_bottom < start)
+ continue;
+ if (span->m_top >= start)
+ span->m_top += delta;
+ span->m_bottom += delta;
+ }
+
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug("After");
+ foreach (QSpanCollection::Span *span, spans)
+ qDebug() << span << *span;
+#endif
+
+ for (Index::iterator it_y = index.begin(); it_y != index.end(); ) {
+ int y = -it_y.key();
+ if (y < start) {
+ ++it_y;
+ continue;
+ }
+
+ index.insert(-y - delta, it_y.value());
+ it_y = index.erase(it_y);
+ }
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug() << index;
+#endif
+}
+
+/** \internal
+* Updates the span collection after column insertion.
+*/
+void QSpanCollection::updateInsertedColumns(int start, int end)
+{
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug() << Q_FUNC_INFO;
+ qDebug() << start << end;
+ qDebug() << index;
+#endif
+ if (spans.isEmpty())
+ return;
+
+ int delta = end - start + 1;
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug("Before");
+#endif
+ for (SpanList::iterator it = spans.begin(); it != spans.end(); ++it) {
+ Span *span = *it;
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug() << span << *span;
+#endif
+ if (span->m_right < start)
+ continue;
+ if (span->m_left >= start)
+ span->m_left += delta;
+ span->m_right += delta;
+ }
+
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug("After");
+ foreach (QSpanCollection::Span *span, spans)
+ qDebug() << span << *span;
+#endif
+
+ for (Index::iterator it_y = index.begin(); it_y != index.end(); ++it_y) {
+ SubIndex &subindex = it_y.value();
+ for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ) {
+ int x = -it.key();
+ if (x < start) {
+ ++it;
+ continue;
+ }
+ subindex.insert(-x - delta, it.value());
+ it = subindex.erase(it);
+ }
+ }
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug() << index;
+#endif
+}
+
+/** \internal
+* Cleans a subindex from to be deleted spans. The update argument is used
+* to move the spans inside the subindex, in case their anchor changed.
+* \return true if no span in this subindex starts at y, and should thus be deleted.
+*/
+bool QSpanCollection::cleanSpanSubIndex(QSpanCollection::SubIndex &subindex, int y, bool update)
+{
+ if (subindex.isEmpty())
+ return true;
+
+ bool should_be_deleted = true;
+ SubIndex::iterator it = subindex.end();
+ do {
+ --it;
+ int x = -it.key();
+ Span *span = it.value();
+ if (span->will_be_deleted) {
+ it = subindex.erase(it);
+ continue;
+ }
+ if (update && span->m_left != x) {
+ subindex.insert(-span->m_left, span);
+ it = subindex.erase(it);
+ }
+ if (should_be_deleted && span->m_top == y)
+ should_be_deleted = false;
+ } while (it != subindex.begin());
+
+ return should_be_deleted;
+}
+
+/** \internal
+* Updates the span collection after row removal.
+*/
+void QSpanCollection::updateRemovedRows(int start, int end)
+{
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug() << Q_FUNC_INFO;
+ qDebug() << start << end;
+ qDebug() << index;
+#endif
+ if (spans.isEmpty())
+ return;
+
+ SpanList spansToBeDeleted;
+ int delta = end - start + 1;
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug("Before");
+#endif
+ for (SpanList::iterator it = spans.begin(); it != spans.end(); ) {
+ Span *span = *it;
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug() << span << *span;
+#endif
+ if (span->m_bottom < start) {
+ ++it;
+ continue;
+ }
+ if (span->m_top < start) {
+ if (span->m_bottom <= end)
+ span->m_bottom = start - 1;
+ else
+ span->m_bottom -= delta;
+ } else {
+ if (span->m_bottom > end) {
+ if (span->m_top <= end)
+ span->m_top = start;
+ else
+ span->m_top -= delta;
+ span->m_bottom -= delta;
+ } else {
+ span->will_be_deleted = true;
+ }
+ }
+ if (span->m_top == span->m_bottom && span->m_left == span->m_right)
+ span->will_be_deleted = true;
+ if (span->will_be_deleted) {
+ spansToBeDeleted.append(span);
+ it = spans.erase(it);
+ } else {
+ ++it;
+ }
+ }
+
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug("After");
+ foreach (QSpanCollection::Span *span, spans)
+ qDebug() << span << *span;
+#endif
+ if (spans.isEmpty()) {
+ qDeleteAll(spansToBeDeleted);
+ index.clear();
+ return;
+ }
+
+ Index::iterator it_y = index.end();
+ do {
+ --it_y;
+ int y = -it_y.key();
+ SubIndex &subindex = it_y.value();
+ if (y < start) {
+ if (cleanSpanSubIndex(subindex, y))
+ it_y = index.erase(it_y);
+ } else if (y >= start && y <= end) {
+ bool span_at_start = false;
+ SubIndex spansToBeMoved;
+ for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ++it) {
+ Span *span = it.value();
+ if (span->will_be_deleted)
+ continue;
+ if (!span_at_start && span->m_top == start)
+ span_at_start = true;
+ spansToBeMoved.insert(it.key(), span);
+ }
+
+ if (y == start && span_at_start)
+ subindex.clear();
+ else
+ it_y = index.erase(it_y);
+
+ if (span_at_start) {
+ Index::iterator it_start;
+ if (y == start)
+ it_start = it_y;
+ else {
+ it_start = index.find(-start);
+ if (it_start == index.end())
+ it_start = index.insert(-start, SubIndex());
+ }
+ SubIndex &start_subindex = it_start.value();
+ for (SubIndex::iterator it = spansToBeMoved.begin(); it != spansToBeMoved.end(); ++it)
+ start_subindex.insert(it.key(), it.value());
+ }
+ } else {
+ if (y == end + 1) {
+ Index::iterator it_top = index.find(-y + delta);
+ if (it_top == index.end())
+ it_top = index.insert(-y + delta, SubIndex());
+ for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ) {
+ Span *span = it.value();
+ if (!span->will_be_deleted)
+ it_top.value().insert(it.key(), span);
+ ++it;
+ }
+ } else {
+ index.insert(-y + delta, subindex);
+ }
+ it_y = index.erase(it_y);
+ }
+ } while (it_y != index.begin());
+
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug() << index;
+ qDebug("Deleted");
+ foreach (QSpanCollection::Span *span, spansToBeDeleted)
+ qDebug() << span << *span;
+#endif
+ qDeleteAll(spansToBeDeleted);
+}
+
+/** \internal
+* Updates the span collection after column removal.
+*/
+void QSpanCollection::updateRemovedColumns(int start, int end)
+{
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug() << Q_FUNC_INFO;
+ qDebug() << start << end;
+ qDebug() << index;
+#endif
+ if (spans.isEmpty())
+ return;
+
+ SpanList toBeDeleted;
+ int delta = end - start + 1;
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug("Before");
+#endif
+ for (SpanList::iterator it = spans.begin(); it != spans.end(); ) {
+ Span *span = *it;
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug() << span << *span;
+#endif
+ if (span->m_right < start) {
+ ++it;
+ continue;
+ }
+ if (span->m_left < start) {
+ if (span->m_right <= end)
+ span->m_right = start - 1;
+ else
+ span->m_right -= delta;
+ } else {
+ if (span->m_right > end) {
+ if (span->m_left <= end)
+ span->m_left = start;
+ else
+ span->m_left -= delta;
+ span->m_right -= delta;
+ } else {
+ span->will_be_deleted = true;
+ }
+ }
+ if (span->m_top == span->m_bottom && span->m_left == span->m_right)
+ span->will_be_deleted = true;
+ if (span->will_be_deleted) {
+ toBeDeleted.append(span);
+ it = spans.erase(it);
+ } else {
+ ++it;
+ }
+ }
+
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug("After");
+ foreach (QSpanCollection::Span *span, spans)
+ qDebug() << span << *span;
+#endif
+ if (spans.isEmpty()) {
+ qDeleteAll(toBeDeleted);
+ index.clear();
+ return;
+ }
+
+ for (Index::iterator it_y = index.begin(); it_y != index.end(); ) {
+ int y = -it_y.key();
+ if (cleanSpanSubIndex(it_y.value(), y, true))
+ it_y = index.erase(it_y);
+ else
+ ++it_y;
+ }
+
+#ifdef DEBUG_SPAN_UPDATE
+ qDebug() << index;
+ qDebug("Deleted");
+ foreach (QSpanCollection::Span *span, toBeDeleted)
+ qDebug() << span << *span;
+#endif
+ qDeleteAll(toBeDeleted);
+}
+
class QTableCornerButton : public QAbstractButton
{
Q_OBJECT
@@ -299,6 +652,9 @@ void QTableViewPrivate::setSpan(int row, int column, int rowSpan, int columnSpan
sp->m_right = column + columnSpan - 1;
spans.updateSpan(sp, old_height);
return;
+ } else if (rowSpan == 1 && columnSpan == 1) {
+ qWarning() << "QTableView::setSpan: single cell span won't be added";
+ return;
}
sp = new QSpanCollection::Span(row, column, rowSpan, columnSpan);
spans.addSpan(sp);
@@ -423,8 +779,6 @@ void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter,
foreach (QSpanCollection::Span *span, visibleSpans) {
int row = span->top();
int col = span->left();
- if (isHidden(row, col))
- continue;
QModelIndex index = model->index(row, col, root);
if (!index.isValid())
continue;
@@ -460,6 +814,46 @@ void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter,
/*!
\internal
+ Updates spans after row insertion.
+*/
+void QTableViewPrivate::_q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ spans.updateInsertedRows(start, end);
+}
+
+/*!
+ \internal
+ Updates spans after column insertion.
+*/
+void QTableViewPrivate::_q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ spans.updateInsertedColumns(start, end);
+}
+
+/*!
+ \internal
+ Updates spans after row removal.
+*/
+void QTableViewPrivate::_q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ spans.updateRemovedRows(start, end);
+}
+
+/*!
+ \internal
+ Updates spans after column removal.
+*/
+void QTableViewPrivate::_q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ spans.updateRemovedColumns(start, end);
+}
+
+/*!
+ \internal
Draws a table cell.
*/
void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItemV4 &option, const QModelIndex &index)
@@ -629,6 +1023,14 @@ QTableView::~QTableView()
void QTableView::setModel(QAbstractItemModel *model)
{
Q_D(QTableView);
+ connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_updateSpanInsertedRows(QModelIndex,int,int)));
+ connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_updateSpanInsertedColumns(QModelIndex,int,int)));
+ connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ this, SLOT(_q_updateSpanRemovedRows(QModelIndex,int,int)));
+ connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
+ this, SLOT(_q_updateSpanRemovedColumns(QModelIndex,int,int)));
d->verticalHeader->setModel(model);
d->horizontalHeader->setModel(model);
QAbstractItemView::setModel(model);
@@ -1076,12 +1478,30 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi
++column;
while (isRowHidden(d->logicalRow(row)) && row < bottom)
++row;
+ d->visualCursor = QPoint(column, row);
return d->model->index(d->logicalRow(row), d->logicalColumn(column), d->root);
}
- int visualRow = d->visualRow(current.row());
+ // Update visual cursor if current index has changed.
+ QPoint visualCurrent(d->visualColumn(current.column()), d->visualRow(current.row()));
+ if (visualCurrent != d->visualCursor) {
+ if (d->hasSpans()) {
+ QSpanCollection::Span span = d->span(current.row(), current.column());
+ if (span.top() > d->visualCursor.y() || d->visualCursor.y() > span.bottom()
+ || span.left() > d->visualCursor.x() || d->visualCursor.x() > span.right())
+ d->visualCursor = visualCurrent;
+ } else {
+ d->visualCursor = visualCurrent;
+ }
+ }
+
+ int visualRow = d->visualCursor.y();
+ if (visualRow > bottom)
+ visualRow = bottom;
Q_ASSERT(visualRow != -1);
- int visualColumn = d->visualColumn(current.column());
+ int visualColumn = d->visualCursor.x();
+ if (visualColumn > right)
+ visualColumn = right;
Q_ASSERT(visualColumn != -1);
if (isRightToLeft()) {
@@ -1092,22 +1512,33 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi
}
switch (cursorAction) {
- case MoveUp:
+ case MoveUp: {
+ int originalRow = visualRow;
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled() && visualRow == 0)
visualRow = d->visualRow(model()->rowCount() - 1) + 1;
+ // FIXME? visualRow = bottom + 1;
#endif
- --visualRow;
- while (visualRow > 0 && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn))
+ int r = d->logicalRow(visualRow);
+ int c = d->logicalColumn(visualColumn);
+ if (r != -1 && d->hasSpans()) {
+ QSpanCollection::Span span = d->span(r, c);
+ if (span.width() > 1 || span.height() > 1)
+ visualRow = d->visualRow(span.top());
+ }
+ while (visualRow >= 0) {
--visualRow;
- if (d->hasSpans()) {
- int row = d->logicalRow(visualRow);
- QSpanCollection::Span span = d->span(row, current.column());
- visualRow = d->visualRow(span.top());
- visualColumn = d->visualColumn(span.left());
+ r = d->logicalRow(visualRow);
+ c = d->logicalColumn(visualColumn);
+ if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c)))
+ break;
}
+ if (visualRow < 0)
+ visualRow = originalRow;
break;
- case MoveDown:
+ }
+ case MoveDown: {
+ int originalRow = visualRow;
if (d->hasSpans()) {
QSpanCollection::Span span = d->span(current.row(), current.column());
visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));
@@ -1116,71 +1547,106 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi
if (QApplication::keypadNavigationEnabled() && visualRow >= bottom)
visualRow = -1;
#endif
- ++visualRow;
- while (visualRow < bottom && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn))
+ int r = d->logicalRow(visualRow);
+ int c = d->logicalColumn(visualColumn);
+ if (r != -1 && d->hasSpans()) {
+ QSpanCollection::Span span = d->span(r, c);
+ if (span.width() > 1 || span.height() > 1)
+ visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height()));
+ }
+ while (visualRow <= bottom) {
++visualRow;
- if (d->hasSpans()) {
- int row = d->logicalRow(visualRow);
- QSpanCollection::Span span = d->span(row, current.column());
- visualColumn = d->visualColumn(span.left());
+ r = d->logicalRow(visualRow);
+ c = d->logicalColumn(visualColumn);
+ if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c)))
+ break;
}
+ if (visualRow > bottom)
+ visualRow = originalRow;
break;
- case MovePrevious: {
- int left = 0;
- while (d->isVisualColumnHiddenOrDisabled(visualRow, left) && left < right)
- ++left;
- if (visualColumn == left) {
- visualColumn = right;
- int top = 0;
- while (top < bottom && d->isVisualRowHiddenOrDisabled(top, visualColumn))
- ++top;
- if (visualRow == top)
+ }
+ case MovePrevious:
+ case MoveLeft: {
+ int originalRow = visualRow;
+ int originalColumn = visualColumn;
+ bool firstTime = true;
+ bool looped = false;
+ bool wrapped = false;
+ do {
+ int r = d->logicalRow(visualRow);
+ int c = d->logicalColumn(visualColumn);
+ if (firstTime && c != -1 && d->hasSpans()) {
+ firstTime = false;
+ QSpanCollection::Span span = d->span(r, c);
+ if (span.width() > 1 || span.height() > 1)
+ visualColumn = d->visualColumn(span.left());
+ }
+ while (visualColumn >= 0) {
+ --visualColumn;
+ r = d->logicalRow(visualRow);
+ c = d->logicalColumn(visualColumn);
+ if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c)))
+ break;
+ if (wrapped && (originalRow < visualRow || (originalRow == visualRow && originalColumn <= visualColumn))) {
+ looped = true;
+ break;
+ }
+ }
+ if (cursorAction == MoveLeft || visualColumn >= 0)
+ break;
+ visualColumn = right + 1;
+ if (visualRow == 0) {
+ wrapped == true;
visualRow = bottom;
- else
- --visualRow;
- while (visualRow > 0 && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn))
+ } else {
--visualRow;
- break;
- } // else MoveLeft
- }
- case MoveLeft:
- --visualColumn;
- while (visualColumn > 0 && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn))
- --visualColumn;
- if (d->hasSpans()) {
- int column = d->logicalColumn(visualColumn);
- QSpanCollection::Span span = d->span(current.row(), column);
- visualRow = d->visualRow(span.top());
- visualColumn = d->visualColumn(span.left());
- }
+ }
+ } while (!looped);
+ if (visualColumn < 0)
+ visualColumn = originalColumn;
break;
+ }
case MoveNext:
- if (visualColumn == right) {
- visualColumn = 0;
- while (visualColumn < right && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn))
+ case MoveRight: {
+ int originalRow = visualRow;
+ int originalColumn = visualColumn;
+ bool firstTime = true;
+ bool looped = false;
+ bool wrapped = false;
+ do {
+ int r = d->logicalRow(visualRow);
+ int c = d->logicalColumn(visualColumn);
+ if (firstTime && c != -1 && d->hasSpans()) {
+ firstTime = false;
+ QSpanCollection::Span span = d->span(r, c);
+ if (span.width() > 1 || span.height() > 1)
+ visualColumn = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width()));
+ }
+ while (visualColumn <= right) {
++visualColumn;
- if (visualRow == bottom)
+ r = d->logicalRow(visualRow);
+ c = d->logicalColumn(visualColumn);
+ if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c)))
+ break;
+ if (wrapped && (originalRow > visualRow || (originalRow == visualRow && originalColumn >= visualColumn))) {
+ looped = true;
+ break;
+ }
+ }
+ if (cursorAction == MoveRight || visualColumn <= right)
+ break;
+ visualColumn = -1;
+ if (visualRow == bottom) {
+ wrapped = true;
visualRow = 0;
- else
+ } else {
++visualRow;
- while (visualRow < bottom && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn))
- ++visualRow;
- break;
- } // else MoveRight
- case MoveRight:
- if (d->hasSpans()) {
- QSpanCollection::Span span = d->span(current.row(), current.column());
- visualColumn = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width()));
- }
- ++visualColumn;
- while (visualColumn < right && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn))
- ++visualColumn;
- if (d->hasSpans()) {
- int column = d->logicalColumn(visualColumn);
- QSpanCollection::Span span = d->span(current.row(), column);
- visualRow = d->visualRow(span.top());
- }
+ }
+ } while (!looped);
+ if (visualColumn > right)
+ visualColumn = originalColumn;
break;
+ }
case MoveHome:
visualColumn = 0;
while (visualColumn < right && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn))
@@ -1209,14 +1675,15 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi
return d->model->index(newRow, current.column(), d->root);
}}
+ d->visualCursor = QPoint(visualColumn, visualRow);
int logicalRow = d->logicalRow(visualRow);
int logicalColumn = d->logicalColumn(visualColumn);
if (!d->model->hasIndex(logicalRow, logicalColumn, d->root))
return QModelIndex();
QModelIndex result = d->model->index(logicalRow, logicalColumn, d->root);
- if (!isIndexHidden(result) && d->isIndexEnabled(result))
- return d->model->index(logicalRow, logicalColumn, d->root);
+ if (!d->isRowHidden(logicalRow) && !d->isColumnHidden(logicalColumn) && d->isIndexEnabled(result))
+ return result;
return QModelIndex();
}
@@ -1971,7 +2438,8 @@ bool QTableView::isCornerButtonEnabled() const
QRect QTableView::visualRect(const QModelIndex &index) const
{
Q_D(const QTableView);
- if (!d->isIndexValid(index) || index.parent() != d->root || isIndexHidden(index) )
+ if (!d->isIndexValid(index) || index.parent() != d->root
+ || (!d->hasSpans() && isIndexHidden(index)))
return QRect();
d->executePostedLayout();
diff --git a/src/gui/itemviews/qtableview.h b/src/gui/itemviews/qtableview.h
index a08d6a9..541c419 100644
--- a/src/gui/itemviews/qtableview.h
+++ b/src/gui/itemviews/qtableview.h
@@ -182,6 +182,10 @@ private:
Q_DISABLE_COPY(QTableView)
Q_PRIVATE_SLOT(d_func(), void _q_selectRow(int))
Q_PRIVATE_SLOT(d_func(), void _q_selectColumn(int))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedRows(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedColumns(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedRows(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedColumns(QModelIndex,int,int))
};
#endif // QT_NO_TABLEVIEW
diff --git a/src/gui/itemviews/qtableview_p.h b/src/gui/itemviews/qtableview_p.h
index 36a3ece..9fa14c2 100644
--- a/src/gui/itemviews/qtableview_p.h
+++ b/src/gui/itemviews/qtableview_p.h
@@ -54,6 +54,7 @@
//
#include <QtCore/QList>
+#include <QtCore/QLinkedList>
#include <QtCore/QMap>
#include <QtCore/QSet>
#include <QtCore/QDebug>
@@ -82,10 +83,11 @@ public:
int m_left;
int m_bottom;
int m_right;
+ bool will_be_deleted;
Span()
- : m_top(-1), m_left(-1), m_bottom(-1), m_right(-1) { }
+ : m_top(-1), m_left(-1), m_bottom(-1), m_right(-1), will_be_deleted(false) { }
Span(int row, int column, int rowCount, int columnCount)
- : m_top(row), m_left(column), m_bottom(row+rowCount-1), m_right(column+columnCount-1) { }
+ : m_top(row), m_left(column), m_bottom(row+rowCount-1), m_right(column+columnCount-1), will_be_deleted(false) { }
inline int top() const { return m_top; }
inline int left() const { return m_left; }
inline int bottom() const { return m_bottom; }
@@ -105,12 +107,20 @@ public:
void clear();
QList<Span *> spansInRect(int x, int y, int w, int h) const;
- QList<Span *> spans; //lists of all spans
+ void updateInsertedRows(int start, int end);
+ void updateInsertedColumns(int start, int end);
+ void updateRemovedRows(int start, int end);
+ void updateRemovedColumns(int start, int end);
+
+ typedef QLinkedList<Span *> SpanList;
+ SpanList spans; //lists of all spans
private:
//the indexes are negative so the QMap::lowerBound do what i need.
typedef QMap<int, Span *> SubIndex;
typedef QMap<int, SubIndex> Index;
Index index;
+
+ bool cleanSpanSubIndex(SubIndex &subindex, int end, bool update = false);
};
Q_DECLARE_TYPEINFO ( QSpanCollection::Span, Q_MOVABLE_TYPE);
@@ -125,7 +135,8 @@ public:
rowSectionAnchor(-1), columnSectionAnchor(-1),
columnResizeTimerID(0), rowResizeTimerID(0),
horizontalHeader(0), verticalHeader(0),
- sortingEnabled(false), geometryRecursionBlock(false)
+ sortingEnabled(false), geometryRecursionBlock(false),
+ visualCursor(QPoint())
{
wrapItemText = true;
#ifndef QT_NO_DRAGANDDROP
@@ -173,6 +184,7 @@ public:
QWidget *cornerWidget;
bool sortingEnabled;
bool geometryRecursionBlock;
+ QPoint visualCursor; // (Row,column) cell coordinates to track through span navigation.
QSpanCollection spans;
@@ -227,6 +239,11 @@ public:
void selectRow(int row, bool anchor);
void selectColumn(int column, bool anchor);
+
+ void _q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end);
+ void _q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end);
+ void _q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end);
+ void _q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 1ae6d29..af7c55f 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -45,9 +45,11 @@ HEADERS += \
kernel/qkeymapper_p.h \
kernel/qgesture.h \
kernel/qgesture_p.h \
- kernel/qstandardgestures.h \
- kernel/qstandardgestures_p.h \
- kernel/qsoftkeymanager_p.h
+ kernel/qstandardgestures_p.h \
+ kernel/qgesturerecognizer.h \
+ kernel/qgesturemanager_p.h \
+ kernel/qsoftkeymanager_p.h \
+ kernel/qguiplatformplugin_p.h
SOURCES += \
kernel/qaction.cpp \
@@ -78,12 +80,18 @@ SOURCES += \
kernel/qwidgetaction.cpp \
kernel/qkeymapper.cpp \
kernel/qgesture.cpp \
- kernel/qstandardgestures.cpp \
- kernel/qsoftkeymanager.cpp
+ kernel/qstandardgestures.cpp \
+ kernel/qgesturerecognizer.cpp \
+ kernel/qgesturemanager.cpp \
+ kernel/qsoftkeymanager.cpp \
+ kernel/qguiplatformplugin.cpp
win32 {
DEFINES += QT_NO_DIRECTDRAW
+ HEADERS += \
+ kernel/qwinnativepangesturerecognizer_win_p.h
+
SOURCES += \
kernel/qapplication_win.cpp \
kernel/qclipboard_win.cpp \
@@ -94,7 +102,8 @@ win32 {
kernel/qsound_win.cpp \
kernel/qwidget_win.cpp \
kernel/qole_win.cpp \
- kernel/qkeymapper_win.cpp
+ kernel/qkeymapper_win.cpp \
+ kernel/qwinnativepangesturerecognizer_win.cpp
!contains(DEFINES, QT_NO_DIRECTDRAW):LIBS += ddraw.lib
}
@@ -214,6 +223,7 @@ embedded_lite {
qcocoaview_mac_p.h \
qcocoaapplication_mac_p.h \
qcocoaapplicationdelegate_mac_p.h \
+ qmacgesturerecognizer_mac_p.h \
qmultitouch_mac_p.h
OBJECTIVE_SOURCES += \
@@ -233,7 +243,8 @@ embedded_lite {
kernel/qdesktopwidget_mac.mm \
kernel/qeventdispatcher_mac.mm \
kernel/qcocoawindowcustomthemeframe_mac.mm \
- kernel/qmultitouch_mac.mm \
+ kernel/qmacgesturerecognizer_mac.mm \
+ kernel/qmultitouch_mac.mm
HEADERS += \
kernel/qt_cocoa_helpers_mac_p.h \
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 77e6ea8..191cdf4 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -84,6 +84,8 @@
#include "qinputcontextfactory.h"
#endif
+#include "qguiplatformplugin_p.h"
+
#include <qthread.h>
#include <private/qthread_p.h>
@@ -97,6 +99,9 @@
#include "qapplication.h"
+#include "qgesture.h"
+#include "private/qgesturemanager_p.h"
+
#ifndef QT_NO_LIBRARY
#include "qlibrary.h"
#endif
@@ -152,6 +157,14 @@ 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)
{
@@ -175,6 +188,8 @@ QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::T
directPainters = 0;
#endif
+ gestureManager = 0;
+
if (!self)
self = this;
}
@@ -790,6 +805,9 @@ void QApplicationPrivate::construct(
qCritical("Library qttestability load failed!");
}
}
+
+ //make sure the plugin is loaded
+ qt_guiPlatformPlugin();
#endif
}
@@ -927,7 +945,7 @@ void QApplicationPrivate::initialize()
graphics_system = QGraphicsSystemFactory::create(graphics_system_name);
#endif
#ifndef QT_NO_WHEELEVENT
-#ifdef QT_MAC_USE_COCOA
+#ifdef Q_OS_MAC
QApplicationPrivate::wheel_scroll_lines = 1;
#else
QApplicationPrivate::wheel_scroll_lines = 3;
@@ -1018,11 +1036,11 @@ QApplication::~QApplication()
d->eventDispatcher->closingDown();
d->eventDispatcher = 0;
+ QApplicationPrivate::is_app_closing = true;
+ QApplicationPrivate::is_app_running = false;
delete qt_desktopWidget;
qt_desktopWidget = 0;
- QApplicationPrivate::is_app_closing = true;
- QApplicationPrivate::is_app_running = false;
#ifndef QT_NO_CLIPBOARD
delete qt_clipboard;
@@ -1957,38 +1975,7 @@ void QApplicationPrivate::setSystemFont(const QFont &font)
*/
QString QApplicationPrivate::desktopStyleKey()
{
-QString desktopstyle;
-#if defined(Q_WS_WIN) && defined(Q_WS_WINCE)
- if (qt_wince_is_smartphone() || qt_wince_is_pocket_pc())
- desktopstyle = QLatin1String("WindowsMobile");
- else
- desktopstyle = QLatin1String("WindowsCE");
-
-#elif defined(Q_WS_WIN)
- if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
- desktopstyle = QLatin1String("WindowsVista");
- else if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
- desktopstyle = QLatin1String("WindowsXP");
- else
- desktopstyle = QLatin1String("Windows"); // default styles for Windows
-#elif defined(Q_WS_X11) && defined(Q_OS_SOLARIS)
- desktopstyle = QLatin1String("CDE"); // default style for X11 on Solaris
-#elif defined(Q_WS_S60)
- desktopstyle = QLatin1String("S60"); // default style for Symbian with S60
-#elif defined(Q_OS_SYMBIAN)
- desktopstyle = QLatin1String("Windows"); // default style for Symbian without S60
-#elif defined(Q_WS_X11) && defined(Q_OS_IRIX)
- desktopstyle = QLatin1String("SGI"); // default style for X11 on IRIX
-#elif defined(Q_WS_QWS) || defined (Q_WS_LITE)
- desktopstyle = QLatin1String("Plastique"); // default style for X11 and small devices
-#elif defined(Q_WS_X11)
- desktopstyle = QApplicationPrivate::x11_desktop_style(); // default runtime dependant style for X11
-#elif defined(Q_WS_MAC)
- desktopstyle = QLatin1String("Macintosh"); // default style for all Mac's
-#endif
- return desktopstyle;
+ return qt_guiPlatformPlugin()->styleName();
}
/*!
@@ -3073,7 +3060,7 @@ void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
qt_button_down = 0;
// Send enter/leave events followed by a mouse move on the entered widget.
- QMouseEvent e(QEvent::MouseMove, pos, globalPos, Qt::NoButton, mouse_buttons, modifier_buttons);
+ QMouseEvent e(QEvent::MouseMove, pos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver);
#endif // QT_NO_CURSOR
}
@@ -3660,6 +3647,13 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
#endif // !QT_NO_WHEELEVENT || !QT_NO_TABLETEVENT
}
+ // walk through parents and check for gestures
+ if (d->gestureManager) {
+ if (d->gestureManager->filterEvent(receiver, e))
+ return true;
+ }
+
+
// User input and window activation makes tooltips sleep
switch (e->type()) {
case QEvent::Wheel:
@@ -4161,6 +4155,65 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
}
break;
}
+ case QEvent::Gesture:
+ case QEvent::GestureOverride:
+ {
+ if (receiver->isWidgetType()) {
+ QWidget *w = static_cast<QWidget *>(receiver);
+ QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(e);
+ QList<QGesture *> allGestures = gestureEvent->allGestures();
+
+ bool eventAccepted = gestureEvent->isAccepted();
+ bool wasAccepted = eventAccepted;
+ while (w) {
+ // send only gestures the widget expects
+ QList<QGesture *> gestures;
+ QWidgetPrivate *wd = w->d_func();
+ for (int i = 0; i < allGestures.size();) {
+ QGesture *g = allGestures.at(i);
+ Qt::GestureType type = g->gestureType();
+ if (wd->gestureContext.contains(type)) {
+ allGestures.removeAt(i);
+ gestures.append(g);
+ gestureEvent->setAccepted(g, false);
+ } else {
+ ++i;
+ }
+ }
+ if (!gestures.isEmpty()) {
+ QGestureEvent ge(gestures);
+ ge.t = gestureEvent->t;
+ ge.spont = gestureEvent->spont;
+ ge.m_accept = wasAccepted;
+ res = d->notify_helper(w, &ge);
+ gestureEvent->spont = false;
+ eventAccepted = ge.isAccepted();
+ if (res && eventAccepted)
+ break;
+ if (!eventAccepted) {
+ // ### two ways to ignore the event/gesture
+
+ // if the whole event wasn't accepted, put back those
+ // gestures that were not accepted.
+ for (int i = 0; i < gestures.size(); ++i) {
+ QGesture *g = gestures.at(i);
+ if (!ge.isAccepted(g))
+ allGestures.append(g);
+ }
+ }
+ }
+ if (allGestures.isEmpty())
+ break;
+ if (w->isWindow())
+ break;
+ w = w->parentWidget();
+ }
+ gestureEvent->m_accept = eventAccepted;
+ } else {
+ res = d->notify_helper(receiver, e);
+ }
+ break;
+ }
default:
res = d->notify_helper(receiver, e);
break;
@@ -5568,6 +5621,37 @@ 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)
+{
+ QGestureManager::instance()->unregisterGestureRecognizer(type);
+}
+
QT_END_NAMESPACE
#include "moc_qapplication.cpp"
diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h
index 5f21a56..12b398d 100644
--- a/src/gui/kernel/qapplication.h
+++ b/src/gui/kernel/qapplication.h
@@ -86,6 +86,7 @@ class QDecoration;
class QApplication;
class QApplicationPrivate;
+class QGestureRecognizer;
#if defined(qApp)
#undef qApp
#endif
@@ -289,6 +290,9 @@ public:
static Qt::NavigationMode navigationMode();
#endif
+ Qt::GestureType registerGestureRecognizer(QGestureRecognizer *recognizer);
+ void unregisterGestureRecognizer(Qt::GestureType type);
+
Q_SIGNALS:
void lastWindowClosed();
void focusChanged(QWidget *old, QWidget *now);
@@ -400,6 +404,7 @@ private:
friend class QDirectPainter;
friend class QDirectPainterPrivate;
#endif
+ friend class QGestureManager;
#if defined(Q_WS_MAC) || defined(Q_WS_X11)
Q_PRIVATE_SLOT(d_func(), void _q_alertTimeOut())
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index c294e62..f9c8aa3 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -1686,13 +1686,15 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
// (actually two events; one for horizontal and one for vertical).
// As a results of this, and to make sure we dont't receive duplicate events,
// we try to detect when this happend by checking the 'compatibilityEvent'.
+ const int scrollFactor = 4 * 8;
SInt32 mdelt = 0;
GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
- wheel_deltaX = mdelt;
+ wheel_deltaX = mdelt * scrollFactor;
+ mdelt = 0;
GetEventParameter(event, kEventParamMouseWheelSmoothVerticalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
- wheel_deltaY = mdelt;
+ wheel_deltaY = mdelt * scrollFactor;
GetEventParameter(event, kEventParamEventRef, typeEventRef, 0,
sizeof(compatibilityEvent), 0, &compatibilityEvent);
} else if (ekind == kEventMouseWheelMoved) {
@@ -1704,10 +1706,32 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
EventMouseWheelAxis axis;
GetEventParameter(event, kEventParamMouseWheelAxis, typeMouseWheelAxis, 0,
sizeof(axis), 0, &axis);
+
+ // The 'new' event has acceleration applied by the OS, while the old (on
+ // Carbon only), has not. So we introduce acceleration here to be consistent.
+ // The acceleration is trying to respect both pixel based and line scrolling,
+ // which turns out to be rather difficult.
+ int linesToScroll = mdelt > 0 ? 1 : -1;
+ static QTime t;
+ int elapsed = t.elapsed();
+ t.restart();
+ if (elapsed < 20)
+ linesToScroll *= 120;
+ else if (elapsed < 30)
+ linesToScroll *= 60;
+ else if (elapsed < 50)
+ linesToScroll *= 30;
+ else if (elapsed < 100)
+ linesToScroll *= 6;
+ else if (elapsed < 200)
+ linesToScroll *= 3;
+ else if (elapsed < 300)
+ linesToScroll *= 2;
+
if (axis == kEventMouseWheelAxisX)
- wheel_deltaX = mdelt * 120;
+ wheel_deltaX = linesToScroll * 120;
else
- wheel_deltaY = mdelt * 120;
+ wheel_deltaY = linesToScroll * 120;
}
}
@@ -2660,7 +2684,11 @@ int QApplication::keyboardInputInterval()
void QApplication::setWheelScrollLines(int n)
{
- QApplicationPrivate::wheel_scroll_lines = n;
+ Q_UNUSED(n);
+ // On Mac, acceleration is handled by the OS. Multiplying wheel scroll
+ // deltas with n will not be as cross platform as one might think! So
+ // we choose to go native in this case (and let wheel_scroll_lines == 1).
+ // QApplicationPrivate::wheel_scroll_lines = n;
}
int QApplication::wheelScrollLines()
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index 32004ba..52d0642 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -83,8 +83,8 @@ class QGraphicsSystem;
class QInputContext;
class QObject;
class QWidget;
-class QGestureManager;
class QSocketNotifier;
+class QGestureManager;
extern bool qt_is_gui_used;
#ifndef QT_NO_CLIPBOARD
@@ -265,20 +265,6 @@ typedef struct tagGESTURECONFIG
#endif // Q_WS_WIN
-class QPanGesture;
-class QPinchGesture;
-class QSwipeGesture;
-
-struct QStandardGestures
-{
- QPanGesture *pan;
- QPinchGesture *pinch;
- QSwipeGesture *swipe;
-
- QStandardGestures() : pan(0), pinch(0), swipe(0) { }
-};
-
-
class QScopedLoopLevelCounter
{
QThreadData *threadData;
@@ -305,7 +291,6 @@ public:
#if defined(Q_WS_X11)
#ifndef QT_NO_SETTINGS
- static QString x11_desktop_style();
static bool x11_apply_settings();
#endif
static void reset_instance_pointer();
@@ -523,6 +508,8 @@ public:
void sendSyntheticEnterLeave(QWidget *widget);
#endif
+ QGestureManager *gestureManager;
+
QMap<int, QWidget *> widgetForTouchPointId;
QMap<int, QTouchEvent::TouchPoint> appCurrentTouchPoints;
static void updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent);
@@ -537,9 +524,6 @@ public:
QTouchEvent::DeviceType deviceType,
const QList<QTouchEvent::TouchPoint> &touchPoints);
- typedef QMap<QWidget*, QStandardGestures> WidgetStandardGesturesMap;
- WidgetStandardGesturesMap widgetGestures;
-
#if defined(Q_WS_WIN)
static PtrRegisterTouchWindow RegisterTouchWindow;
static PtrGetTouchInputInfo GetTouchInputInfo;
@@ -556,7 +540,6 @@ public:
PtrBeginPanningFeedback BeginPanningFeedback;
PtrUpdatePanningFeedback UpdatePanningFeedback;
PtrEndPanningFeedback EndPanningFeedback;
- QWidget *gestureWidget;
#endif
#ifdef QT_RX71_MULTITOUCH
diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp
index e9284f7..167beb2 100644
--- a/src/gui/kernel/qapplication_qws.cpp
+++ b/src/gui/kernel/qapplication_qws.cpp
@@ -110,6 +110,8 @@
#include <sys/stat.h>
#include <sys/types.h>
+#include <qvfbhdr.h>
+
#ifndef QT_NO_QWS_MULTIPROCESS
#ifdef QT_NO_QSHM
#include <sys/ipc.h>
@@ -199,14 +201,9 @@ QString qws_dataDir()
static QString result;
if (!result.isEmpty())
return result;
- QByteArray dataDir;
-#ifdef QT_QWS_TEMP_DIR
- dataDir = QT_QWS_TEMP_DIR;
-#else
- dataDir = "/tmp";
-#endif
- dataDir += "/qtembedded-";
- dataDir += QByteArray::number(qws_display_id);
+ result = QT_VFB_DATADIR(qws_display_id);
+ QByteArray dataDir = result.toLocal8Bit();
+
if (QT_MKDIR(dataDir, 0700)) {
if (errno != EEXIST) {
qFatal("Cannot create Qt for Embedded Linux data directory: %s", dataDir.constData());
@@ -227,16 +224,16 @@ QString qws_dataDir()
if ((buf.st_mode & 0677) != 0600)
qFatal("Qt for Embedded Linux data directory has incorrect permissions: %s", dataDir.constData());
#endif
- dataDir += '/';
- result = QString::fromLocal8Bit(dataDir);
+ result.append("/");
return result;
}
// Get the filename of the pipe Qt for Embedded Linux uses for server/client comms
Q_GUI_EXPORT QString qws_qtePipeFilename()
{
- return (qws_dataDir() + QString::fromLatin1(QTE_PIPE).arg(qws_display_id));
+ qws_dataDir();
+ return QTE_PIPE(qws_display_id);
}
static void setMaxWindowRect(const QRect &rect)
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 992e754..6d50e55 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -91,6 +91,8 @@ extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
QWidget *qt_button_down = 0; // widget got last button-down
+QSymbianControl *QSymbianControl::lastFocusedControl = 0;
+
QS60Data* qGlobalS60Data()
{
return qt_s60Data();
@@ -350,6 +352,8 @@ QSymbianControl::~QSymbianControl()
{
if (S60->curWin == this)
S60->curWin = 0;
+ if (!QApplicationPrivate::is_app_closing)
+ setFocusSafely(false);
S60->appUi()->RemoveFromStack(this);
delete m_longTapDetector;
}
@@ -685,7 +689,7 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod
Qt::KeyboardModifiers mods = mapToQtModifiers(keyEvent.iModifiers);
QKeyEventEx qKeyEvent(type == EEventKeyUp ? QEvent::KeyRelease : QEvent::KeyPress, keyCode,
mods, qt_keymapper_private()->translateKeyEvent(keyCode, mods),
- false, 1, keyEvent.iScanCode, s60Keysym, mods);
+ false, 1, keyEvent.iScanCode, s60Keysym, keyEvent.iModifiers);
// WId wid = reinterpret_cast<RWindowGroup *>(keyEvent.Handle())->Child();
// if (!wid)
// Could happen if window isn't shown yet.
@@ -777,7 +781,7 @@ TCoeInputCapabilities QSymbianControl::InputCapabilities() const
}
#endif
-void QSymbianControl::Draw(const TRect& r) const
+void QSymbianControl::Draw(const TRect& controlRect) const
{
QWindowSurface *surface = qwidget->windowSurface();
QPaintEngine *engine = surface ? surface->paintDevice()->paintEngine() : NULL;
@@ -785,6 +789,11 @@ void QSymbianControl::Draw(const TRect& r) const
if (!engine)
return;
+ // Map source rectangle into coordinates of the backing store.
+ const QPoint controlBase(controlRect.iTl.iX, controlRect.iTl.iY);
+ const QPoint backingStoreBase = qwidget->mapTo(qwidget->window(), controlBase);
+ const TRect backingStoreRect(TPoint(backingStoreBase.x(), backingStoreBase.y()), controlRect.Size());
+
if (engine->type() == QPaintEngine::Raster) {
QS60WindowSurface *s60Surface = static_cast<QS60WindowSurface *>(qwidget->windowSurface());
CFbsBitmap *bitmap = s60Surface->symbianBitmap();
@@ -793,10 +802,10 @@ void QSymbianControl::Draw(const TRect& r) const
if(!qwidget->d_func()->extraData()->disableBlit) {
if (qwidget->d_func()->isOpaque)
gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
- gc.BitBlt(r.iTl, bitmap, r);
- }
+ gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect);
+ }
} else {
- surface->flush(qwidget, QRegion(qt_TRect2QRect(r)), QPoint());
+ surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint());
}
}
@@ -860,8 +869,23 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
|| (qwidget->windowType() & Qt::Popup) == Qt::Popup)
return;
- QEvent *deferredFocusEvent = new QEvent(QEvent::SymbianDeferredFocusChanged);
- QApplication::postEvent(qwidget, deferredFocusEvent);
+ if (IsFocused() && IsVisible()) {
+ QApplication::setActiveWindow(qwidget->window());
+#ifdef Q_WS_S60
+ // If widget is fullscreen, hide status pane and button container
+ // otherwise show them.
+ CEikStatusPane* statusPane = S60->statusPane();
+ CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
+ bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
+ if (statusPane && (statusPane->IsVisible() == isFullscreen))
+ statusPane->MakeVisible(!isFullscreen);
+ if (buttonGroup && (buttonGroup->IsVisible() == isFullscreen))
+ buttonGroup->MakeVisible(!isFullscreen);
+#endif
+ } else if (QApplication::activeWindow() == qwidget->window()) {
+ QApplication::setActiveWindow(0);
+ }
+ // else { We don't touch the active window unless we were explicitly activated or deactivated }
}
void QSymbianControl::HandleResourceChange(int resourceType)
@@ -905,15 +929,42 @@ TTypeUid::Ptr QSymbianControl::MopSupplyObject(TTypeUid id)
return CCoeControl::MopSupplyObject(id);
}
+void QSymbianControl::setFocusSafely(bool focus)
+{
+ // The stack hack in here is very unfortunate, but it is the only way to ensure proper
+ // focus in Symbian. If this is not executed, the control which happens to be on
+ // the top of the stack may randomly be assigned focus by Symbian, for example
+ // when creating new windows (specifically in CCoeAppUi::HandleStackChanged()).
+ if (focus) {
+ S60->appUi()->RemoveFromStack(this);
+ // Symbian doesn't automatically remove focus from the last focused control, so we need to
+ // remember it and clear focus ourselves.
+ if (lastFocusedControl && lastFocusedControl != this)
+ lastFocusedControl->SetFocus(false);
+ QT_TRAP_THROWING(S60->appUi()->AddToStackL(this,
+ ECoeStackPriorityDefault + 1, ECoeStackFlagStandard)); // Note the + 1
+ lastFocusedControl = this;
+ this->SetFocus(true);
+ } else {
+ S60->appUi()->RemoveFromStack(this);
+ QT_TRAP_THROWING(S60->appUi()->AddToStackL(this,
+ ECoeStackPriorityDefault, ECoeStackFlagStandard));
+ if(this == lastFocusedControl)
+ lastFocusedControl = 0;
+ this->SetFocus(false);
+ }
+}
+
/*!
\typedef QApplication::QS60MainApplicationFactory
+ \since 4.6
This is a typedef for a pointer to a function with the following
signature:
\snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 47
- \sa QApplication::QApplication(QApplication::QS60MainApplicationFactory, int &, char **)
+ \sa QApplication::QApplication()
*/
/*!
@@ -983,6 +1034,11 @@ void qt_init(QApplicationPrivate * /* priv */, int)
//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.
+ static const bool touchIsUnsupportedOnSystem =
+ QSysInfo::s60Version() == QSysInfo::SV_S60_3_1
+ || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2;
TInt machineUID;
TInt mouse;
TInt touch;
@@ -994,7 +1050,7 @@ void qt_init(QApplicationPrivate * /* priv */, int)
if (err != KErrNone)
machineUID = 0;
err = HAL::Get(HALData::EPen, touch);
- if (err != KErrNone)
+ if (err != KErrNone || touchIsUnsupportedOnSystem)
touch = 0;
if (mouse || machineUID == KMachineUidSamsungI8510) {
S60->hasTouchscreen = false;
@@ -1042,6 +1098,10 @@ void qt_init(QApplicationPrivate * /* priv */, int)
}
#endif
+ QFont systemFont;
+ systemFont.setFamily(systemFont.defaultFamily());
+ QApplicationPrivate::setSystemFont(systemFont);
+
/*
### Commented out for now as parameter handling not needed in SOS(yet). Code below will break testlib with -o flag
int argc = priv->argc;
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 6ecd535..5bb25fa 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -92,8 +92,6 @@ extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.c
#include <private/qkeymapper_p.h>
#include <private/qlocale_p.h>
#include "qevent_p.h"
-#include "qstandardgestures.h"
-#include "qstandardgestures_p.h"
//#define ALIEN_DEBUG
@@ -171,10 +169,13 @@ typedef struct tagTOUCHINPUT
#include <mywinsock.h>
#endif
+#ifndef IMR_RECONVERTSTRING
+#define IMR_RECONVERTSTRING 4
+#endif
+
#ifndef IMR_CONFIRMRECONVERTSTRING
#define IMR_CONFIRMRECONVERTSTRING 0x0005
#endif
-
QT_BEGIN_NAMESPACE
#ifdef Q_WS_WINCE
@@ -818,13 +819,16 @@ void qt_init(QApplicationPrivate *priv, int)
priv->GetGestureInfo = 0;
priv->GetGestureExtraArgs = 0;
+ priv->CloseGestureInfoHandle = 0;
+ priv->SetGestureConfig = 0;
+ priv->GetGestureConfig = 0;
+ priv->BeginPanningFeedback = 0;
+ priv->UpdatePanningFeedback = 0;
+ priv->EndPanningFeedback = 0;
#if defined(Q_WS_WINCE_WM) && defined(QT_WINCE_GESTURES)
priv->GetGestureInfo = (PtrGetGestureInfo) &TKGetGestureInfo;
priv->GetGestureExtraArgs = (PtrGetGestureExtraArgs) &TKGetGestureExtraArguments;
- priv->CloseGestureInfoHandle = (PtrCloseGestureInfoHandle) 0;
- priv->SetGestureConfig = (PtrSetGestureConfig) 0;
- priv->GetGestureConfig = (PtrGetGestureConfig) 0;
#elif !defined(Q_WS_WINCE)
priv->GetGestureInfo =
(PtrGetGestureInfo)QLibrary::resolve(QLatin1String("user32"),
@@ -851,7 +855,6 @@ void qt_init(QApplicationPrivate *priv, int)
(PtrEndPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"),
"EndPanningFeedback");
#endif
- priv->gestureWidget = 0;
}
/*****************************************************************************
@@ -1752,79 +1755,18 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
case APPCOMMAND_BASS_UP:
key = Qt::Key_BassUp;
break;
- case APPCOMMAND_BROWSER_BACKWARD:
- key = Qt::Key_Back;
- break;
- case APPCOMMAND_BROWSER_FAVORITES:
- key = Qt::Key_Favorites;
- break;
- case APPCOMMAND_BROWSER_FORWARD:
- key = Qt::Key_Forward;
- break;
- case APPCOMMAND_BROWSER_HOME:
- key = Qt::Key_HomePage;
- break;
- case APPCOMMAND_BROWSER_REFRESH:
- key = Qt::Key_Refresh;
- break;
- case APPCOMMAND_BROWSER_SEARCH:
- key = Qt::Key_Search;
- break;
- case APPCOMMAND_BROWSER_STOP:
- key = Qt::Key_Stop;
- break;
- case APPCOMMAND_LAUNCH_APP1:
- key = Qt::Key_Launch0;
- break;
- case APPCOMMAND_LAUNCH_APP2:
- key = Qt::Key_Launch1;
- break;
- case APPCOMMAND_LAUNCH_MAIL:
- key = Qt::Key_LaunchMail;
- break;
- case APPCOMMAND_LAUNCH_MEDIA_SELECT:
- key = Qt::Key_LaunchMedia;
- break;
- case APPCOMMAND_MEDIA_NEXTTRACK:
- key = Qt::Key_MediaNext;
- break;
- case APPCOMMAND_MEDIA_PLAY_PAUSE:
- key = Qt::Key_MediaPlay;
- break;
- case APPCOMMAND_MEDIA_PREVIOUSTRACK:
- key = Qt::Key_MediaPrevious;
- break;
- case APPCOMMAND_MEDIA_STOP:
- key = Qt::Key_MediaStop;
- break;
case APPCOMMAND_TREBLE_DOWN:
key = Qt::Key_TrebleDown;
break;
case APPCOMMAND_TREBLE_UP:
key = Qt::Key_TrebleUp;
break;
- case APPCOMMAND_VOLUME_DOWN:
- key = Qt::Key_VolumeDown;
- break;
- case APPCOMMAND_VOLUME_MUTE:
- key = Qt::Key_VolumeMute;
- break;
- case APPCOMMAND_VOLUME_UP:
- key = Qt::Key_VolumeUp;
- break;
- // Commands new in Windows XP
case APPCOMMAND_HELP:
key = Qt::Key_Help;
break;
case APPCOMMAND_FIND:
key = Qt::Key_Search;
break;
- case APPCOMMAND_PRINT:
- key = Qt::Key_Print;
- break;
- case APPCOMMAND_MEDIA_PLAY:
- key = Qt::Key_MediaPlay;
- break;
default:
break;
}
@@ -2028,13 +1970,22 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
// where it got it from; it would simply get a 0 value as the old focus widget.
#ifdef Q_WS_WINCE
{
- if (widget->windowState() & Qt::WindowMinimized) {
- if (widget->windowState() & Qt::WindowMaximized)
- widget->showMaximized();
- else
- widget->show();
+#ifdef Q_WS_WINCE_WM
+ // On Windows mobile we do not receive WM_SYSCOMMAND / SC_MINIMIZE messages.
+ // Thus we have to unset the minimized state explicitly. We must do this for all
+ // top-level widgets, because we get the HWND of a random widget here.
+ foreach (QWidget* tlw, QApplication::topLevelWidgets()) {
+ if (tlw->isMinimized())
+ tlw->setWindowState(tlw->windowState() & ~Qt::WindowMinimized);
}
#else
+ // On Windows CE we do not receive WM_SYSCOMMAND / SC_MINIMIZE messages.
+ // Thus we have to unset the minimized state explicitly.
+ if (widget->windowState() & Qt::WindowMinimized)
+ widget->setWindowState(widget->windowState() & ~Qt::WindowMinimized);
+#endif // Q_WS_WINCE_WM
+
+#else
if (!(widget->windowState() & Qt::WindowMinimized)) {
#endif
// Ignore the activate message send by WindowsXP to a minimized window
@@ -2548,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/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index bbce438..bf95684 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -85,6 +85,7 @@
#include "qtimer.h"
#include "qlibrary.h"
#include <private/qgraphicssystemfactory_p.h>
+#include "qguiplatformplugin_p.h"
#include "qkde_p.h"
#if !defined (QT_NO_TABLET)
@@ -919,7 +920,7 @@ bool QApplicationPrivate::x11_apply_settings()
QString stylename = settings.value(QLatin1String("style")).toString();
if (stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull() && X11->use_xrender) {
- stylename = x11_desktop_style();
+ stylename = qt_guiPlatformPlugin()->styleName();
}
static QString currentStyleName = stylename;
@@ -1313,8 +1314,7 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0,
pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue);
}
- if (kdeColors)
- pal = QKde::kdePalette().resolve(pal);
+ pal = qt_guiPlatformPlugin()->palette().resolve(pal);
QApplicationPrivate::setSystemPalette(pal);
QColor::setAllowX11ColorNames(allowX11ColorNames);
}
@@ -2256,8 +2256,13 @@ void qt_init(QApplicationPrivate *priv, int,
unsigned long length, after;
uchar *data = 0;
- if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING),
- 0, 1, False, AnyPropertyType, &type, &format, &length,
+ QString session = QString::fromLocal8Bit(qgetenv("DESKTOP_SESSION"));
+ if (session == QLatin1String("kde")) {
+ X11->desktopEnvironment = DE_KDE;
+ } else if (session == QLatin1String("gnome") || session == QLatin1String("xfce")) {
+ X11->desktopEnvironment = DE_GNOME;
+ } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING),
+ 0, 1, False, AnyPropertyType, &type, &format, &length,
&after, &data) == Success && length) {
// DTWM is running, meaning most likely CDE is running...
X11->desktopEnvironment = DE_CDE;
@@ -2555,42 +2560,6 @@ void qt_init(QApplicationPrivate *priv, int,
#endif
}
-
- // run-time search for default style
-/*!
- \internal
-*/
-QString QApplicationPrivate::x11_desktop_style()
-{
- QString stylename;
- switch(X11->desktopEnvironment) {
- case DE_KDE:
- stylename = QKde::kdeStyle();
- break;
- case DE_GNOME: {
- QStringList availableStyles = QStyleFactory::keys();
- // Set QGtkStyle for GNOME if available
- QString gtkStyleKey = QString::fromLatin1("GTK+");
- if (availableStyles.contains(gtkStyleKey)) {
- stylename = gtkStyleKey;
- break;
- }
- if (X11->use_xrender)
- stylename = QLatin1String("cleanlooks");
- else
- stylename = QLatin1String("windows");
- break;
- }
- case DE_CDE:
- stylename = QLatin1String("cde");
- break;
- default:
- // Don't do anything
- break;
- }
- return stylename;
-}
-
void QApplicationPrivate::initializeWidgetPaletteHash()
{
}
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index f482d1c..b1c5fc5 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -789,18 +789,22 @@ extern "C" {
const EventRef carbonEvent = (EventRef)[theEvent eventRef];
const UInt32 carbonEventKind = carbonEvent ? ::GetEventKind(carbonEvent) : 0;
if (carbonEventKind == kEventMouseScroll) {
- // The mouse device containts pixel scroll
- // wheel support (Mighty Mouse, Trackpad)
- deltaX = (int)[theEvent deviceDeltaX] * 120;
- deltaY = (int)[theEvent deviceDeltaY] * 120;
- deltaZ = (int)[theEvent deviceDeltaZ] * 120;
+ // The mouse device containts pixel scroll wheel support (Mighty Mouse, Trackpad).
+ // Since deviceDelta is delivered as pixels rather than degrees, we need to
+ // convert from pixels to degrees in a sensible manner.
+ // It looks like four degrees per pixel behaves most native.
+ // Qt expects the unit for delta to be 1/8 of a degree:
+ const int scrollFactor = 4 * 8;
+ deltaX = (int)[theEvent deviceDeltaX] * scrollFactor;
+ deltaY = (int)[theEvent deviceDeltaY] * scrollFactor;
+ deltaZ = (int)[theEvent deviceDeltaZ] * scrollFactor;
} else { // carbonEventKind == kEventMouseWheelMoved
// Mouse wheel deltas seem to tick in at increments of 0.1.
// Qt widgets expect the delta to be a multiple of 120.
const int scrollFactor = 10 * 120;
- deltaX = [theEvent deltaX] * scrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaX]));
- deltaY = [theEvent deltaY] * scrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaY]));
- deltaZ = [theEvent deltaZ] * scrollFactor * qMax(0.6, 1.1 - qAbs([theEvent deltaZ]));
+ deltaX = [theEvent deltaX] * scrollFactor;
+ deltaY = [theEvent deltaY] * scrollFactor;
+ deltaZ = [theEvent deltaZ] * scrollFactor;
}
if (deltaX != 0) {
diff --git a/src/gui/kernel/qcursor_s60.cpp b/src/gui/kernel/qcursor_s60.cpp
index 0d8283d..7f5c32a 100644
--- a/src/gui/kernel/qcursor_s60.cpp
+++ b/src/gui/kernel/qcursor_s60.cpp
@@ -110,7 +110,7 @@ void qt_symbian_set_cursor_visible(bool visible) {
else
cursorSpriteVisible--;
Q_ASSERT(cursorSpriteVisible >=0);
-
+
if (cursorSpriteVisible && !S60->mouseInteractionEnabled) {
#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
if (S60->brokenPointerCursors)
@@ -119,7 +119,7 @@ void qt_symbian_set_cursor_visible(bool visible) {
#endif
S60->wsSession().SetPointerCursorMode(EPointerCursorNormal);
} else if (!cursorSpriteVisible && S60->mouseInteractionEnabled) {
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
+#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
if (S60->brokenPointerCursors)
qt_symbian_hide_pointer_sprite();
else
@@ -188,7 +188,7 @@ Qt::HANDLE QCursor::handle() const
return reinterpret_cast<Qt::HANDLE> (&(d->pcurs));
#ifdef Q_SYMBIAN_HAS_SYSTEM_CURSORS
- // don't construct shape cursors, QApplication_s60 will use the system cursor instead
+ // don't construct shape cursors, QApplication_s60 will use the system cursor instead
if (!(d->bm))
return 0;
#endif
@@ -228,12 +228,12 @@ void QCursorData::loadShapeFromResource(RWsSpriteBase& target, QString resource,
/*
* Constructs the native cursor from resources compiled into QtGui
* This is needed only when the platform doesn't have system cursors.
- *
+ *
* System cursors are higher performance, since they are constructed once
* and shared by all applications by specifying the shape number.
* Due to symbian platform security considerations, and the fact most
* existing phones have a broken RWsPointerCursor, system cursors are not
- * being used.
+ * being used.
*/
void QCursorData::constructShapeSprite(RWsSpriteBase& target)
{
@@ -346,7 +346,7 @@ void QCursorData::constructCursorSprite(RWsSpriteBase& target)
member->iMaskBitmap = pixmap.mask().toSymbianCFbsBitmap();
}
else {
- member->iMaskBitmap = pixmap.createHeuristicMask().toSymbianCFbsBitmap();
+ member->iMaskBitmap = 0; //opaque rectangle cursor (due to EDrawModePEN)
}
}
@@ -371,11 +371,11 @@ void qt_symbian_show_pointer_sprite()
} else {
cursorSprite = QCursor(Qt::ArrowCursor);
}
-
+
cursorSprite.d->scurs = RWsSprite(S60->wsSession());
QPoint pos = QCursor::pos();
cursorSprite.d->scurs.Construct(S60->windowGroup(), TPoint(pos.x(), pos.y()), ESpriteNoChildClip | ESpriteNoShadows);
-
+
cursorSprite.d->constructCursorSprite(cursorSprite.d->scurs);
cursorSprite.d->scurs.Activate();
}
@@ -409,7 +409,7 @@ void qt_symbian_set_pointer_sprite(const QCursor& cursor)
* RWsPointerCursor, this function is called in response to pointer events
* and when QCursor::setPos() is called.
* Performance is worse than a real pointer cursor, due to extra context
- * switches vs. the window server moving the cursor by itself.
+ * switches vs. the window server moving the cursor by itself.
*/
void qt_symbian_move_cursor_sprite()
{
@@ -421,7 +421,7 @@ void qt_symbian_move_cursor_sprite()
/*
* Translate from Qt::CursorShape to OS system pointer cursor list index.
* Currently we control the implementation of the system pointer cursor list,
- * so this function is trivial. That may not always be the case.
+ * so this function is trivial. That may not always be the case.
*/
TInt qt_symbian_translate_cursor_shape(Qt::CursorShape shape)
{
@@ -462,7 +462,7 @@ void qt_symbian_set_cursor(QWidget *w, bool force)
/*
* Makes the specified cursor appear above a specific native window group
* Called from QSymbianControl and QApplication::restoreOverrideCursor
- *
+ *
* Window server is needed for this, so there is no equivalent when using
* the sprite workaround.
*/
@@ -486,7 +486,7 @@ void qt_symbian_setWindowGroupCursor(const QCursor &cursor, RWindowTreeNode &nod
/*
* Makes the specified cursor appear above a specific native window
* Called from QSymbianControl and QApplication::restoreOverrideCursor
- *
+ *
* Window server is needed for this, so there is no equivalent when using
* the sprite workaround.
*/
diff --git a/src/gui/kernel/qdnd_s60.cpp b/src/gui/kernel/qdnd_s60.cpp
index 3d6ecd2..a8d3ac5 100644
--- a/src/gui/kernel/qdnd_s60.cpp
+++ b/src/gui/kernel/qdnd_s60.cpp
@@ -277,7 +277,7 @@ Qt::DropAction QDragManager::drag(QDrag *o)
qApp->installEventFilter(this);
- global_accepted_action = Qt::MoveAction;
+ global_accepted_action = defaultAction(dragPrivate()->possible_actions, Qt::NoModifier);
qt_symbian_dnd_dragging = true;
eventLoop = new QEventLoop;
@@ -288,7 +288,7 @@ Qt::DropAction QDragManager::drag(QDrag *o)
#ifndef QT_NO_CURSOR
qt_symbian_set_cursor_visible(false);
-
+
overrideCursor = QCursor(); //deref the cursor data
qt_symbian_dnd_dragging = false;
#endif
diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp
index 33da0f3..da150fb 100644
--- a/src/gui/kernel/qdnd_x11.cpp
+++ b/src/gui/kernel/qdnd_x11.cpp
@@ -506,6 +506,7 @@ bool QX11Data::xdndMimeDataForAtom(Atom a, QMimeData *mimeData, QByteArray *data
*atomFormat = textprop.encoding;
*dataFormat = textprop.format;
*data = QByteArray((const char *) textprop.value, textprop.nitems * textprop.format / 8);
+ ret = true;
DEBUG(" textprop type %lx\n"
" textprop name '%s'\n"
@@ -541,12 +542,13 @@ bool QX11Data::xdndMimeDataForAtom(Atom a, QMimeData *mimeData, QByteArray *data
dm->xdndMimeTransferedPixmap[dm->xdndMimeTransferedPixmapIndex] = pm;
dm->xdndMimeTransferedPixmapIndex =
(dm->xdndMimeTransferedPixmapIndex + 1) % 2;
+ ret = true;
}
} else {
DEBUG("QClipboard: xdndMimeDataForAtom(): converting to type '%s' is not supported", qPrintable(atomName));
}
}
- return data;
+ return ret && data != 0;
}
//$$$
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index ce64c68..4826704 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -49,6 +49,8 @@
#include "qmime.h"
#include "qdnd_p.h"
#include "qevent_p.h"
+#include "qgesture.h"
+#include "qgesture_p.h"
QT_BEGIN_NAMESPACE
@@ -3357,6 +3359,9 @@ QDebug operator<<(QDebug dbg, const QEvent *e) {
case QEvent::ChildRemoved: n = n ? n : "ChildRemoved";
dbg.nospace() << "QChildEvent(" << n << ", " << (static_cast<const QChildEvent*>(e))->child();
return dbg.space();
+ case QEvent::Gesture:
+ n = "Gesture";
+ break;
default:
dbg.nospace() << "QEvent(" << (const void *)e << ", type = " << e->type() << ')';
return dbg.space();
@@ -3566,7 +3571,7 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar)
Qt::WA_AcceptTouchEvents attribute set and graphics items need to have the
\l{QGraphicsItem::setAcceptTouchEvents()}{acceptTouchEvents} attribute set to true.
- When using QAbstractScrollArea based widgets, you should enabled the Qt::WA_AcceptTouchEvents
+ When using QAbstractScrollArea based widgets, you should enable the Qt::WA_AcceptTouchEvents
attribute on the scroll area's \l{QAbstractScrollArea::viewport()}{viewport}.
Similarly to QMouseEvent, Qt automatically grabs each touch point on the first press inside a
@@ -4186,4 +4191,129 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T
return *this;
}
+/*!
+ \class QGestureEvent
+ \since 4.6
+ \ingroup events
+
+ \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.
+
+ 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
+ were previously active and have been canceled can be accessed using the
+ canceledGestures() function. A gesture might be canceled if the current window loses
+ 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.
+
+ \sa QGesture, QGestureRecognizer,
+ QWidget::grabGesture(), QGraphicsObject::grabGesture()
+*/
+
+/*!
+ Creates new QGestureEvent containing a list of \a gestures.
+*/
+QGestureEvent::QGestureEvent(const QList<QGesture *> &gestures)
+ : QEvent(QEvent::Gesture), gestures_(gestures)
+{
+}
+
+/*!
+ Returns all gestures that are delivered in the event.
+*/
+QList<QGesture *> QGestureEvent::allGestures() const
+{
+ return gestures_;
+}
+
+/*!
+ Returns a gesture object by \a type.
+*/
+QGesture *QGestureEvent::gesture(Qt::GestureType type) const
+{
+ for(int i = 0; i < gestures_.size(); ++i)
+ if (gestures_.at(i)->gestureType() == type)
+ return gestures_.at(i);
+ return 0;
+}
+
+/*!
+ Returns a list of active (not canceled) gestures.
+*/
+QList<QGesture *> QGestureEvent::activeGestures() const
+{
+ return gestures_;
+}
+
+/*!
+ Returns a list of canceled gestures.
+*/
+QList<QGesture *> QGestureEvent::canceledGestures() const
+{
+ return gestures_;
+}
+
+/*!
+ Sets the accept flag of the given \a gesture 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.
+
+ By default, gestures in events of type QEvent::Gesture are accepted, and
+ gestures in QEvent::GestureOverride events are ignored.
+
+ For convenience, the accept flag can also be set with
+ \l{QGestureEvent::accept()}{accept(gesture)}, and cleared with
+ \l{QGestureEvent::ignore()}{ignore(gesture)}.
+*/
+void QGestureEvent::setAccepted(QGesture *gesture, bool value)
+{
+ setAccepted(false);
+ if (gesture)
+ gesture->d_func()->accept = value;
+}
+
+/*!
+ Sets the accept flag of the given \a gesture object, the equivalent of calling
+ \l{QGestureEvent::setAccepted()}{setAccepted(gesture, true)}.
+
+ Setting the accept flag indicates that the event receiver wants the
+ gesture. Unwanted gestures may be propagated to the parent widget.
+
+ \sa QGestureEvent::ignore()
+*/
+void QGestureEvent::accept(QGesture *gesture)
+{
+ setAccepted(gesture, true);
+}
+
+/*!
+ Clears the accept flag parameter of the given \a gesture object, the equivalent
+ of calling \l{QGestureEvent::setAccepted()}{setAccepted(gesture, false)}.
+
+ Clearing the accept flag indicates that the event receiver does not
+ want the gesture. Unwanted gestures may be propgated to the parent widget.
+
+ \sa QGestureEvent::accept()
+*/
+void QGestureEvent::ignore(QGesture *gesture)
+{
+ setAccepted(gesture, false);
+}
+
+/*!
+ Returns true if the \a gesture is accepted; otherwise returns false.
+*/
+bool QGestureEvent::isAccepted(QGesture *gesture) const
+{
+ return gesture ? gesture->d_func()->accept : false;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 4396766..3516222 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -819,6 +819,40 @@ protected:
friend class QApplicationPrivate;
};
+class QGesture;
+class Q_GUI_EXPORT QGestureEvent : public QEvent
+{
+public:
+ QGestureEvent(const QList<QGesture *> &gestures);
+
+ QList<QGesture *> allGestures() const;
+ QGesture *gesture(Qt::GestureType type) const;
+
+ QList<QGesture *> activeGestures() const;
+ QList<QGesture *> canceledGestures() const;
+
+#ifdef Q_NO_USING_KEYWORD
+ inline void setAccepted(bool accepted) { QEvent::setAccepted(accepted); }
+ inline bool isAccepted() const { return QEvent::isAccepted(); }
+
+ inline void accept() { QEvent::accept(); }
+ inline void ignore() { QEvent::ignore(); }
+#else
+ using QEvent::setAccepted;
+ using QEvent::isAccepted;
+ using QEvent::accept;
+ using QEvent::ignore;
+#endif
+
+ void setAccepted(QGesture *, bool);
+ void accept(QGesture *);
+ void ignore(QGesture *);
+ bool isAccepted(QGesture *) const;
+
+private:
+ QList<QGesture *> gestures_;
+};
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm
index 7152705..49c851b 100644
--- a/src/gui/kernel/qeventdispatcher_mac.mm
+++ b/src/gui/kernel/qeventdispatcher_mac.mm
@@ -942,7 +942,7 @@ Boolean QEventDispatcherMacPrivate::postedEventSourceEqualCallback(const void *i
inline static void processPostedEvents(QEventDispatcherMacPrivate *const d, const bool blockSendPostedEvents)
{
- if (blockSendPostedEvents) {
+ if (blockSendPostedEvents || d->interrupt) {
CFRunLoopSourceSignal(d->postedEventsSource);
} else {
if (!d->threadData->canWait || (d->serialNumber != d->lastSerial)) {
diff --git a/src/gui/kernel/qformlayout.cpp b/src/gui/kernel/qformlayout.cpp
index 6ceab07..3e5dadc 100644
--- a/src/gui/kernel/qformlayout.cpp
+++ b/src/gui/kernel/qformlayout.cpp
@@ -252,7 +252,7 @@ QFormLayoutPrivate::QFormLayoutPrivate()
: fieldGrowthPolicy(DefaultFieldGrowthPolicy),
rowWrapPolicy(DefaultRowWrapPolicy), has_hfw(false), dirty(true), sizesDirty(true),
expandVertical(0), expandHorizontal(0), labelAlignment(0), formAlignment(0),
- hfw_width(-1), hfw_sh_height(-1), min_width(-1),
+ layoutWidth(-1), hfw_width(-1), hfw_sh_height(-1), min_width(-1),
sh_width(-1), thresh_width(QLAYOUTSIZE_MAX), hSpacing(-1), vSpacing(-1)
{
}
diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp
index 00839d1..3639a45 100644
--- a/src/gui/kernel/qgesture.cpp
+++ b/src/gui/kernel/qgesture.cpp
@@ -40,273 +40,329 @@
****************************************************************************/
#include "qgesture.h"
-#include <private/qgesture_p.h>
-#include "qgraphicsitem.h"
+#include "private/qgesture_p.h"
QT_BEGIN_NAMESPACE
-
-class QEventFilterProxyGraphicsItem : public QGraphicsItem
-{
-public:
- QEventFilterProxyGraphicsItem(QGesture *g)
- : gesture(g)
- {
- }
- bool sceneEventFilter(QGraphicsItem *, QEvent *event)
- {
- return gesture ? gesture->filterEvent(event) : false;
- }
- QRectF boundingRect() const { return QRectF(); }
- void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) { }
-
-private:
- QGesture *gesture;
-};
-
-/*!
+ /*!
\class QGesture
\since 4.6
- \brief The QGesture class is the base class for implementing custom
- gestures.
+ \brief The QGesture class represents a gesture, containing properties that
+ describe the corresponding user input.
- This class represents both an object that recognizes a gesture out of a set
- of input events (a gesture recognizer), and a gesture object itself that
- can be used to get extended information about the triggered gesture.
+ QGesture objects are delivered to widgets and \l{QGraphicsObject}s with
+ \l{QGestureEvent}s.
The class has a list of properties that can be queried by the user to get
- some gesture-specific parameters (for example, an offset of a Pan gesture).
-
- Usually gesture recognizer implements a state machine, storing its state
- internally in the recognizer object. The recognizer receives input events
- through the \l{QGesture::}{filterEvent()} virtual function and decides
- whether the event should change the state of the recognizer by emitting an
- appropriate signal.
-
- Input events should be either fed to the recognizer one by one with a
- filterEvent() function, or the gesture recognizer should be attached to an
- object it filters events for by specifying it as a parent object. The
- QGesture object installs itself as an event filter to the parent object
- automatically, the unsetObject() function should be used to remove an event
- filter from the parent object. To make a
- gesture that operates on a QGraphicsItem, both the appropriate QGraphicsView
- should be passed as a parent object and setGraphicsItem() functions should
- be used to attach a gesture to a graphics item.
-
- This is a base class, to create a custom gesture type, you should subclass
- it and implement its pure virtual functions.
-
- \sa QPanGesture
-*/
+ some gesture-specific arguments. For example, the QPinchGesture gesture has a scale
+ factor that is exposed as a property.
-/*! \fn bool QGesture::filterEvent(QEvent *event)
+ Developers of custom gesture recognizers can add additional properties in
+ order to provide additional information about a gesture. This can be done
+ by adding new dynamic properties to a QGesture object, or by subclassing
+ the QGesture class (or one of its subclasses).
- Parses input \a event and emits a signal when detects a gesture.
+ \sa QGestureEvent, QGestureRecognizer
+*/
- In your reimplementation of this function, if you want to filter the \a
- event out, i.e. stop it being handled further, return true; otherwise
- return false;
+/*!
+ Constructs a new gesture object with the given \a parent.
- This is a pure virtual function that needs to be implemented in subclasses.
+ QGesture objects are created by gesture recognizers in the
+ QGestureRecognizer::createGesture() function.
*/
+QGesture::QGesture(QObject *parent)
+ : QObject(*new QGesturePrivate, parent)
+{
+ d_func()->gestureType = Qt::CustomGesture;
+}
-/*! \fn void QGesture::started()
-
- The signal is emitted when the gesture is started. Extended information
- about the gesture is contained in the signal sender object.
+/*!
+ \internal
+*/
+QGesture::QGesture(QGesturePrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{
+}
- In addition to started(), a triggered() signal should also be emitted.
+/*!
+ Destroys the gesture object.
*/
+QGesture::~QGesture()
+{
+}
-/*! \fn void QGesture::triggered()
+/*!
+ \property QGesture::state
+ \brief the current state of the gesture
+*/
- The signal is emitted when the gesture is detected. Extended information
- about the gesture is contained in the signal sender object.
+/*!
+ \property QGesture::gestureType
+ \brief the type of the gesture
*/
-/*! \fn void QGesture::finished()
+/*!
+ \property QGesture::hotSpot
- The signal is emitted when the gesture is finished. Extended information
- about the gesture is contained in the signal sender object.
-*/
+ \brief The point that is used to find the receiver for the gesture event.
-/*! \fn void QGesture::canceled()
+ If the hot-spot is not set, the targetObject is used as the receiver of the
+ gesture event.
+*/
- The signal is emitted when the gesture is canceled, for example the
- reset() function is called while the gesture was in the process of
- emitting a triggered() signal. Extended information about the
- gesture is contained in the sender object.
+/*!
+ \property QGesture::hasHotSpot
+ \brief whether the gesture has a hot-spot
*/
/*!
- Creates a new gesture handler object and marks it as a child of \a
- parent. \a gestureTarget is the object that the gesture will watch
- for events.
+ \property QGesture::targetObject
+ \brief the target object which will receive the gesture event if the hotSpot is
+ not set
+*/
- The \a parent object is also the default event source for the
- gesture, meaning that the gesture installs itself as an event filter
- for the \a parent.
+Qt::GestureType QGesture::gestureType() const
+{
+ return d_func()->gestureType;
+}
- \sa setGraphicsItem()
-*/
-QGesture::QGesture(QObject *gestureTarget, QObject *parent)
- : QObject(*new QGesturePrivate, parent)
+Qt::GestureState QGesture::state() const
{
- setGestureTarget(gestureTarget);
+ return d_func()->state;
}
-/*! \internal
- */
-QGesture::QGesture(QGesturePrivate &dd, QObject *gestureTarget, QObject *parent)
- : QObject(dd, parent)
+QObject *QGesture::targetObject() const
{
- setGestureTarget(gestureTarget);
+ return d_func()->targetObject;
}
-/*!
- Destroys the gesture object.
-*/
-QGesture::~QGesture()
+void QGesture::setTargetObject(QObject *value)
{
+ d_func()->targetObject = value;
}
-/*!
- \property QGesture::gestureTarget
+QPointF QGesture::hotSpot() const
+{
+ return d_func()->hotSpot;
+}
- Gesture target is the object that the gesture will watch for events.
- Typically this means that the gesture installs an event filter on the
- target object.
-*/
-void QGesture::setGestureTarget(QObject *object)
+void QGesture::setHotSpot(const QPointF &value)
{
- d_func()->setupGestureTarget(object);
+ Q_D(QGesture);
+ d->hotSpot = value;
+ d->isHotSpotSet = true;
}
-QObject* QGesture::gestureTarget() const
+bool QGesture::hasHotSpot() const
{
- return d_func()->gestureTarget;
+ return d_func()->isHotSpotSet;
}
-void QGesturePrivate::setupGestureTarget(QObject *object)
+void QGesture::unsetHotSpot()
{
- Q_Q(QGesture);
- if (gestureTarget)
- gestureTarget->removeEventFilter(q);
- if (object)
- object->installEventFilter(q);
- gestureTarget = object;
+ d_func()->isHotSpotSet = false;
}
-/*! \internal
- */
-bool QGesture::eventFilter(QObject *receiver, QEvent *event)
+// QPanGesture
+
+QPanGesture::QPanGesture(QObject *parent)
+ : QGesture(*new QPanGesturePrivate, parent)
{
- Q_D(QGesture);
- if (d->graphicsItem && receiver == parent())
- return false;
- return filterEvent(event);
+ d_func()->gestureType = Qt::PanGesture;
}
-/*!
- \property QGesture::state
+QSizeF QPanGesture::totalOffset() const
+{
+ return d_func()->totalOffset;
+}
- \brief The current state of the gesture.
-*/
+QSizeF QPanGesture::lastOffset() const
+{
+ return d_func()->lastOffset;
+}
-/*!
- Returns the gesture recognition state.
- */
-Qt::GestureState QGesture::state() const
+QSizeF QPanGesture::offset() const
{
- return d_func()->state;
+ return d_func()->offset;
}
-/*!
- Sets this gesture's recognition state to \a state and emits appropriate
- signals.
+qreal QPanGesture::acceleration() const
+{
+ return d_func()->acceleration;
+}
- This functions emits the signals according to the old state and the new
- \a state, and it should be called after all the internal properties have been
- initialized.
- \sa started(), triggered(), finished(), canceled()
- */
-void QGesture::updateState(Qt::GestureState state)
+void QPanGesture::setTotalOffset(const QSizeF &value)
{
- Q_D(QGesture);
- if (d->state == state) {
- if (state == Qt::GestureUpdated)
- emit triggered();
- return;
- }
- const Qt::GestureState oldState = d->state;
- if (state != Qt::NoGesture && oldState > state) {
- // comparing the state as ints: state should only be changed from
- // started to (optionally) updated and to finished.
- d->state = state;
- qWarning("QGesture::updateState: incorrect new state");
- return;
- }
- if (oldState == Qt::NoGesture) {
- d->state = Qt::GestureStarted;
- emit started();
- }
- d->state = state;
- if (state == Qt::GestureUpdated)
- emit triggered();
- else if (state == Qt::GestureFinished)
- emit finished();
- else if (state == Qt::NoGesture)
- emit canceled();
-
- if (state == Qt::GestureFinished) {
- // gesture is finished, so we reset the internal state.
- d->state = Qt::NoGesture;
- }
+ d_func()->totalOffset = value;
}
-/*!
- Sets the \a graphicsItem the gesture is filtering events for.
+void QPanGesture::setLastOffset(const QSizeF &value)
+{
+ d_func()->lastOffset = value;
+}
- The gesture will install an event filter to the \a graphicsItem and
- redirect them to the filterEvent() function.
+void QPanGesture::setOffset(const QSizeF &value)
+{
+ d_func()->offset = value;
+}
- \sa graphicsItem()
-*/
-void QGesture::setGraphicsItem(QGraphicsItem *graphicsItem)
+void QPanGesture::setAcceleration(qreal value)
{
- Q_D(QGesture);
- if (d->graphicsItem && d->eventFilterProxyGraphicsItem)
- d->graphicsItem->removeSceneEventFilter(d->eventFilterProxyGraphicsItem);
- d->graphicsItem = graphicsItem;
- if (!d->eventFilterProxyGraphicsItem)
- d->eventFilterProxyGraphicsItem = new QEventFilterProxyGraphicsItem(this);
- if (graphicsItem)
- graphicsItem->installSceneEventFilter(d->eventFilterProxyGraphicsItem);
+ d_func()->acceleration = value;
}
-/*!
- Returns the graphics item the gesture is filtering events for.
+// QPinchGesture
- \sa setGraphicsItem()
-*/
-QGraphicsItem* QGesture::graphicsItem() const
+QPinchGesture::QPinchGesture(QObject *parent)
+ : QGesture(*new QPinchGesturePrivate, parent)
+{
+ d_func()->gestureType = Qt::PinchGesture;
+}
+
+QPinchGesture::WhatChanged QPinchGesture::whatChanged() const
{
- return d_func()->graphicsItem;
+ return d_func()->whatChanged;
}
-/*! \fn void QGesture::reset()
+void QPinchGesture::setWhatChanged(QPinchGesture::WhatChanged value)
+{
+ d_func()->whatChanged = value;
+}
- Resets the internal state of the gesture. This function might be called by
- the filterEvent() implementation in a derived class, or by the user to
- cancel a gesture. The base class implementation calls
- updateState(Qt::NoGesture) which emits the canceled()
- signal if the state() of the gesture indicated it was active.
-*/
-void QGesture::reset()
+
+QPointF QPinchGesture::startCenterPoint() const
+{
+ return d_func()->startCenterPoint;
+}
+
+QPointF QPinchGesture::lastCenterPoint() const
+{
+ return d_func()->lastCenterPoint;
+}
+
+QPointF QPinchGesture::centerPoint() const
+{
+ return d_func()->centerPoint;
+}
+
+void QPinchGesture::setStartCenterPoint(const QPointF &value)
+{
+ d_func()->startCenterPoint = value;
+}
+
+void QPinchGesture::setLastCenterPoint(const QPointF &value)
+{
+ d_func()->lastCenterPoint = value;
+}
+
+void QPinchGesture::setCenterPoint(const QPointF &value)
+{
+ d_func()->centerPoint = value;
+}
+
+
+qreal QPinchGesture::totalScaleFactor() const
+{
+ return d_func()->totalScaleFactor;
+}
+
+qreal QPinchGesture::lastScaleFactor() const
+{
+ return d_func()->lastScaleFactor;
+}
+
+qreal QPinchGesture::scaleFactor() const
+{
+ return d_func()->scaleFactor;
+}
+
+void QPinchGesture::setTotalScaleFactor(qreal value)
+{
+ d_func()->totalScaleFactor = value;
+}
+
+void QPinchGesture::setLastScaleFactor(qreal value)
+{
+ d_func()->lastScaleFactor = value;
+}
+
+void QPinchGesture::setScaleFactor(qreal value)
+{
+ d_func()->scaleFactor = value;
+}
+
+
+qreal QPinchGesture::totalRotationAngle() const
+{
+ return d_func()->totalRotationAngle;
+}
+
+qreal QPinchGesture::lastRotationAngle() const
+{
+ return d_func()->lastRotationAngle;
+}
+
+qreal QPinchGesture::rotationAngle() const
+{
+ return d_func()->rotationAngle;
+}
+
+void QPinchGesture::setTotalRotationAngle(qreal value)
+{
+ d_func()->totalRotationAngle = value;
+}
+
+void QPinchGesture::setLastRotationAngle(qreal value)
+{
+ d_func()->lastRotationAngle = value;
+}
+
+void QPinchGesture::setRotationAngle(qreal value)
+{
+ d_func()->rotationAngle = value;
+}
+
+// QSwipeGesture
+
+QSwipeGesture::QSwipeGesture(QObject *parent)
+ : QGesture(*new QSwipeGesturePrivate, parent)
+{
+ d_func()->gestureType = Qt::SwipeGesture;
+}
+
+QSwipeGesture::SwipeDirection QSwipeGesture::horizontalDirection() const
+{
+ Q_D(const QSwipeGesture);
+ if (d->swipeAngle < 0 || d->swipeAngle == 90 || d->swipeAngle == 270)
+ return QSwipeGesture::NoDirection;
+ else if (d->swipeAngle < 90 || d->swipeAngle > 270)
+ return QSwipeGesture::Right;
+ else
+ return QSwipeGesture::Left;
+}
+
+QSwipeGesture::SwipeDirection QSwipeGesture::verticalDirection() const
+{
+ Q_D(const QSwipeGesture);
+ if (d->swipeAngle <= 0 || d->swipeAngle == 180)
+ return QSwipeGesture::NoDirection;
+ else if (d->swipeAngle < 180)
+ return QSwipeGesture::Up;
+ else
+ return QSwipeGesture::Down;
+}
+
+qreal QSwipeGesture::swipeAngle() const
+{
+ return d_func()->swipeAngle;
+}
+
+void QSwipeGesture::setSwipeAngle(qreal value)
{
- updateState(Qt::NoGesture);
+ d_func()->swipeAngle = value;
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h
index 440565e..0034819 100644
--- a/src/gui/kernel/qgesture.h
+++ b/src/gui/kernel/qgesture.h
@@ -55,7 +55,8 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
-class QGraphicsItem;
+Q_DECLARE_METATYPE(Qt::GestureState)
+
class QGesturePrivate;
class Q_GUI_EXPORT QGesture : public QObject
{
@@ -63,37 +64,146 @@ class Q_GUI_EXPORT QGesture : public QObject
Q_DECLARE_PRIVATE(QGesture)
Q_PROPERTY(Qt::GestureState state READ state)
- Q_PROPERTY(QObject* gestureTarget READ gestureTarget WRITE setGestureTarget)
+ Q_PROPERTY(Qt::GestureType gestureType READ gestureType)
+ Q_PROPERTY(QPointF hotSpot READ hotSpot WRITE setHotSpot RESET unsetHotSpot)
+ Q_PROPERTY(bool hasHotSpot READ hasHotSpot)
+ Q_PROPERTY(QObject* targetObject READ targetObject WRITE setTargetObject)
public:
- explicit QGesture(QObject *gestureTarget = 0, QObject *parent = 0);
+ explicit QGesture(QObject *parent = 0);
~QGesture();
- virtual bool filterEvent(QEvent *event) = 0;
+ Qt::GestureType gestureType() const;
- void setGestureTarget(QObject *object);
- QObject* gestureTarget() const;
+ Qt::GestureState state() const;
- void setGraphicsItem(QGraphicsItem *);
- QGraphicsItem *graphicsItem() const;
+ QObject *targetObject() const;
+ void setTargetObject(QObject *value);
- Qt::GestureState state() const;
+ QPointF hotSpot() const;
+ void setHotSpot(const QPointF &value);
+ bool hasHotSpot() const;
+ void unsetHotSpot();
protected:
- QGesture(QGesturePrivate &dd, QObject *gestureTarget, QObject *parent);
- bool eventFilter(QObject*, QEvent*);
+ QGesture(QGesturePrivate &dd, QObject *parent);
- virtual void reset();
- void updateState(Qt::GestureState state);
+private:
+ friend class QGestureEvent;
+ friend class QGestureRecognizer;
+ friend class QGestureManager;
+};
-Q_SIGNALS:
- void started();
- void triggered();
- void finished();
- void canceled();
+class QPanGesturePrivate;
+class Q_GUI_EXPORT QPanGesture : public QGesture
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPanGesture)
-private:
- friend class QWidget;
+ Q_PROPERTY(QSizeF totalOffset READ totalOffset WRITE setTotalOffset)
+ Q_PROPERTY(QSizeF lastOffset READ lastOffset WRITE setLastOffset)
+ Q_PROPERTY(QSizeF offset READ offset WRITE setOffset)
+ Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration)
+
+public:
+ QPanGesture(QObject *parent = 0);
+
+ QSizeF totalOffset() const;
+ QSizeF lastOffset() const;
+ QSizeF offset() const;
+ qreal acceleration() const;
+
+ void setTotalOffset(const QSizeF &value);
+ void setLastOffset(const QSizeF &value);
+ void setOffset(const QSizeF &value);
+ void setAcceleration(qreal value);
+
+ friend class QPanGestureRecognizer;
+ friend class QWinNativePanGestureRecognizer;
+};
+
+class QPinchGesturePrivate;
+class Q_GUI_EXPORT QPinchGesture : public QGesture
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPinchGesture)
+
+public:
+ enum WhatChange {
+ ScaleFactorChanged = 0x1,
+ RotationAngleChanged = 0x2,
+ CenterPointChanged = 0x4
+ };
+ Q_DECLARE_FLAGS(WhatChanged, WhatChange)
+
+ Q_PROPERTY(WhatChanged whatChanged READ whatChanged WRITE setWhatChanged)
+
+ Q_PROPERTY(qreal totalScaleFactor READ totalScaleFactor WRITE setTotalScaleFactor)
+ Q_PROPERTY(qreal lastScaleFactor READ lastScaleFactor WRITE setLastScaleFactor)
+ Q_PROPERTY(qreal scaleFactor READ scaleFactor WRITE setScaleFactor)
+
+ Q_PROPERTY(qreal totalRotationAngle READ totalRotationAngle WRITE setTotalRotationAngle)
+ Q_PROPERTY(qreal lastRotationAngle READ lastRotationAngle WRITE setLastRotationAngle)
+ Q_PROPERTY(qreal rotationAngle READ rotationAngle WRITE setRotationAngle)
+
+ Q_PROPERTY(QPointF startCenterPoint READ startCenterPoint WRITE setStartCenterPoint)
+ Q_PROPERTY(QPointF lastCenterPoint READ lastCenterPoint WRITE setLastCenterPoint)
+ Q_PROPERTY(QPointF centerPoint READ centerPoint WRITE setCenterPoint)
+
+public:
+ QPinchGesture(QObject *parent = 0);
+
+ WhatChanged whatChanged() const;
+ void setWhatChanged(WhatChanged value);
+
+ QPointF startCenterPoint() const;
+ QPointF lastCenterPoint() const;
+ QPointF centerPoint() const;
+ void setStartCenterPoint(const QPointF &value);
+ void setLastCenterPoint(const QPointF &value);
+ void setCenterPoint(const QPointF &value);
+
+ qreal totalScaleFactor() const;
+ qreal lastScaleFactor() const;
+ qreal scaleFactor() const;
+ void setTotalScaleFactor(qreal value);
+ void setLastScaleFactor(qreal value);
+ void setScaleFactor(qreal value);
+
+ qreal totalRotationAngle() const;
+ qreal lastRotationAngle() const;
+ qreal rotationAngle() const;
+ void setTotalRotationAngle(qreal value);
+ void setLastRotationAngle(qreal value);
+ void setRotationAngle(qreal value);
+
+ friend class QPinchGestureRecognizer;
+};
+
+Q_DECLARE_METATYPE(QPinchGesture::WhatChanged)
+
+class QSwipeGesturePrivate;
+class Q_GUI_EXPORT QSwipeGesture : public QGesture
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QSwipeGesture)
+ Q_ENUMS(SwipeDirection)
+
+ Q_PROPERTY(SwipeDirection horizontalDirection READ horizontalDirection STORED false)
+ Q_PROPERTY(SwipeDirection verticalDirection READ verticalDirection STORED false)
+ Q_PROPERTY(qreal swipeAngle READ swipeAngle WRITE setSwipeAngle)
+
+public:
+ enum SwipeDirection { NoDirection, Left, Right, Up, Down };
+ QSwipeGesture(QObject *parent = 0);
+
+ SwipeDirection horizontalDirection() const;
+ SwipeDirection verticalDirection() const;
+
+ qreal swipeAngle() const;
+ void setSwipeAngle(qreal value);
+
+ friend class QSwipeGestureRecognizer;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h
index 52e399f..7f69a4e 100644
--- a/src/gui/kernel/qgesture_p.h
+++ b/src/gui/kernel/qgesture_p.h
@@ -61,29 +61,83 @@
QT_BEGIN_NAMESPACE
-class QObject;
-class QGraphicsItem;
class QGesturePrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QGesture)
public:
QGesturePrivate()
- : gestureTarget(0), graphicsItem(0), eventFilterProxyGraphicsItem(0),
- state(Qt::NoGesture), implicitGesture(false)
+ : gestureType(Qt::CustomGesture), state(Qt::NoGesture), isHotSpotSet(false),
+ targetObject(0), accept(true)
{
}
- virtual void setupGestureTarget(QObject *o);
+ Qt::GestureType gestureType;
+ Qt::GestureState state;
+ QPointF hotSpot;
+ bool isHotSpotSet;
+ QObject *targetObject;
+ bool accept;
+};
- QPointer<QObject> gestureTarget;
- QGraphicsItem *graphicsItem;
- QGraphicsItem *eventFilterProxyGraphicsItem;
+class QPanGesturePrivate : public QGesturePrivate
+{
+ Q_DECLARE_PUBLIC(QPanGesture)
- Qt::GestureState state;
+public:
+ QPanGesturePrivate()
+ : acceleration(0)
+ {
+ }
+
+ QSizeF totalOffset;
+ QSizeF lastOffset;
+ QSizeF offset;
+ QPoint lastPosition;
+ qreal acceleration;
+};
+
+class QPinchGesturePrivate : public QGesturePrivate
+{
+ Q_DECLARE_PUBLIC(QPinchGesture)
+
+public:
+ QPinchGesturePrivate()
+ : whatChanged(0), totalScaleFactor(0), lastScaleFactor(0), scaleFactor(0),
+ totalRotationAngle(0), lastRotationAngle(0), rotationAngle(0)
+ {
+ }
+
+ QPinchGesture::WhatChanged whatChanged;
+
+ QPointF startCenterPoint;
+ QPointF lastCenterPoint;
+ QPointF centerPoint;
+
+ qreal totalScaleFactor;
+ qreal lastScaleFactor;
+ qreal scaleFactor;
+
+ qreal totalRotationAngle;
+ qreal lastRotationAngle;
+ qreal rotationAngle;
+};
+
+class QSwipeGesturePrivate : public QGesturePrivate
+{
+ Q_DECLARE_PUBLIC(QSwipeGesture)
+
+public:
+ QSwipeGesturePrivate()
+ : horizontalDirection(QSwipeGesture::NoDirection),
+ verticalDirection(QSwipeGesture::NoDirection),
+ swipeAngle(0)
+ {
+ }
- // the flag specifies if the gesture was created implicitely by Qt.
- bool implicitGesture;
+ QSwipeGesture::SwipeDirection horizontalDirection;
+ QSwipeGesture::SwipeDirection verticalDirection;
+ qreal swipeAngle;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
new file mode 100644
index 0000000..0f0aef2
--- /dev/null
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -0,0 +1,467 @@
+/****************************************************************************
+**
+** 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 QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** 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$
+**
+****************************************************************************/
+
+#include "private/qgesturemanager_p.h"
+#include "private/qstandardgestures_p.h"
+#include "private/qwidget_p.h"
+#include "private/qgesture_p.h"
+#include "private/qgraphicsitem_p.h"
+#include "qgesture.h"
+#include "qevent.h"
+#include "qgraphicsitem.h"
+
+#ifdef Q_WS_MAC
+#include "qmacgesturerecognizer_mac_p.h"
+#endif
+
+#include "qdebug.h"
+
+// #define GESTURE_DEBUG
+#ifndef GESTURE_DEBUG
+# define DEBUG if (0) qDebug
+#else
+# define DEBUG qDebug
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QGestureManager::QGestureManager(QObject *parent)
+ : QObject(parent), state(NotGesture), lastCustomGestureId(0)
+{
+ qRegisterMetaType<Qt::GestureState>();
+
+#if defined(Q_WS_MAC)
+ registerGestureRecognizer(new QMacSwipeGestureRecognizer);
+ registerGestureRecognizer(new QMacPinchGestureRecognizer);
+ #if defined(QT_MAC_USE_COCOA)
+ registerGestureRecognizer(new QMacPanGestureRecognizer);
+ #endif
+#else
+ registerGestureRecognizer(new QPanGestureRecognizer);
+#endif
+}
+
+QGestureManager::~QGestureManager()
+{
+
+}
+
+Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer)
+{
+ QGesture *dummy = recognizer->createGesture(0);
+ if (!dummy) {
+ qWarning("QGestureManager::registerGestureRecognizer: the recognizer doesn't provide gesture object");
+ return Qt::GestureType(0);
+ }
+ Qt::GestureType type = dummy->gestureType();
+ if (type == Qt::CustomGesture) {
+ // generate a new custom gesture id
+ ++lastCustomGestureId;
+ type = Qt::GestureType(Qt::CustomGesture + lastCustomGestureId);
+ }
+ recognizers.insertMulti(type, recognizer);
+ delete dummy;
+ return type;
+}
+
+void QGestureManager::unregisterGestureRecognizer(Qt::GestureType)
+{
+
+}
+
+QGesture* QGestureManager::getState(QObject *object, Qt::GestureType type)
+{
+ // if the widget is being deleted we should be carefull and not to
+ // create a new state, as it will create QWeakPointer which doesnt work
+ // from the destructor.
+ if (object->isWidgetType()) {
+ if (static_cast<QWidget *>(object)->d_func()->data.in_destructor)
+ return 0;
+ }
+
+ QWeakPointer<QGesture> state = objectGestures.value(QGestureManager::ObjectGesture(object, type));
+ if (!state) {
+ QGestureRecognizer *recognizer = recognizers.value(type);
+ if (recognizer) {
+ state = recognizer->createGesture(object);
+ if (!state)
+ return 0;
+ if (state.data()->gestureType() == Qt::CustomGesture) {
+ // if the recognizer didn't fill in the gesture type, then this
+ // is a custom gesture with autogenerated it and we fill it.
+ state.data()->d_func()->gestureType = type;
+ }
+ objectGestures.insert(QGestureManager::ObjectGesture(object, type), state);
+ gestureToRecognizer[state.data()] = recognizer;
+ }
+ }
+ return state.data();
+}
+
+bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
+{
+ QSet<QGesture *> triggeredGestures;
+ QSet<QGesture *> finishedGestures;
+ QSet<QGesture *> newMaybeGestures;
+ QSet<QGesture *> canceledGestures;
+ QSet<QGesture *> notGestures;
+
+ QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(receiver);
+ if (receiver->isWidgetType() || graphicsObject) {
+ QMap<QObject *, Qt::GestureType> contexts;
+ if (receiver->isWidgetType()) {
+ QWidget *w = static_cast<QWidget *>(receiver);
+ if (!w->d_func()->gestureContext.isEmpty()) {
+ typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
+ for(ContextIterator it = w->d_func()->gestureContext.begin(),
+ e = w->d_func()->gestureContext.end(); it != e; ++it) {
+ contexts.insertMulti(w, it.key());
+ }
+ }
+ // find all gesture contexts for the widget tree
+ w = w->parentWidget();
+ while (w)
+ {
+ typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
+ for (ContextIterator it = w->d_func()->gestureContext.begin(),
+ e = w->d_func()->gestureContext.end(); it != e; ++it) {
+ if (it.value() == Qt::WidgetWithChildrenGesture)
+ contexts.insertMulti(w, it.key());
+ }
+ w = w->parentWidget();
+ }
+ } else {
+ QGraphicsObject *item = graphicsObject;
+ if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
+ typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
+ for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
+ e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
+ contexts.insertMulti(item, it.key());
+ }
+ }
+ // find all gesture contexts for the widget tree
+ item = item->parentObject();
+ while (item)
+ {
+ typedef QMap<Qt::GestureType, Qt::GestureContext>::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::WidgetWithChildrenGesture)
+ contexts.insertMulti(item, it.key());
+ }
+ item = item->parentObject();
+ }
+ }
+ // filter the event through recognizers
+ typedef QMap<QObject *, Qt::GestureType>::const_iterator ContextIterator;
+ for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) {
+ Qt::GestureType gestureType = cit.value();
+ QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
+ rit = recognizers.lowerBound(gestureType),
+ re = recognizers.upperBound(gestureType);
+ for (; rit != re; ++rit) {
+ QGestureRecognizer *recognizer = rit.value();
+ QObject *target = cit.key();
+ QGesture *state = getState(target, gestureType);
+ if (!state)
+ continue;
+ QGestureRecognizer::Result result = recognizer->filterEvent(state, target, event);
+ QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask;
+ if (type == QGestureRecognizer::GestureTriggered) {
+ DEBUG() << "QGestureManager: gesture triggered: " << state;
+ triggeredGestures << state;
+ } else if (type == QGestureRecognizer::GestureFinished) {
+ DEBUG() << "QGestureManager: gesture finished: " << state;
+ finishedGestures << state;
+ } else if (type == QGestureRecognizer::MaybeGesture) {
+ DEBUG() << "QGestureManager: maybe gesture: " << state;
+ newMaybeGestures << state;
+ } else if (type == QGestureRecognizer::NotGesture) {
+ DEBUG() << "QGestureManager: not gesture: " << state;
+ notGestures << state;
+ } else if (type == QGestureRecognizer::Ignore) {
+ DEBUG() << "QGestureManager: gesture ignored the event: " << state;
+ } else {
+ DEBUG() << "QGestureManager: hm, lets assume the recognizer ignored the event: " << state;
+ }
+ if (result & QGestureRecognizer::ConsumeEventHint) {
+ DEBUG() << "QGestureManager: we were asked to consume the event: " << state;
+ //TODO: consume events if asked
+ }
+ }
+ }
+ } else if (QGesture *state = qobject_cast<QGesture*>(receiver)) {
+ if (QGestureRecognizer *recognizer = gestureToRecognizer.value(state)) {
+ QGestureRecognizer::Result result = recognizer->filterEvent(state, state, event);
+ QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask;
+ if (type == QGestureRecognizer::GestureTriggered) {
+ DEBUG() << "QGestureManager: gesture triggered: " << state;
+ triggeredGestures << state;
+ } else if (type == QGestureRecognizer::GestureFinished) {
+ DEBUG() << "QGestureManager: gesture finished: " << state;
+ finishedGestures << state;
+ } else if (type == QGestureRecognizer::MaybeGesture) {
+ DEBUG() << "QGestureManager: maybe gesture: " << state;
+ newMaybeGestures << state;
+ } else if (type == QGestureRecognizer::NotGesture) {
+ DEBUG() << "QGestureManager: not gesture: " << state;
+ notGestures << state;
+ } else if (type == QGestureRecognizer::Ignore) {
+ DEBUG() << "QGestureManager: gesture ignored the event: " << state;
+ } else {
+ DEBUG() << "QGestureManager: hm, lets assume the recognizer ignored the event: " << state;
+ }
+ }
+ } else {
+ return false;
+ }
+
+ QSet<QGesture *> startedGestures = triggeredGestures - activeGestures;
+ triggeredGestures &= activeGestures;
+
+ // check if a running gesture switched back to maybe state
+ QSet<QGesture *> activeToMaybeGestures = activeGestures & newMaybeGestures;
+
+ // check if a running gesture switched back to not gesture state, i.e. were canceled
+ QSet<QGesture *> activeToCancelGestures = activeGestures & notGestures;
+ canceledGestures += activeToCancelGestures;
+
+ // start timers for new gestures in maybe state
+ foreach (QGesture *state, newMaybeGestures) {
+ QBasicTimer &timer = maybeGestures[state];
+ if (!timer.isActive())
+ timer.start(3000, this);
+ }
+ // kill timers for gestures that were in maybe state
+ QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures | finishedGestures | canceledGestures | notGestures);
+ foreach(QGesture *gesture, notMaybeGestures) {
+ QMap<QGesture *, QBasicTimer>::iterator it =
+ maybeGestures.find(gesture);
+ if (it != maybeGestures.end()) {
+ it.value().stop();
+ maybeGestures.erase(it);
+ }
+ }
+
+ Q_ASSERT((startedGestures & finishedGestures).isEmpty());
+ Q_ASSERT((startedGestures & newMaybeGestures).isEmpty());
+ Q_ASSERT((startedGestures & canceledGestures).isEmpty());
+ Q_ASSERT((finishedGestures & newMaybeGestures).isEmpty());
+ Q_ASSERT((finishedGestures & canceledGestures).isEmpty());
+ Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty());
+
+ QSet<QGesture *> notStarted = finishedGestures - activeGestures;
+ if (!notStarted.isEmpty()) {
+ // there are some gestures that claim to be finished, but never started.
+ // probably those are "singleshot" gestures so we'll fake the started state.
+ foreach (QGesture *gesture, notStarted)
+ gesture->d_func()->state = Qt::GestureStarted;
+ deliverEvents(notStarted, receiver);
+ }
+
+ activeGestures += startedGestures;
+ // sanity check: all triggered gestures should already be in active gestures list
+ Q_ASSERT((activeGestures & triggeredGestures).size() == triggeredGestures.size());
+ activeGestures -= finishedGestures;
+ activeGestures -= activeToMaybeGestures;
+ activeGestures -= canceledGestures;
+
+ // set the proper gesture state on each gesture
+ foreach (QGesture *gesture, startedGestures)
+ gesture->d_func()->state = Qt::GestureStarted;
+ foreach (QGesture *gesture, triggeredGestures)
+ gesture->d_func()->state = Qt::GestureUpdated;
+ foreach (QGesture *gesture, finishedGestures)
+ gesture->d_func()->state = Qt::GestureFinished;
+ foreach (QGesture *gesture, canceledGestures)
+ gesture->d_func()->state = Qt::GestureCanceled;
+ foreach (QGesture *gesture, activeToMaybeGestures)
+ gesture->d_func()->state = Qt::GestureFinished;
+
+ if (!activeGestures.isEmpty() || !maybeGestures.isEmpty() ||
+ !startedGestures.isEmpty() || !triggeredGestures.isEmpty() ||
+ !finishedGestures.isEmpty() || !canceledGestures.isEmpty()) {
+ DEBUG() << "QGestureManager::filterEvent:"
+ << "\n\tactiveGestures:" << activeGestures
+ << "\n\tmaybeGestures:" << maybeGestures.keys()
+ << "\n\tstarted:" << startedGestures
+ << "\n\ttriggered:" << triggeredGestures
+ << "\n\tfinished:" << finishedGestures
+ << "\n\tcanceled:" << canceledGestures;
+ }
+
+ deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures, receiver);
+
+ // reset gestures that ended
+ QSet<QGesture *> endedGestures = finishedGestures + canceledGestures;
+ foreach (QGesture *gesture, endedGestures) {
+ if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0)) {
+ recognizer->reset(gesture);
+ }
+ gestureTargets.remove(gesture);
+ }
+ return false;
+}
+
+void QGestureManager::deliverEvents(const QSet<QGesture*> &gestures, QObject *lastReceiver)
+{
+ if (gestures.isEmpty())
+ return;
+
+ // group gestures by widgets
+ typedef QMap<QObject *, QList<QGesture *> > GesturesPerReceiver;
+ GesturesPerReceiver groupedGestures;
+ // for conflicted gestures the key is always the innermost widget (i.e. the child)
+ GesturesPerReceiver conflictedGestures;
+ QMultiHash<QObject *, QGesture *> objectGestures;
+
+ foreach (QGesture *gesture, gestures) {
+ QObject *target = gestureTargets.value(gesture, 0);
+ if (!target) {
+ Q_ASSERT(gesture->state() == Qt::GestureStarted);
+ if (gesture->hasHotSpot()) {
+ // guess the target using the hotspot of the gesture
+ QPoint pt = gesture->hotSpot().toPoint();
+ if (!pt.isNull()) {
+ if (QWidget *w = qApp->topLevelAt(pt))
+ target = w->childAt(w->mapFromGlobal(pt));
+ }
+ }
+ if (!target) {
+ target = gesture->targetObject();
+ if (!target)
+ target = lastReceiver;
+ }
+ }
+ if (target) {
+ gestureTargets.insert(gesture, target);
+ if (target->isWidgetType())
+ objectGestures.insert(target, gesture);
+ groupedGestures[target].append(gesture);
+ } else {
+ qWarning() << "QGestureManager::deliverEvent: could not find the target for gesture"
+ << gesture->gestureType();
+ }
+ }
+
+ typedef QMultiHash<QObject *, QGesture *>::const_iterator ObjectGesturesIterator;
+ for (ObjectGesturesIterator it = objectGestures.begin(), e = objectGestures.end(); it != e; ++it) {
+ QObject *object1 = it.key();
+ QWidget *widget1 = qobject_cast<QWidget *>(object1);
+ QGraphicsObject *item1 = qobject_cast<QGraphicsObject *>(object1);
+ QGesture *gesture1 = it.value();
+ ObjectGesturesIterator cit = it;
+ for (++cit; cit != e; ++cit) {
+ QObject *object2 = cit.key();
+ QWidget *widget2 = qobject_cast<QWidget *>(object2);
+ QGraphicsObject *item2 = qobject_cast<QGraphicsObject *>(object2);
+ QGesture *gesture2 = cit.value();
+ // TODO: ugly, rewrite this.
+ if ((widget1 && widget2 && widget2->isAncestorOf(widget1)) ||
+ (item1 && item2 && item2->isAncestorOf(item1))) {
+ groupedGestures[object2].removeOne(gesture2);
+ groupedGestures[object1].removeOne(gesture1);
+ conflictedGestures[object1].append(gesture1);
+ } else if ((widget1 && widget2 && widget1->isAncestorOf(widget2)) ||
+ (item1 && item2 && item1->isAncestorOf(item2))) {
+ groupedGestures[object2].removeOne(gesture2);
+ groupedGestures[object1].removeOne(gesture1);
+ conflictedGestures[object2].append(gesture2);
+ }
+ }
+ }
+
+ DEBUG() << "deliverEvents: conflicted =" << conflictedGestures.values()
+ << " grouped =" << groupedGestures.values();
+
+ // if there are conflicting gestures, send the GestureOverride event
+ for (GesturesPerReceiver::const_iterator it = conflictedGestures.begin(),
+ e = conflictedGestures.end(); it != e; ++it) {
+ DEBUG() << "QGestureManager::deliverEvents: sending GestureOverride to"
+ << it.key()
+ << " gestures:" << it.value();
+ QGestureEvent event(it.value());
+ event.t = QEvent::GestureOverride;
+ event.ignore();
+ QApplication::sendEvent(it.key(), &event);
+ if (!event.isAccepted()) {
+ // nobody accepted the GestureOverride, put it back to deliver to
+ // the closest context (i.e. to the inner-most widget).
+ DEBUG() <<" override was not accepted";
+ groupedGestures[it.key()].append(it.value());
+ }
+ }
+
+ for (GesturesPerReceiver::const_iterator it = groupedGestures.begin(),
+ e = groupedGestures.end(); it != e; ++it) {
+ if (!it.value().isEmpty()) {
+ DEBUG() << "QGestureManager::deliverEvents: sending to" << it.key()
+ << " gestures:" << it.value();
+ QGestureEvent event(it.value());
+ QApplication::sendEvent(it.key(), &event);
+ }
+ }
+}
+
+void QGestureManager::timerEvent(QTimerEvent *event)
+{
+ QMap<QGesture*, QBasicTimer>::iterator it = maybeGestures.begin(),
+ e = maybeGestures.end();
+ for (; it != e; ) {
+ QBasicTimer &timer = it.value();
+ Q_ASSERT(timer.isActive());
+ if (timer.timerId() == event->timerId()) {
+ timer.stop();
+ QGesture *gesture = it.key();
+ it = maybeGestures.erase(it);
+ DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:" << gesture;
+ QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0);
+ if (recognizer)
+ recognizer->reset(gesture);
+ } else {
+ ++it;
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qgesturemanager_p.cpp"
diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h
new file mode 100644
index 0000000..c61819f
--- /dev/null
+++ b/src/gui/kernel/qgesturemanager_p.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** 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 QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** 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$
+**
+****************************************************************************/
+
+#ifndef QGESTUREMANAGER_P_H
+#define QGESTUREMANAGER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qobject.h"
+#include "qbasictimer.h"
+#include "private/qwidget_p.h"
+#include "qgesturerecognizer.h"
+
+QT_BEGIN_NAMESPACE
+
+class QBasicTimer;
+class QGestureManager : public QObject
+{
+ Q_OBJECT
+public:
+ QGestureManager(QObject *parent);
+ ~QGestureManager();
+
+ Qt::GestureType registerGestureRecognizer(QGestureRecognizer *recognizer);
+ void unregisterGestureRecognizer(Qt::GestureType type);
+
+ bool filterEvent(QObject *receiver, QEvent *event);
+
+ // declared in qapplication.cpp
+ static QGestureManager* instance();
+
+protected:
+ void timerEvent(QTimerEvent *event);
+
+private:
+ QMultiMap<Qt::GestureType, QGestureRecognizer *> recognizers;
+
+ QSet<QGesture *> activeGestures;
+ QMap<QGesture *, QBasicTimer> maybeGestures;
+
+ enum State {
+ Gesture,
+ NotGesture,
+ MaybeGesture // this means timers are up and waiting for some
+ // more events, and input events are handled by
+ // gesture recognizer explicitely
+ } state;
+
+ struct ObjectGesture
+ {
+ QWeakPointer<QObject> object;
+ Qt::GestureType gesture;
+
+ ObjectGesture(QObject *o, const Qt::GestureType &g) : object(o), gesture(g) { }
+ inline bool operator<(const ObjectGesture& rhs) const
+ {
+ if (object.data() < rhs.object.data())
+ return true;
+ if (object == rhs.object)
+ return gesture < rhs.gesture;
+ return false;
+ }
+ };
+
+ QMap<ObjectGesture, QWeakPointer<QGesture> > objectGestures;
+ QMap<QGesture *, QGestureRecognizer *> gestureToRecognizer;
+
+ QHash<QGesture *, QObject *> gestureTargets;
+
+ int lastCustomGestureId;
+
+ QGesture *getState(QObject *widget, Qt::GestureType gesture);
+ void deliverEvents(const QSet<QGesture *> &gestures, QObject *lastReceiver);
+};
+
+QT_END_NAMESPACE
+
+#endif // QGESTUREMANAGER_P_H
diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp
new file mode 100644
index 0000000..2af087f
--- /dev/null
+++ b/src/gui/kernel/qgesturerecognizer.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** 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 QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** 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$
+**
+****************************************************************************/
+
+#include "qgesturerecognizer.h"
+
+#include "private/qgesture_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QGestureRecognizer
+ \since 4.6
+ \brief The QGestureRecognizer class provides the infrastructure for gesture recognition.
+
+ Gesture recognizers are responsible for creating and managing QGesture objects and
+ monitoring input events sent to QWidget and QGraphicsObject subclasses.
+ QGestureRecognizer is the base class for implementing custom gestures.
+
+ Developers that only need to provide gesture recognition for standard gestures do not
+ need to use this class directly. Instances will be created behind the scenes by the
+ framework.
+
+ \section1 Recognizing Gestures
+
+ The process of recognizing gestures involves filtering input events sent to specific
+ 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
+ for a particular target QWidget or QGraphicsObject instance. Once a QGesture has been
+ created for one of these objects, the gesture recognizer will receive events for it
+ in its filterEvent() 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.
+
+ \section1 Supporting New Gestures
+
+ To add support for new gestures, you need to derive from QGestureRecognizer to create
+ a custom recognizer class and register it with the application by calling
+ QApplication::registerGestureRecognizer(). You can also derive from 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, the state of
+ recognition for each target object can be recorded in the QGesture object supplied.
+
+ 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.
+ Similarly, you may need to reimplement the reset() function if your custom gesture
+ objects need to be specially handled when a gesture is canceled.
+
+ \sa QGesture
+*/
+
+/*!
+ \enum QGestureRecognizer::ResultFlags
+
+ 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
+ (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,
+ 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
+ may be reset automatically if they take too long to recognize gestures.
+
+ \value GestureTriggered 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
+ 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()
+*/
+
+/*!
+ Constructs a new gesture recognizer object.
+*/
+QGestureRecognizer::QGestureRecognizer()
+{
+}
+
+/*!
+ Destroys the gesture recognizer.
+*/
+QGestureRecognizer::~QGestureRecognizer()
+{
+}
+
+/*!
+ This function is called by Qt to create a new QGesture object for the
+ given \a target (QWidget or QGraphicsObject).
+
+ Reimplement this function to create a custom QGesture-derived gesture
+ object if necessary.
+*/
+QGesture *QGestureRecognizer::createGesture(QObject *target)
+{
+ Q_UNUSED(target);
+ return new QGesture;
+}
+
+/*!
+ This function is called by the framework to reset a given \a gesture.
+
+ Reimplement this function to implement additional requirements for custom QGesture
+ objects. This may be necessary if you implement a custom QGesture whose properties
+ need special handling when the gesture is reset.
+*/
+void QGestureRecognizer::reset(QGesture *gesture)
+{
+ if (gesture) {
+ QGesturePrivate *d = gesture->d_func();
+ d->state = Qt::NoGesture;
+ d->hotSpot = QPointF();
+ d->targetObject = 0;
+ }
+}
+
+/*!
+ \fn QGestureRecognizer::filterEvent(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.
+
+ This function is called by the framework to allow the recognizer to filter input events
+ dispatched to QWidget or QGraphicsObject instances that it is monitoring.
+
+ 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
+*/
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qgesturerecognizer.h b/src/gui/kernel/qgesturerecognizer.h
new file mode 100644
index 0000000..efd8565
--- /dev/null
+++ b/src/gui/kernel/qgesturerecognizer.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** 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 QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** 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$
+**
+****************************************************************************/
+
+#ifndef QGESTURERECOGNIZER_H
+#define QGESTURERECOGNIZER_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QObject;
+class QEvent;
+class QGesture;
+class Q_GUI_EXPORT QGestureRecognizer
+{
+public:
+ enum ResultFlags
+ {
+ Ignore = 0x0001,
+ NotGesture = 0x0002,
+ MaybeGesture = 0x0004,
+ GestureTriggered = 0x0008, // Gesture started or updated
+ GestureFinished = 0x0010,
+
+ ResultState_Mask = 0x00ff,
+
+ ConsumeEventHint = 0x0100,
+ // StoreEventHint = 0x0200,
+ // ReplayStoredEventsHint = 0x0400,
+ // DiscardStoredEventsHint = 0x0800,
+
+ ResultHint_Mask = 0xff00
+ };
+ Q_DECLARE_FLAGS(Result, ResultFlags)
+
+ QGestureRecognizer();
+ virtual ~QGestureRecognizer();
+
+ virtual QGesture *createGesture(QObject *target);
+ virtual QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event) = 0;
+
+ virtual void reset(QGesture *state);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGestureRecognizer::Result)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGESTURERECOGNIZER_H
diff --git a/src/gui/kernel/qguifunctions_wince.cpp b/src/gui/kernel/qguifunctions_wince.cpp
index 048780e..58e12ee 100644
--- a/src/gui/kernel/qguifunctions_wince.cpp
+++ b/src/gui/kernel/qguifunctions_wince.cpp
@@ -329,17 +329,14 @@ void qt_wince_maximize(QWidget *widget)
void qt_wince_minimize(HWND hwnd)
{
- uint exstyle = GetWindowLongW(hwnd, GWL_EXSTYLE);
- uint style = GetWindowLongW(hwnd, GWL_STYLE);
- RECT rect;
- RECT crect = {0,0,0,0};
- GetWindowRect(hwnd, &rect);
- AdjustWindowRectEx(&crect, style & ~WS_OVERLAPPED, FALSE, exstyle);
- MoveWindow(hwnd, rect.left - crect.left, rect.top - crect.top, 0, 0, true);
- SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong (hwnd, GWL_EXSTYLE) | WS_EX_NODRAG);
#ifdef Q_OS_WINCE_WM
ShowWindow(hwnd, SW_HIDE);
#else
+ if (!IsWindowVisible(hwnd)) {
+ // Hack for an initial showMinimized.
+ // Without it, our widget doesn't appear in the task bar.
+ ShowWindow(hwnd, SW_SHOW);
+ }
ShowWindow(hwnd, SW_MINIMIZE);
#endif
}
diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/gui/kernel/qguiplatformplugin.cpp
new file mode 100644
index 0000000..69e6290
--- /dev/null
+++ b/src/gui/kernel/qguiplatformplugin.cpp
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** 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 QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** 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$
+**
+****************************************************************************/
+
+#include "qguiplatformplugin_p.h"
+#include <qdebug.h>
+#include <qfile.h>
+#include <qdir.h>
+#include <qsettings.h>
+#include "private/qfactoryloader_p.h"
+#include "qstylefactory.h"
+#include "qapplication.h"
+#include "qplatformdefs.h"
+#include "qicon.h"
+
+#ifdef Q_WS_WINCE
+#include "qguifunctions_wince.h"
+extern bool qt_wince_is_smartphone(); //qguifunctions_wince.cpp
+extern bool qt_wince_is_mobile(); //qguifunctions_wince.cpp
+extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp
+#endif
+
+
+#if defined(Q_WS_X11)
+#include "qkde_p.h"
+#include "qt_x11_p.h"
+#include <private/gtksymbols_p.h>
+#endif
+
+
+QT_BEGIN_NAMESPACE
+
+
+/*! \internal
+ Return (an construct if necesseray) the Gui Platform plugin.
+
+ The plugin key to be loaded is inside the QT_PLATFORM_PLUGIN environment variable.
+ If it is not set, it will be the DESKTOP_SESSION on X11.
+
+ If no plugin can be loaded, the default one is returned.
+ */
+QGuiPlatformPlugin *qt_guiPlatformPlugin()
+{
+ static QGuiPlatformPlugin *plugin;
+ if (!plugin)
+ {
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+
+ QString key = QString::fromLocal8Bit(qgetenv("QT_PLATFORM_PLUGIN"));
+#ifdef Q_WS_X11
+ if (key.isEmpty()) {
+ switch(X11->desktopEnvironment) {
+ case DE_KDE:
+ key = QString::fromLatin1("kde");
+ break;
+ default:
+ key = QString::fromLocal8Bit(qgetenv("DESKTOP_SESSION"));
+ break;
+ }
+ }
+#endif
+
+ if (!key.isEmpty() && QApplication::desktopSettingsAware()) {
+ QFactoryLoader loader(QGuiPlatformPluginInterface_iid, QLatin1String("/gui_platform"));
+ plugin = qobject_cast<QGuiPlatformPlugin *>(loader.instance(key));
+ }
+#endif // QT_NO_LIBRARY
+
+ if(!plugin) {
+ static QGuiPlatformPlugin def;
+ plugin = &def;
+ }
+ }
+ return plugin;
+}
+
+
+/* \class QPlatformPlugin
+ QGuiPlatformPlugin can be used to integrate Qt applications in a platform built on top of Qt.
+ The application developer should not know or use the plugin, it is only used by Qt internaly.
+
+ But full platform that are built on top of Qt may provide a plugin so 3rd party Qt application
+ running in the platform are integrated.
+ */
+
+/*
+ The constructor can be used to install hooks in Qt
+ */
+QGuiPlatformPlugin::QGuiPlatformPlugin(QObject *parent) : QObject(parent) {}
+QGuiPlatformPlugin::~QGuiPlatformPlugin() {}
+
+
+/* return the string key to be used by default the application */
+QString QGuiPlatformPlugin::styleName()
+{
+#if defined(Q_WS_WIN) && defined(Q_WS_WINCE)
+ if (qt_wince_is_smartphone() || qt_wince_is_pocket_pc())
+ return QLatin1String("WindowsMobile");
+ else
+ return QLatin1String("WindowsCE");
+#elif defined(Q_WS_WIN)
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
+ return QLatin1String("WindowsVista");
+ else if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
+ return QLatin1String("WindowsXP");
+ else
+ return QLatin1String("Windows"); // default styles for Windows
+#elif defined(Q_WS_X11) && defined(Q_OS_SOLARIS)
+ return QLatin1String("CDE"); // default style for X11 on Solaris
+#elif defined(Q_WS_S60)
+ return QLatin1String("S60"); // default style for Symbian with S60
+#elif defined(Q_OS_SYMBIAN)
+ return QLatin1String("Windows"); // default style for Symbian without S60
+#elif defined(Q_WS_X11) && defined(Q_OS_IRIX)
+ return QLatin1String("SGI"); // default style for X11 on IRIX
+#elif defined(Q_WS_QWS) || defined(Q_WS_LITE)
+ return QLatin1String("Plastique"); // default style for X11 and small devices
+#elif defined(Q_WS_MAC)
+ return QLatin1String("Macintosh"); // default style for all Mac's
+#elif defined(Q_WS_X11)
+ QString stylename;
+ switch(X11->desktopEnvironment) {
+ case DE_KDE:
+ stylename = QKde::kdeStyle();
+ break;
+ case DE_GNOME: {
+ QStringList availableStyles = QStyleFactory::keys();
+ // Set QGtkStyle for GNOME if available
+ QString gtkStyleKey = QString::fromLatin1("GTK+");
+ if (availableStyles.contains(gtkStyleKey)) {
+ stylename = gtkStyleKey;
+ break;
+ }
+ if (X11->use_xrender)
+ stylename = QLatin1String("cleanlooks");
+ else
+ stylename = QLatin1String("windows");
+ break;
+ }
+ case DE_CDE:
+ stylename = QLatin1String("cde");
+ break;
+ default:
+ // Don't do anything
+ break;
+ }
+ return stylename;
+#endif
+}
+
+/* return an aditional default palette (only work on X11) */
+QPalette QGuiPlatformPlugin::palette()
+{
+#ifdef Q_WS_X11
+ if (QApplication::desktopSettingsAware() && X11->desktopEnvironment == DE_KDE)
+ return QKde::kdePalette();
+#endif
+
+ return QPalette();
+}
+
+/* the default icon theme name for QIcon::fromTheme. */
+QString QGuiPlatformPlugin::systemIconThemeName()
+{
+ QString result;
+#ifdef Q_WS_X11
+ if (X11->desktopEnvironment == DE_GNOME) {
+ result = QString::fromLatin1("gnome");
+#ifndef QT_NO_STYLE_GTK
+ result = QGtk::getGConfString(QLatin1String("/desktop/gnome/interface/icon_theme"), result);
+#endif
+ } else if (X11->desktopEnvironment == DE_KDE) {
+ result = X11->desktopVersion >= 4 ? QString::fromLatin1("oxygen") : QString::fromLatin1("crystalsvg");
+ QSettings settings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
+ settings.beginGroup(QLatin1String("Icons"));
+ result = settings.value(QLatin1String("Theme"), result).toString();
+ }
+#endif
+ return result;
+}
+
+
+QStringList QGuiPlatformPlugin::iconThemeSearchPaths()
+{
+ QStringList paths;
+#if defined(Q_WS_X11)
+ QString xdgDirString = QFile::decodeName(getenv("XDG_DATA_DIRS"));
+ if (xdgDirString.isEmpty())
+ xdgDirString = QLatin1String("/usr/local/share/:/usr/share/");
+
+ QStringList xdgDirs = xdgDirString.split(QLatin1Char(':'));
+
+ for (int i = 0 ; i < xdgDirs.size() ; ++i) {
+ QDir dir(xdgDirs[i]);
+ if (dir.exists())
+ paths.append(dir.path() + QLatin1String("/icons"));
+ }
+ if (X11->desktopEnvironment == DE_KDE) {
+ paths << QLatin1Char(':') + QKde::kdeHome() + QLatin1String("/share/icons");
+ QStringList kdeDirs = QFile::decodeName(getenv("KDEDIRS")).split(QLatin1Char(':'));
+ for (int i = 0 ; i< kdeDirs.count() ; ++i) {
+ QDir dir(QLatin1Char(':') + kdeDirs.at(i) + QLatin1String("/share/icons"));
+ if (dir.exists())
+ paths.append(dir.path());
+ }
+ }
+
+ // Add home directory first in search path
+ QDir homeDir(QDir::homePath() + QLatin1String("/.icons"));
+ if (homeDir.exists())
+ paths.prepend(homeDir.path());
+#endif
+
+#if defined(Q_WS_WIN)
+ paths.append(qApp->applicationDirPath() + QLatin1String("/icons"));
+#elif defined(Q_WS_MAC)
+ paths.append(qApp->applicationDirPath() + QLatin1String("/../Resources/icons"));
+#endif
+ return paths;
+}
+
+/* backend for QFileIconProvider, null icon means default */
+QIcon QGuiPlatformPlugin::fileSystemIcon(const QFileInfo &)
+{
+ return QIcon();
+}
+
+/* Like QStyle::styleHint */
+int QGuiPlatformPlugin::platformHint(PlatformHint hint)
+{
+ int ret = 0;
+ switch(hint)
+ {
+ case PH_ToolButtonStyle:
+ ret = Qt::ToolButtonIconOnly;
+#ifdef Q_WS_X11
+ if (X11->desktopEnvironment == DE_KDE && X11->desktopVersion >= 4
+ && QApplication::desktopSettingsAware()) {
+ ret = QKde::kdeToolButtonStyle();
+ }
+#endif
+ break;
+ case PH_ToolBarIconSize:
+#ifdef Q_WS_X11
+ if (X11->desktopEnvironment == DE_KDE && X11->desktopVersion >= 4
+ && QApplication::desktopSettingsAware()) {
+ ret = QKde::kdeToolBarIconSize();
+ }
+#endif
+ //by default keep ret = 0 so QCommonStyle will use the style default
+ break;
+ }
+ return ret;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qguiplatformplugin_p.h b/src/gui/kernel/qguiplatformplugin_p.h
new file mode 100644
index 0000000..2a70ee7
--- /dev/null
+++ b/src/gui/kernel/qguiplatformplugin_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** 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 QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** 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$
+**
+****************************************************************************/
+
+#ifndef QGUIPLATFORM_P_H
+#define QGUIPLATFORM_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+#include <QtGui/qdialog.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QStyle;
+class QPalette;
+class QIcon;
+class QFileDialog;
+class QColorDialog;
+class QFileInfo;
+
+struct Q_GUI_EXPORT QGuiPlatformPluginInterface : public QFactoryInterface
+{
+};
+
+#define QGuiPlatformPluginInterface_iid "com.nokia.qt.QGuiPlatformPluginInterface"
+
+Q_DECLARE_INTERFACE(QGuiPlatformPluginInterface, QGuiPlatformPluginInterface_iid)
+
+class Q_GUI_EXPORT QGuiPlatformPlugin : public QObject, public QGuiPlatformPluginInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QGuiPlatformPluginInterface:QFactoryInterface)
+ public:
+ explicit QGuiPlatformPlugin(QObject *parent = 0);
+ ~QGuiPlatformPlugin();
+
+ virtual QStringList keys() const { return QStringList() << QLatin1String("default"); };
+
+ virtual QString styleName();
+ virtual QPalette palette();
+ virtual QString systemIconThemeName();
+ virtual QStringList iconThemeSearchPaths();
+ virtual QIcon fileSystemIcon(const QFileInfo &);
+
+ enum PlatformHint { PH_ToolButtonStyle, PH_ToolBarIconSize, PH_ItemView_ActivateItemOnSingleClick };
+ virtual int platformHint(PlatformHint hint);
+
+
+ virtual void fileDialogDelete(QFileDialog *) {}
+ virtual bool fileDialogSetVisible(QFileDialog *, bool) { return false; }
+ virtual QDialog::DialogCode fileDialogResultCode(QFileDialog *) { return QDialog::Rejected; }
+ virtual void fileDialogSetDirectory(QFileDialog *, const QString &) {}
+ virtual QString fileDialogDirectory(const QFileDialog *) const { return QString(); }
+ virtual void fileDialogSelectFile(QFileDialog *, const QString &) {}
+ virtual QStringList fileDialogSelectedFiles(const QFileDialog *) const { return QStringList(); }
+ virtual void fileDialogSetFilter(QFileDialog *) {}
+ virtual void fileDialogSetNameFilters(QFileDialog *, const QStringList &) {}
+ virtual void fileDialogSelectNameFilter(QFileDialog *, const QString &) {}
+ virtual QString fileDialogSelectedNameFilter(const QFileDialog *) const { return QString(); }
+
+ virtual void colorDialogDelete(QColorDialog *) {}
+ virtual bool colorDialogSetVisible(QColorDialog *, bool) { return false; }
+ virtual void colorDialogSetCurrentColor(QColorDialog *, const QColor &) {}
+};
+
+//internal
+QGuiPlatformPlugin *qt_guiPlatformPlugin();
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+
+#endif // QGUIPLATFORMPLUGIN_H
diff --git a/src/gui/kernel/qkde.cpp b/src/gui/kernel/qkde.cpp
index 6c8909f..edc53ac 100644
--- a/src/gui/kernel/qkde.cpp
+++ b/src/gui/kernel/qkde.cpp
@@ -141,14 +141,33 @@ QString QKde::kdeStyle()
return QLatin1String("windows");
}
-/*!\internal
- placeholder to load icon from kde.
- to be implemented
- */
-QIcon QKde::kdeIcon(const QString &name)
+
+int QKde::kdeToolButtonStyle()
+{
+ QSettings settings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"),
+ QSettings::IniFormat);
+ settings.beginGroup(QLatin1String("Toolbar style"));
+ QString toolbarStyle = settings.value(QLatin1String("ToolButtonStyle"), QLatin1String("TextBesideIcon")).toString();
+ if (toolbarStyle == QLatin1String("TextBesideIcon"))
+ return Qt::ToolButtonTextBesideIcon;
+ else if (toolbarStyle == QLatin1String("TextOnly"))
+ return Qt::ToolButtonTextOnly;
+ else if (toolbarStyle == QLatin1String("TextUnderIcon"))
+ return Qt::ToolButtonTextUnderIcon;
+
+ return Qt::ToolButtonTextBesideIcon;
+}
+
+int QKde::kdeToolBarIconSize()
{
- //###todo
- return QIcon();
+ static int iconSize = -1;
+ if (iconSize == -1) {
+ QSettings settings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"),
+ QSettings::IniFormat);
+ settings.beginGroup(QLatin1String("ToolbarIcons"));
+ iconSize = settings.value(QLatin1String("Size")).toInt();
+ }
+ return iconSize;
}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qkde_p.h b/src/gui/kernel/qkde_p.h
index 4063f0e..c22a145 100644
--- a/src/gui/kernel/qkde_p.h
+++ b/src/gui/kernel/qkde_p.h
@@ -61,12 +61,17 @@
QT_BEGIN_NAMESPACE
-// This namespace contains helper function to help KDE integration
+/*!\internal
+ This namespace contains helper function to help KDE integration
+ They are only used if we detect the use of KDE and the KDE platform plugin is not found (old KDE version)
+ Or if the detected KDE version is KDE3
+*/
namespace QKde {
QString kdeHome();
QString kdeStyle();
QPalette kdePalette();
- QIcon kdeIcon(const QString &name);
+ int kdeToolButtonStyle();
+ int kdeToolBarIconSize();
}
diff --git a/src/gui/kernel/qkeymapper_win.cpp b/src/gui/kernel/qkeymapper_win.cpp
index 402d88e..be207df 100644
--- a/src/gui/kernel/qkeymapper_win.cpp
+++ b/src/gui/kernel/qkeymapper_win.cpp
@@ -433,6 +433,23 @@ static const Qt::KeyboardModifiers ModsTbl[] = {
Qt::NoModifier, // Fall-back to raw Key_*
};
+/**
+ Remap return or action key to select key for windows mobile.
+*/
+inline int winceKeyBend(int keyCode)
+{
+#ifdef Q_OS_WINCE_WM
+ // remap return or action key to select key for windows mobile.
+ // will be changed to a table remapping function in the next version (4.6/7).
+ if (keyCode == 13)
+ return Qt::Key_Select;
+ else
+ return KeyTbl[keyCode];
+#else
+ return KeyTbl[keyCode];
+#endif
+}
+
#if defined(Q_OS_WINCE)
// Use the KeyTbl to resolve a Qt::Key out of the virtual keys.
// In case it is not resolvable, continue using the virtual key itself.
@@ -472,7 +489,7 @@ static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer,
// Qt::Key_*'s are not encoded below 0x20, so try again, and DEL keys (0x7f) is encoded with a
// proper Qt::Key_ code
if (code < 0x20 || code == 0x7f) // Handles res==0 too
- code = KeyTbl[vk];
+ code = winceKeyBend(vk);
if (isDeadkey)
*isDeadkey = (res == -1);
@@ -482,7 +499,7 @@ static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer,
Q_GUI_EXPORT int qt_translateKeyCode(int vk)
{
- int code = (vk < 0 || vk > 255) ? 0 : KeyTbl[vk];
+ int code = winceKeyBend((vk < 0 || vk > 255) ? 0 : vk);
return code == Qt::Key_unknown ? 0 : code;
}
@@ -689,7 +706,7 @@ void QKeyMapperPrivate::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32
keyLayout[vk_key]->qtKey[7] = toKeyOrUnicode(vk_key, scancode, buffer, &isDeadKey);
keyLayout[vk_key]->deadkeys |= isDeadKey ? 0x80 : 0;
// Add a fall back key for layouts which don't do composition and show non-latin1 characters
- int fallbackKey = KeyTbl[vk_key];
+ int fallbackKey = winceKeyBend(vk_key);
if (!fallbackKey || fallbackKey == Qt::Key_unknown) {
fallbackKey = 0;
if (vk_key != keyLayout[vk_key]->qtKey[0] && vk_key < 0x5B && vk_key > 0x2F)
@@ -888,8 +905,8 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool
if(msg.wParam == VK_PROCESSKEY)
return true;
- // Ignore invalid virtual keycode (see bug 127424)
- if (msg.wParam == 0xFF)
+ // Ignore invalid virtual keycodes (see bugs 127424, QTBUG-3630)
+ if (msg.wParam == 0 || msg.wParam == 0xFF)
return true;
// Translate VK_* (native) -> Key_* (Qt) keys
@@ -898,7 +915,7 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool
// ..also if we're typing numbers on the keypad, while holding down the Alt modifier.
int code = 0;
if (isNumpad && (nModifiers & AltAny)) {
- code = KeyTbl[msg.wParam];
+ code = winceKeyBend(msg.wParam);
} else if (!isDeadKey) {
unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
GetKeyboardState(kbdBuffer);
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index aec757f..b44ef7f 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -571,7 +571,7 @@ const QKeyBinding QKeySequencePrivate::keyBindings[] = {
{QKeySequence::Close, 0, Qt::CTRL | Qt::Key_W, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
{QKeySequence::Close, 1, Qt::CTRL | Qt::Key_W, QApplicationPrivate::KB_Mac},
{QKeySequence::Cut, 1, Qt::CTRL | Qt::Key_X, QApplicationPrivate::KB_All},
- {QKeySequence::Redo, 1, Qt::CTRL | Qt::Key_Y, QApplicationPrivate::KB_Win},
+ {QKeySequence::Redo, 1, Qt::CTRL | Qt::Key_Y, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_S60},
{QKeySequence::Redo, 0, Qt::CTRL | Qt::Key_Y, QApplicationPrivate::KB_Mac},//different priority from above
{QKeySequence::Undo, 1, Qt::CTRL | Qt::Key_Z, QApplicationPrivate::KB_All},
{QKeySequence::Back, 1, Qt::CTRL | Qt::Key_BracketLeft, QApplicationPrivate::KB_Mac},
@@ -600,7 +600,7 @@ const QKeyBinding QKeySequencePrivate::keyBindings[] = {
{QKeySequence::FindPrevious, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_G, QApplicationPrivate::KB_Win},
{QKeySequence::AddTab, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_N, QApplicationPrivate::KB_KDE},
{QKeySequence::SaveAs, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_S, QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac},
- {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
+ {QKeySequence::Redo, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
{QKeySequence::Redo, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, QApplicationPrivate::KB_Mac}, //different priority from above
{QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
{QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Mac },//different priority from above
diff --git a/src/gui/kernel/qmacgesturerecognizer_mac.mm b/src/gui/kernel/qmacgesturerecognizer_mac.mm
new file mode 100644
index 0000000..7b19a54
--- /dev/null
+++ b/src/gui/kernel/qmacgesturerecognizer_mac.mm
@@ -0,0 +1,267 @@
+/****************************************************************************
+**
+** 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 QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** 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$
+**
+****************************************************************************/
+
+#include "qmacgesturerecognizer_mac_p.h"
+#include "qgesture.h"
+#include "qgesture_p.h"
+#include "qevent.h"
+#include "qevent_p.h"
+#include "qwidget.h"
+#include "qdebug.h"
+
+QT_BEGIN_NAMESPACE
+
+QMacSwipeGestureRecognizer::QMacSwipeGestureRecognizer()
+{
+}
+
+QGesture *QMacSwipeGestureRecognizer::createGesture(QObject * /*target*/)
+{
+ return new QSwipeGesture;
+}
+
+QGestureRecognizer::Result
+QMacSwipeGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
+ QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
+ switch (ev->gestureType) {
+ case QNativeGestureEvent::Swipe: {
+ QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture);
+ g->setSwipeAngle(ev->angle);
+ return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
+ break; }
+ default:
+ break;
+ }
+ }
+
+ return QGestureRecognizer::Ignore;
+}
+
+void QMacSwipeGestureRecognizer::reset(QGesture *gesture)
+{
+ QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture);
+ g->setSwipeAngle(0);
+ QGestureRecognizer::reset(gesture);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+QMacPinchGestureRecognizer::QMacPinchGestureRecognizer()
+{
+}
+
+QGesture *QMacPinchGestureRecognizer::createGesture(QObject * /*target*/)
+{
+ return new QPinchGesture;
+}
+
+QGestureRecognizer::Result
+QMacPinchGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
+ QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
+ QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
+ switch(ev->gestureType) {
+ case QNativeGestureEvent::GestureBegin:
+ reset(gesture);
+ g->setStartCenterPoint(static_cast<QWidget*>(obj)->mapFromGlobal(ev->position));
+ g->setCenterPoint(g->startCenterPoint());
+ g->setWhatChanged(QPinchGesture::CenterPointChanged);
+ 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;
+ }
+ 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;
+ case QNativeGestureEvent::GestureEnd:
+ return QGestureRecognizer::GestureFinished | QGestureRecognizer::ConsumeEventHint;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return QGestureRecognizer::Ignore;
+}
+
+void QMacPinchGestureRecognizer::reset(QGesture *gesture)
+{
+ QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
+ g->setWhatChanged(0);
+ g->setScaleFactor(1.0f);
+ g->setTotalScaleFactor(1.0f);
+ g->setLastScaleFactor(1.0f);
+ g->setRotationAngle(0.0f);
+ g->setTotalRotationAngle(0.0f);
+ g->setLastRotationAngle(0.0f);
+ g->setCenterPoint(QPointF());
+ g->setStartCenterPoint(QPointF());
+ g->setLastCenterPoint(QPointF());
+ QGestureRecognizer::reset(gesture);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#if defined(QT_MAC_USE_COCOA)
+
+QMacPanGestureRecognizer::QMacPanGestureRecognizer() : _panCanceled(true)
+{
+}
+
+QGesture *QMacPanGestureRecognizer::createGesture(QObject *target)
+{
+ if (!target)
+ return new QPanGesture;
+
+ if (QWidget *w = qobject_cast<QWidget *>(target)) {
+ w->setAttribute(Qt::WA_AcceptTouchEvents);
+ w->setAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
+ return new QPanGesture;
+ }
+ return 0;
+}
+
+QGestureRecognizer::Result
+QMacPanGestureRecognizer::filterEvent(QGesture *gesture, QObject *target, QEvent *event)
+{
+ const int panBeginDelay = 300;
+ const int panBeginRadius = 3;
+
+ QPanGesture *g = static_cast<QPanGesture *>(gesture);
+
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ if (ev->touchPoints().size() == 1) {
+ reset(gesture);
+ _startPos = QCursor::pos();
+ _lastPos = _startPos;
+ _panTimer.start(panBeginDelay, target);
+ _panCanceled = false;
+ return QGestureRecognizer::MaybeGesture;
+ }
+ break;}
+ case QEvent::TouchEnd: {
+ if (_panCanceled)
+ break;
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ if (ev->touchPoints().size() == 1)
+ return QGestureRecognizer::GestureFinished;
+ break;}
+ case QEvent::TouchUpdate: {
+ if (_panCanceled)
+ break;
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ if (ev->touchPoints().size() == 1) {
+ if (_panTimer.isActive()) {
+ // INVARIANT: Still in maybeGesture. Check if the user
+ // moved his finger so much that it makes sense to cancel the pan:
+ const QPointF p = QCursor::pos();
+ if ((p - _startPos).manhattanLength() > panBeginRadius) {
+ _panCanceled = true;
+ _panTimer.stop();
+ return QGestureRecognizer::NotGesture;
+ }
+ } else {
+ const QPointF p = QCursor::pos();
+ const QPointF posOffset = p - _lastPos;
+ g->setLastOffset(g->offset());
+ g->setOffset(QSizeF(posOffset.x(), posOffset.y()));
+ g->setTotalOffset(g->lastOffset() + g->offset());
+ _lastPos = p;
+ return QGestureRecognizer::GestureTriggered;
+ }
+ } 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;
+ }
+ break;}
+ case QEvent::Timer: {
+ QTimerEvent *ev = static_cast<QTimerEvent *>(event);
+ if (ev->timerId() == _panTimer.timerId()) {
+ _panTimer.stop();
+ if (_panCanceled)
+ break;
+ // Begin new pan session!
+ _startPos = QCursor::pos();
+ _lastPos = _startPos;
+ return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
+ }
+ break; }
+ default:
+ break;
+ }
+
+ return QGestureRecognizer::Ignore;
+}
+
+void QMacPanGestureRecognizer::reset(QGesture *gesture)
+{
+ QPanGesture *g = static_cast<QPanGesture *>(gesture);
+ _startPos = QPointF();
+ _lastPos = QPointF();
+ _panCanceled = true;
+ g->setOffset(QSizeF(0, 0));
+ g->setLastOffset(QSizeF(0, 0));
+ g->setTotalOffset(QSizeF(0, 0));
+ g->setAcceleration(qreal(1));
+ QGestureRecognizer::reset(gesture);
+}
+#endif // QT_MAC_USE_COCOA
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qmacgesturerecognizer_mac_p.h b/src/gui/kernel/qmacgesturerecognizer_mac_p.h
new file mode 100644
index 0000000..bdc2e08
--- /dev/null
+++ b/src/gui/kernel/qmacgesturerecognizer_mac_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** 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 QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** 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$
+**
+****************************************************************************/
+
+#ifndef QMACSWIPEGESTURERECOGNIZER_MAC_P_H
+#define QMACSWIPEGESTURERECOGNIZER_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtimer.h"
+#include "qpoint.h"
+#include "qgesturerecognizer.h"
+
+QT_BEGIN_NAMESPACE
+
+class QMacSwipeGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QMacSwipeGestureRecognizer();
+
+ QGesture *createGesture(QObject *target);
+ QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event);
+ void reset(QGesture *gesture);
+};
+
+class QMacPinchGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QMacPinchGestureRecognizer();
+
+ QGesture *createGesture(QObject *target);
+ QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event);
+ void reset(QGesture *gesture);
+};
+
+#if defined(QT_MAC_USE_COCOA)
+
+class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer
+{
+public:
+ QMacPanGestureRecognizer();
+
+ QGesture *createGesture(QObject *target);
+ QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event);
+ void reset(QGesture *gesture);
+private:
+ QPointF _startPos;
+ QPointF _lastPos;
+ QBasicTimer _panTimer;
+ bool _panCanceled;
+};
+
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QMACSWIPEGESTURERECOGNIZER_MAC_P_H
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp
index 45695d9..1214f08 100644
--- a/src/gui/kernel/qsoftkeymanager.cpp
+++ b/src/gui/kernel/qsoftkeymanager.cpp
@@ -112,7 +112,7 @@ QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *act
{
const char* text = standardSoftKeyText(standardKey);
QAction *action = new QAction(QSoftKeyManager::tr(text), actionWidget);
- QAction::SoftKeyRole softKeyRole;
+ QAction::SoftKeyRole softKeyRole = QAction::NoSoftKey;
switch (standardKey) {
case OkSoftKey:
case SelectSoftKey:
@@ -200,6 +200,7 @@ bool QSoftKeyManager::event(QEvent *e)
void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys)
{
CEikButtonGroupContainer* nativeContainer = S60->buttonGroupContainer();
+ nativeContainer->DrawableWindow()->SetPointerCapturePriority(1); //keep softkeys available in modal dialog
QT_TRAP_THROWING(nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS));
int position = -1;
diff --git a/src/gui/kernel/qsoftkeymanager_p.h b/src/gui/kernel/qsoftkeymanager_p.h
index c4bb84d..b455445 100644
--- a/src/gui/kernel/qsoftkeymanager_p.h
+++ b/src/gui/kernel/qsoftkeymanager_p.h
@@ -74,7 +74,7 @@ public:
SelectSoftKey,
DoneSoftKey,
MenuSoftKey,
- CancelSoftKey,
+ CancelSoftKey
};
static void updateSoftKeys();
diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp
index bcc411a..dfc3499 100644
--- a/src/gui/kernel/qstandardgestures.cpp
+++ b/src/gui/kernel/qstandardgestures.cpp
@@ -39,173 +39,45 @@
**
****************************************************************************/
-#include "qstandardgestures.h"
#include "qstandardgestures_p.h"
-
-#include <qabstractscrollarea.h>
-#include <qscrollbar.h>
-#include <private/qapplication_p.h>
-#include <private/qevent_p.h>
-#include <private/qwidget_p.h>
-#include <qmath.h>
+#include "qgesture.h"
+#include "qgesture_p.h"
+#include "qevent.h"
+#include "qwidget.h"
QT_BEGIN_NAMESPACE
-#ifdef Q_WS_WIN
-QWidgetPrivate *qt_widget_private(QWidget *widget);
-#endif
-
-/*!
- \class QPanGesture
- \since 4.6
-
- \brief The QPanGesture class represents a Pan gesture,
- providing additional information related to panning.
-*/
-
-/*!
- \enum QSwipeGesture::SwipeDirection
- \brief This enum specifies the direction of the swipe gesture.
-
- \value NoDirection
- \value Left
- \value Right
- \value Up
- \value Down
-*/
-
-/*!
- Creates a new pan gesture handler object and marks it as a child of
- \a parent. The pan gesture handler watches \a gestureTarget for its
- events.
-
- On some platform like Windows it's necessary to provide a non-null
- widget as \a parent to get native gesture support.
-*/
-QPanGesture::QPanGesture(QWidget *gestureTarget, QObject *parent)
- : QGesture(*new QPanGesturePrivate, gestureTarget, parent)
+QPanGestureRecognizer::QPanGestureRecognizer()
{
- setObjectName(QLatin1String("QPanGesture"));
-}
-
-void QPanGesturePrivate::setupGestureTarget(QObject *newGestureTarget)
-{
- Q_Q(QPanGesture);
- QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
-
- if (gestureTarget && gestureTarget->isWidgetType()) {
- QWidget *w = static_cast<QWidget*>(gestureTarget.data());
- if (qAppPriv->widgetGestures[w].pan == q)
- qAppPriv->widgetGestures[w].pan = 0;
-#if defined(Q_WS_WIN)
- qt_widget_private(w)->winSetupGestures();
-#elif defined(Q_WS_MAC)
- w->setAttribute(Qt::WA_AcceptTouchEvents, false);
- w->setAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents, false);
-#endif
- }
-
- if (newGestureTarget && newGestureTarget->isWidgetType()) {
- QWidget *w = static_cast<QWidget*>(newGestureTarget);
- qAppPriv->widgetGestures[w].pan = q;
-#if defined(Q_WS_WIN)
- qt_widget_private(w)->winSetupGestures();
-#elif defined(Q_WS_MAC)
- w->setAttribute(Qt::WA_AcceptTouchEvents);
- w->setAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
-#endif
- }
- QGesturePrivate::setupGestureTarget(newGestureTarget);
-}
-
-/*! \internal */
-bool QPanGesture::event(QEvent *event)
-{
-#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);
- }
- }
-#endif
-
- return QObject::event(event);
}
-bool QPanGesture::eventFilter(QObject *receiver, QEvent *event)
+QGesture *QPanGestureRecognizer::createGesture(QObject *target)
{
- Q_D(QPanGesture);
-
- if (d->implicitGesture && d->gestureTarget && d->gestureTarget->isWidgetType() &&
- static_cast<QWidget*>(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures))
- return false;
-
-#ifdef Q_WS_WIN
- if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) {
- QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
- QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
- QApplicationPrivate::WidgetStandardGesturesMap::iterator it;
- it = qAppPriv->widgetGestures.find(static_cast<QWidget*>(receiver));
- if (it == qAppPriv->widgetGestures.end())
- return false;
- if (this != it.value().pan)
- return false;
- Qt::GestureState nextState = Qt::NoGesture;
- switch(ev->gestureType) {
- case QNativeGestureEvent::GestureBegin:
- // next we might receive the first gesture update event, so we
- // prepare for it.
- d->state = Qt::NoGesture;
- return false;
- case QNativeGestureEvent::Pan:
- nextState = Qt::GestureUpdated;
- event->accept();
- break;
- case QNativeGestureEvent::GestureEnd:
- if (state() == Qt::NoGesture)
- return false; // some other gesture has ended
- nextState = Qt::GestureFinished;
- break;
- default:
- return false;
- }
- if (state() == Qt::NoGesture) {
- d->lastOffset = d->totalOffset = d->offset = QSize();
- } else {
- d->lastOffset = d->offset;
- d->offset = QSize(ev->position.x() - d->lastPosition.x(),
- ev->position.y() - d->lastPosition.y());
- d->totalOffset += d->offset;
- }
- d->lastPosition = ev->position;
- updateState(nextState);
- return true;
+ if (target && target->isWidgetType()) {
+ static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
}
-#endif
- return QGesture::eventFilter(receiver, event);
+ return new QPanGesture;
}
-/*! \internal */
-bool QPanGesture::filterEvent(QEvent *event)
+QGestureRecognizer::Result QPanGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event)
{
- Q_D(QPanGesture);
+ QPanGesture *q = static_cast<QPanGesture*>(state);
+ QPanGesturePrivate *d = q->d_func();
- if (d->implicitGesture && d->gestureTarget && d->gestureTarget->isWidgetType() &&
- static_cast<QWidget*>(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures))
- return false;
-
-#if defined(Q_WS_WIN)
const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
- if (event->type() == QEvent::TouchBegin) {
+ QGestureRecognizer::Result result;
+
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ result = QGestureRecognizer::MaybeGesture;
QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
d->lastPosition = p.pos().toPoint();
d->lastOffset = d->totalOffset = d->offset = QSize();
- } else if (event->type() == QEvent::TouchEnd) {
- if (state() != Qt::NoGesture) {
+ break;
+ }
+ case QEvent::TouchEnd: {
+ if (q->state() != Qt::NoGesture) {
if (ev->touchPoints().size() == 2) {
QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
@@ -215,11 +87,14 @@ bool QPanGesture::filterEvent(QEvent *event)
p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2;
d->totalOffset += d->offset;
}
- updateState(Qt::GestureFinished);
+ result = QGestureRecognizer::GestureFinished;
+ } else {
+ result = QGestureRecognizer::NotGesture;
}
- reset();
- } else if (event->type() == QEvent::TouchUpdate) {
- if (ev->touchPoints().size() == 2) {
+ break;
+ }
+ case QEvent::TouchUpdate: {
+ if (ev->touchPoints().size() >= 2) {
QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
d->lastOffset = d->offset;
@@ -229,10 +104,60 @@ bool QPanGesture::filterEvent(QEvent *event)
d->totalOffset += d->offset;
if (d->totalOffset.width() > 10 || d->totalOffset.height() > 10 ||
d->totalOffset.width() < -10 || d->totalOffset.height() < -10) {
- updateState(Qt::GestureUpdated);
+ result = QGestureRecognizer::GestureTriggered;
+ } else {
+ result = QGestureRecognizer::MaybeGesture;
}
}
+ break;
+ }
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ result = QGestureRecognizer::Ignore;
+ break;
+ default:
+ result = QGestureRecognizer::Ignore;
+ break;
+ }
+ return result;
+}
+
+void QPanGestureRecognizer::reset(QGesture *state)
+{
+ QPanGesture *pan = static_cast<QPanGesture*>(state);
+ QPanGesturePrivate *d = pan->d_func();
+
+ d->totalOffset = d->lastOffset = d->offset = QSizeF();
+ d->lastPosition = QPoint();
+ d->acceleration = 0;
+
+//#if defined(QT_MAC_USE_COCOA)
+// d->singleTouchPanTimer.stop();
+// d->prevMousePos = QPointF(0, 0);
+//#endif
+
+ QGestureRecognizer::reset(state);
+}
+
+/*! \internal */
+/*
+bool QPanGestureRecognizer::event(QEvent *event)
+{
+#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);
+ }
}
+#endif
+
+ bool consume = false;
+
+#if defined(Q_WS_WIN)
#elif defined(QT_MAC_USE_COCOA)
// The following implements single touch
// panning on Mac:
@@ -243,16 +168,25 @@ bool QPanGesture::filterEvent(QEvent *event)
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);
}
break;}
case QEvent::TouchEnd: {
- if (state() != Qt::NoGesture)
+ d->delayManager->setEnabled(false);
+ if (state() != Qt::NoGesture) {
updateState(Qt::GestureFinished);
+ consume = true;
+ d->delayManager->clear();
+ } else {
+ d->delayManager->replay();
+ }
reset();
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.
@@ -260,11 +194,15 @@ bool QPanGesture::filterEvent(QEvent *event)
// 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)
+ if ((startPos - p).manhattanLength() > panBeginRadius) {
+ d->delayManager->replay();
+ consume = false;
reset();
- else
+ } else {
d->lastPosition = QCursor::pos();
+ }
} else {
+ d->delayManager->clear();
QPointF mousePos = QCursor::pos();
QPointF dist = mousePos - d->lastPosition;
d->lastPosition = mousePos;
@@ -274,525 +212,25 @@ bool QPanGesture::filterEvent(QEvent *event)
updateState(Qt::GestureUpdated);
}
} else if (state() == Qt::NoGesture) {
+ d->delayManager->replay();
+ consume = false;
reset();
}
break;}
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ if (d->delayManager->isEnabled())
+ consume = d->delayManager->append(d->gestureTarget, *event);
+ break;
default:
return false;
}
#else
Q_UNUSED(event);
#endif
- return false;
-}
-
-/*! \internal */
-void QPanGesture::reset()
-{
- Q_D(QPanGesture);
- d->lastOffset = d->totalOffset = d->offset = QSize(0, 0);
- d->lastPosition = QPoint(0, 0);
-
-#if defined(QT_MAC_USE_COCOA)
- d->singleTouchPanTimer.stop();
- d->prevMousePos = QPointF(0, 0);
-#endif
-
- QGesture::reset();
-}
-
-/*!
- \property QPanGesture::totalOffset
-
- Specifies a total pan offset since the start of the gesture.
-*/
-QSizeF QPanGesture::totalOffset() const
-{
- Q_D(const QPanGesture);
- return d->totalOffset;
-}
-
-/*!
- \property QPanGesture::lastOffset
-
- Specifies a pan offset the last time the gesture was triggered.
-*/
-QSizeF QPanGesture::lastOffset() const
-{
- Q_D(const QPanGesture);
- return d->lastOffset;
-}
-
-/*!
- \property QPanGesture::offset
-
- Specifies the current pan offset since the last time the gesture was
- triggered.
-*/
-QSizeF QPanGesture::offset() const
-{
- Q_D(const QPanGesture);
- return d->offset;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-/*!
- \class QPinchGesture
- \since 4.6
-
- \brief The QPinchGesture class represents a Pinch gesture,
- providing additional information related to zooming and/or rotation.
-*/
-
-/*!
- Creates a new Pinch gesture handler object and marks it as a child
- of \a parent. The pan gesture handler watches \a gestureTarget for its
- events.
-
- On some platform like Windows it's necessary to provide a non-null
- widget as \a parent to get native gesture support.
-*/
-QPinchGesture::QPinchGesture(QWidget *gestureTarget, QObject *parent)
- : QGesture(*new QPinchGesturePrivate, gestureTarget, parent)
-{
- setObjectName(QLatin1String("QPinchGesture"));
-}
-
-void QPinchGesturePrivate::setupGestureTarget(QObject *newGestureTarget)
-{
- Q_Q(QPinchGesture);
- if (gestureTarget && gestureTarget->isWidgetType()) {
- QWidget *w = static_cast<QWidget*>(gestureTarget.data());
- QApplicationPrivate::instance()->widgetGestures[w].pinch = 0;
-#ifdef Q_WS_WIN
- qt_widget_private(w)->winSetupGestures();
-#endif
- }
-
- if (newGestureTarget && newGestureTarget->isWidgetType()) {
- QWidget *w = static_cast<QWidget*>(newGestureTarget);
- QApplicationPrivate::instance()->widgetGestures[w].pinch = q;
-#ifdef Q_WS_WIN
- qt_widget_private(w)->winSetupGestures();
-#endif
- }
- QGesturePrivate::setupGestureTarget(newGestureTarget);
-}
-
-/*! \internal */
-bool QPinchGesture::event(QEvent *event)
-{
- return QObject::event(event);
-}
-
-bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event)
-{
- Q_D(QPinchGesture);
-
- if (d->implicitGesture && d->gestureTarget && d->gestureTarget->isWidgetType() &&
- static_cast<QWidget*>(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures))
- return false;
-
-#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
- if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) {
- QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
-#if defined(Q_WS_WIN)
- QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
- QApplicationPrivate::WidgetStandardGesturesMap::iterator it;
- it = qAppPriv->widgetGestures.find(static_cast<QWidget*>(receiver));
- if (it == qAppPriv->widgetGestures.end())
- return false;
- if (this != it.value().pinch)
- return false;
-#endif
- Qt::GestureState nextState = Qt::NoGesture;
-
- switch(ev->gestureType) {
- case QNativeGestureEvent::GestureBegin:
- // next we might receive the first gesture update event, so we
- // prepare for it.
- d->state = Qt::NoGesture;
- d->changes = 0;
- d->totalScaleFactor = d->scaleFactor = d->lastScaleFactor = 1.;
- d->totalRotationAngle = d->rotationAngle = d->lastRotationAngle = 0.;
- d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPointF();
-#if defined(Q_WS_WIN)
- d->initialDistance = 0;
- d->lastSequenceId = ev->sequenceId;
-#endif
- return false;
- case QNativeGestureEvent::Rotate: {
- d->lastScaleFactor = d->scaleFactor;
- d->lastRotationAngle = d->rotationAngle;
-#if defined(Q_WS_MAC)
- d->rotationAngle += ev->percentage;
- nextState = Qt::GestureUpdated;
-#elif defined(Q_WS_WIN)
- // This is a workaround for an issue with the native rotation
- // gesture on Windows 7. For some reason the rotation angle in the
- // first WM_GESTURE message in a sequence contains value that is
- // off a little bit and causes the rotating item to "jump", so
- // we just ignore the first WM_GESTURE in every sequence.
- bool windowsRotateWorkaround = false;
- if (!d->lastSequenceId) {
- windowsRotateWorkaround = true;
- d->lastSequenceId = ev->sequenceId;
- }
- if (d->lastSequenceId > 0 && d->lastSequenceId != (ulong)-1 && ev->sequenceId != d->lastSequenceId) {
- // this is the first WM_GESTURE message in a sequence.
- d->totalRotationAngle += d->rotationAngle;
- windowsRotateWorkaround = true;
- // a magic value to mark that the next WM_GESTURE message is
- // the second message in a sequence and we should clear the
- // lastRotationAngle
- d->lastSequenceId = (ulong)-1;
- }
- if (!windowsRotateWorkaround) {
- d->rotationAngle = -1 * GID_ROTATE_ANGLE_FROM_ARGUMENT(ev->argument) * 180. / M_PI;
- if (d->lastSequenceId == (ulong)-1) {
- // a special case since we need to set the lastRotationAngle to
- // rotationAngle when the first WM_GESTURE is received in each
- // sequence.
- d->lastRotationAngle = d->rotationAngle;
- }
- d->lastSequenceId = ev->sequenceId;
- }
- if (!windowsRotateWorkaround)
- nextState = Qt::GestureUpdated;
-#endif
- d->changes = QPinchGesture::RotationAngleChanged;
- event->accept();
- break;
- }
- case QNativeGestureEvent::Zoom:
- d->lastRotationAngle = d->rotationAngle;
- d->lastScaleFactor = d->scaleFactor;
-#if defined(Q_WS_WIN)
- if (d->initialDistance != 0) {
- int distance = int(qint64(ev->argument));
- if (d->lastSequenceId && ev->sequenceId != d->lastSequenceId) {
- d->totalScaleFactor *= d->scaleFactor;
- d->initialDistance = int(qint64(ev->argument));
- d->lastScaleFactor = d->scaleFactor = (qreal) distance / d->initialDistance;
- } else {
- d->scaleFactor = (qreal) distance / d->initialDistance;
- }
- d->lastSequenceId = ev->sequenceId;
- } else {
- d->initialDistance = int(qint64(ev->argument));
- }
-#elif defined(Q_WS_MAC)
- d->scaleFactor += ev->percentage;
-#endif
- nextState = Qt::GestureUpdated;
- d->changes = QPinchGesture::ScaleFactorChanged;
- event->accept();
- break;
- case QNativeGestureEvent::GestureEnd:
- if (state() == Qt::NoGesture)
- return false; // some other gesture has ended
- nextState = Qt::GestureFinished;
- break;
- default:
- return false;
- }
- if (d->startCenterPoint.isNull())
- d->startCenterPoint = d->centerPoint;
- d->lastCenterPoint = d->centerPoint;
- d->centerPoint = static_cast<QWidget*>(receiver)->mapFromGlobal(ev->position);
- if (d->lastCenterPoint != d->centerPoint)
- d->changes |= QPinchGesture::CenterPointChanged;
- updateState(nextState);
- return true;
- }
-#endif
- return QGesture::eventFilter(receiver, event);
-}
-
-
-/*! \internal */
-bool QPinchGesture::filterEvent(QEvent *event)
-{
- Q_D(QPinchGesture);
-
- if (d->implicitGesture && d->gestureTarget && d->gestureTarget->isWidgetType() &&
- static_cast<QWidget*>(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures))
- return false;
-
- Q_UNUSED(event);
- return false;
-}
-
-/*! \internal */
-void QPinchGesture::reset()
-{
- Q_D(QPinchGesture);
- d->changes = 0;
- d->totalScaleFactor = d->scaleFactor = d->lastScaleFactor = 1.;
- d->totalRotationAngle = d->rotationAngle = d->lastRotationAngle = 0.;
- d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPointF();
- QGesture::reset();
-}
-
-/*! \enum QPinchGesture::WhatChange
- \value ScaleFactorChanged
- \value RotationAngleChanged
- \value CenterPointChanged
-*/
-
-/*!
- \property QPinchGesture::whatChanged
-
- Specifies which values were changed in the gesture.
-*/
-QPinchGesture::WhatChanged QPinchGesture::whatChanged() const
-{
- return d_func()->changes;
-}
-
-/*!
- \property QPinchGesture::totalScaleFactor
-
- Specifies a total scale factor of the pinch gesture since the gesture
- started.
-*/
-qreal QPinchGesture::totalScaleFactor() const
-{
- Q_D(const QPinchGesture);
- return d->totalScaleFactor * d->scaleFactor;
-}
-
-/*!
- \property QPinchGesture::scaleFactor
-
- Specifies a scale factor of the pinch gesture.
-
- If the gesture consists of several pinch sequences (i.e. zoom and rotate
- sequences), then this property specifies the scale factor in the current
- sequence. When pinching changes the rotation angle only, the value of this
- property is 1.
-*/
-qreal QPinchGesture::scaleFactor() const
-{
- return d_func()->scaleFactor;
-}
-
-/*!
- \property QPinchGesture::lastScaleFactor
-
- Specifies a previous scale factor of the pinch gesture.
-*/
-qreal QPinchGesture::lastScaleFactor() const
-{
- return d_func()->lastScaleFactor;
-}
-
-/*!
- \property QPinchGesture::totalRotationAngle
-
- Specifies a total rotation angle of the gesture since the gesture started.
-
- The angle is specified in degrees.
-*/
-qreal QPinchGesture::totalRotationAngle() const
-{
- Q_D(const QPinchGesture);
- return d->totalRotationAngle + d->rotationAngle;
-}
-
-/*!
- \property QPinchGesture::rotationAngle
-
- Specifies a rotation angle of the gesture.
-
- If the gesture consists of several pinch sequences (i.e. zoom and rotate
- sequences), then this property specifies the rotation angle in the current
- sequence. When pinching changes the scale factor only, the value of this
- property is 0.
-
- The angle is specified in degrees.
-*/
-qreal QPinchGesture::rotationAngle() const
-{
- return d_func()->rotationAngle;
-}
-
-/*!
- \property QPinchGesture::lastRotationAngle
-
- Specifies a previous rotation angle of the gesture.
-
- The angle is specified in degrees.
-*/
-qreal QPinchGesture::lastRotationAngle() const
-{
- return d_func()->lastRotationAngle;
-}
-
-/*!
- \property QPinchGesture::centerPoint
-
- Specifies a center point of the gesture. The point can be used as a center
- point that the object is rotated around.
-*/
-QPointF QPinchGesture::centerPoint() const
-{
- return d_func()->centerPoint;
-}
-
-/*!
- \property QPinchGesture::lastCenterPoint
-
- Specifies a previous center point of the gesture.
-*/
-QPointF QPinchGesture::lastCenterPoint() const
-{
- return d_func()->lastCenterPoint;
-}
-
-/*!
- \property QPinchGesture::startCenterPoint
-
- Specifies an initial center point of the gesture. Difference between the
- startCenterPoint and the centerPoint is the distance at which pinching
- fingers has shifted.
-*/
-QPointF QPinchGesture::startCenterPoint() const
-{
- return d_func()->startCenterPoint;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-/*!
- \class QSwipeGesture
- \since 4.6
-
- \brief The QSwipeGesture class represents a swipe gesture,
- providing additional information related to swiping.
-*/
-
-/*!
- Creates a new Swipe gesture handler object and marks it as a
- child of \a parent. The swipe gesture handler watches \a
- gestureTarget for its events.
-
- On some platform like Windows it's necessary to provide a non-null
- widget as \a parent to get native gesture support.
-*/
-QSwipeGesture::QSwipeGesture(QWidget *gestureTarget, QObject *parent)
- : QGesture(*new QSwipeGesturePrivate, gestureTarget, parent)
-{
- setObjectName(QLatin1String("QSwipeGesture"));
-}
-
-void QSwipeGesturePrivate::setupGestureTarget(QObject *newGestureTarget)
-{
- Q_Q(QSwipeGesture);
- if (gestureTarget && gestureTarget->isWidgetType()) {
- QWidget *w = static_cast<QWidget*>(gestureTarget.data());
- QApplicationPrivate::instance()->widgetGestures[w].swipe = 0;
-#if defined(Q_WS_WIN)
- qt_widget_private(w)->winSetupGestures();
-#endif
- }
-
- if (newGestureTarget && newGestureTarget->isWidgetType()) {
- QWidget *w = static_cast<QWidget*>(newGestureTarget);
- QApplicationPrivate::instance()->widgetGestures[w].swipe = q;
-#if defined(Q_WS_WIN)
- qt_widget_private(w)->winSetupGestures();
-#endif
- }
- QGesturePrivate::setupGestureTarget(newGestureTarget);
-}
-
-/*!
- \property QSwipeGesture::swipeAngle
-
- Holds the angle of the swipe gesture, 0..360.
-*/
-qreal QSwipeGesture::swipeAngle() const
-{
- Q_D(const QSwipeGesture);
- return d->swipeAngle;
-}
-
-/*!
- \property QSwipeGesture::horizontalDirection
-
- Holds the direction for the horizontal component of the swipe
- gesture, SwipeDirection::Left or SwipeDirection::Right.
- SwipeDirection::NoDirection if there is no horizontal
- component to the swipe gesture.
-*/
-QSwipeGesture::SwipeDirection QSwipeGesture::horizontalDirection() const
-{
- Q_D(const QSwipeGesture);
- if (d->swipeAngle < 0 || d->swipeAngle == 90 || d->swipeAngle == 270)
- return QSwipeGesture::NoDirection;
- else if (d->swipeAngle < 90 || d->swipeAngle > 270)
- return QSwipeGesture::Right;
- else
- return QSwipeGesture::Left;
-}
-
-
-/*!
- \property QSwipeGesture::verticalDirection
-
- Holds the direction for the vertical component of the swipe
- gesture, SwipeDirection::Down or SwipeDirection::Up.
- SwipeDirection::NoDirection if there is no vertical
- component to the swipe gesture.
-*/
-QSwipeGesture::SwipeDirection QSwipeGesture::verticalDirection() const
-{
- Q_D(const QSwipeGesture);
- if (d->swipeAngle <= 0 || d->swipeAngle == 180)
- return QSwipeGesture::NoDirection;
- else if (d->swipeAngle < 180)
- return QSwipeGesture::Up;
- else
- return QSwipeGesture::Down;
-}
-
-bool QSwipeGesture::eventFilter(QObject *receiver, QEvent *event)
-{
- Q_D(QSwipeGesture);
- if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) {
- QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
- switch (ev->gestureType) {
- case QNativeGestureEvent::Swipe:
- d->swipeAngle = ev->angle;
- updateState(Qt::GestureStarted);
- updateState(Qt::GestureUpdated);
- updateState(Qt::GestureFinished);
- break;
- default:
- return false;
- }
- return true;
- }
- return QGesture::eventFilter(receiver, event);
-}
-
-/*! \internal */
-bool QSwipeGesture::filterEvent(QEvent *)
-{
- return false;
-}
-
-/*! \internal */
-void QSwipeGesture::reset()
-{
- Q_D(QSwipeGesture);
- d->swipeAngle = -1;
- QGesture::reset();
+ return QGestureRecognizer::Ignore;
}
+ */
QT_END_NAMESPACE
-
-#include "moc_qstandardgestures.cpp"
-
diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h
deleted file mode 100644
index 9e8291b..0000000
--- a/src/gui/kernel/qstandardgestures.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/****************************************************************************
-**
-** 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 QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** 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$
-**
-****************************************************************************/
-
-#ifndef QSTANDARDGESTURES_H
-#define QSTANDARDGESTURES_H
-
-#include <QtGui/qevent.h>
-#include <QtCore/qbasictimer.h>
-
-#include <QtGui/qgesture.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Gui)
-
-class QPanGesturePrivate;
-class Q_GUI_EXPORT QPanGesture : public QGesture
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPanGesture)
-
- Q_PROPERTY(QSizeF totalOffset READ totalOffset)
- Q_PROPERTY(QSizeF lastOffset READ lastOffset)
- Q_PROPERTY(QSizeF offset READ offset)
-
-public:
- QPanGesture(QWidget *gestureTarget, QObject *parent = 0);
-
- bool filterEvent(QEvent *event);
-
- QSizeF totalOffset() const;
- QSizeF lastOffset() const;
- QSizeF offset() const;
-
-protected:
- void reset();
-
-private:
- bool event(QEvent *event);
- bool eventFilter(QObject *receiver, QEvent *event);
-
- friend class QWidget;
- friend class QAbstractScrollAreaPrivate;
-};
-
-class QPinchGesturePrivate;
-class Q_GUI_EXPORT QPinchGesture : public QGesture
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QPinchGesture)
-
-public:
- enum WhatChange {
- ScaleFactorChanged = 0x1,
- RotationAngleChanged = 0x2,
- CenterPointChanged = 0x4
- };
- Q_DECLARE_FLAGS(WhatChanged, WhatChange)
-
- Q_PROPERTY(WhatChanged whatChanged READ whatChanged)
-
- Q_PROPERTY(qreal totalScaleFactor READ totalScaleFactor)
- Q_PROPERTY(qreal lastScaleFactor READ lastScaleFactor)
- Q_PROPERTY(qreal scaleFactor READ scaleFactor)
-
- Q_PROPERTY(qreal totalRotationAngle READ totalRotationAngle)
- Q_PROPERTY(qreal lastRotationAngle READ lastRotationAngle)
- Q_PROPERTY(qreal rotationAngle READ rotationAngle)
-
- Q_PROPERTY(QPointF startCenterPoint READ startCenterPoint)
- Q_PROPERTY(QPointF lastCenterPoint READ lastCenterPoint)
- Q_PROPERTY(QPointF centerPoint READ centerPoint)
-
-public:
-
- QPinchGesture(QWidget *gestureTarget, QObject *parent = 0);
-
- bool filterEvent(QEvent *event);
- void reset();
-
- WhatChanged whatChanged() const;
-
- QPointF startCenterPoint() const;
- QPointF lastCenterPoint() const;
- QPointF centerPoint() const;
-
- qreal totalScaleFactor() const;
- qreal lastScaleFactor() const;
- qreal scaleFactor() const;
-
- qreal totalRotationAngle() const;
- qreal lastRotationAngle() const;
- qreal rotationAngle() const;
-
-private:
- bool event(QEvent *event);
- bool eventFilter(QObject *receiver, QEvent *event);
-
- friend class QWidget;
-};
-
-class QSwipeGesturePrivate;
-class Q_GUI_EXPORT QSwipeGesture : public QGesture
-{
- Q_OBJECT
- Q_ENUMS(SwipeDirection)
-
- Q_PROPERTY(SwipeDirection horizontalDirection READ horizontalDirection)
- Q_PROPERTY(SwipeDirection verticalDirection READ verticalDirection)
- Q_PROPERTY(qreal swipeAngle READ swipeAngle)
-
- Q_DECLARE_PRIVATE(QSwipeGesture)
-
-public:
- enum SwipeDirection { NoDirection, Left, Right, Up, Down };
- QSwipeGesture(QWidget *gestureTarget, QObject *parent = 0);
-
- bool filterEvent(QEvent *event);
- void reset();
-
- SwipeDirection horizontalDirection() const;
- SwipeDirection verticalDirection() const;
- qreal swipeAngle() const;
-
-private:
- bool eventFilter(QObject *receiver, QEvent *event);
-
- friend class QWidget;
-};
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSTANDARDGESTURES_H
diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h
index 79aadfd..fec5c2f 100644
--- a/src/gui/kernel/qstandardgestures_p.h
+++ b/src/gui/kernel/qstandardgestures_p.h
@@ -53,83 +53,20 @@
// We mean it.
//
-#include "qevent.h"
-#include "qbasictimer.h"
-#include "qdebug.h"
-
-#include "qgesture.h"
-#include "qgesture_p.h"
-
-#include "qstandardgestures.h"
-#include "qbasictimer.h"
+#include "qgesturerecognizer.h"
+#include "private/qgesture_p.h"
QT_BEGIN_NAMESPACE
-class QPanGesturePrivate : public QGesturePrivate
-{
- Q_DECLARE_PUBLIC(QPanGesture)
-
-public:
- void setupGestureTarget(QObject *o);
-
- QSizeF totalOffset;
- QSizeF lastOffset;
- QSizeF offset;
- QPointF lastPosition;
-
-#if defined(QT_MAC_USE_COCOA)
- QBasicTimer singleTouchPanTimer;
- QPointF prevMousePos;
-#endif
-};
-
-class QPinchGesturePrivate : public QGesturePrivate
+class QPanGestureRecognizer : public QGestureRecognizer
{
- Q_DECLARE_PUBLIC(QPinchGesture)
-
public:
- QPinchGesturePrivate()
- : changes(0), totalScaleFactor(0.), lastScaleFactor(0.), scaleFactor(0.),
- totalRotationAngle(0.), lastRotationAngle(0.), rotationAngle(0.)
-#ifdef Q_WS_WIN
- ,initialDistance(0), lastSequenceId(0)
-#endif
- {
- }
+ QPanGestureRecognizer();
- void setupGestureTarget(QObject *o);
-
- QPinchGesture::WhatChanged changes;
-
- qreal totalScaleFactor; // total scale factor, excluding the current sequence.
- qreal lastScaleFactor;
- qreal scaleFactor; // scale factor in the current sequence.
-
- qreal totalRotationAngle; // total rotation angle, excluding the current sequence.
- qreal lastRotationAngle;
- qreal rotationAngle; // rotation angle in the current sequence.
-
- QPointF startCenterPoint;
- QPointF lastCenterPoint;
- QPointF centerPoint;
-#ifdef Q_WS_WIN
- int initialDistance;
- ulong lastSequenceId;
-#endif
-};
-
-class QSwipeGesturePrivate : public QGesturePrivate
-{
- Q_DECLARE_PUBLIC(QSwipeGesture)
-
-public:
- QSwipeGesturePrivate()
- : swipeAngle(-1)
- {
- }
+ QGesture *createGesture(QObject *target);
- void setupGestureTarget(QObject *o);
- qreal swipeAngle;
+ QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index d1ec74d..d33791b 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -157,6 +157,8 @@ public:
void setIgnoreFocusChanged(bool enabled) { m_ignoreFocusChanged = enabled; }
void CancelLongTapTimer();
+ void setFocusSafely(bool focus);
+
protected:
void Draw(const TRect& aRect) const;
void SizeChanged();
@@ -174,6 +176,9 @@ private:
#endif
private:
+ static QSymbianControl *lastFocusedControl;
+
+private:
QWidget *qwidget;
bool m_ignoreFocusChanged;
QLongTapTimer* m_longTapDetector;
diff --git a/src/gui/kernel/qtooltip.cpp b/src/gui/kernel/qtooltip.cpp
index 2d0d209..4261808 100644
--- a/src/gui/kernel/qtooltip.cpp
+++ b/src/gui/kernel/qtooltip.cpp
@@ -183,7 +183,6 @@ QTipLabel::QTipLabel(const QString &text, QWidget *w)
setFrameStyle(QFrame::NoFrame);
setAlignment(Qt::AlignLeft);
setIndent(1);
- setWordWrap(Qt::mightBeRichText(text));
qApp->installEventFilter(this);
setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / 255.0);
setMouseTracking(true);
@@ -208,6 +207,7 @@ void QTipLabel::reuseTip(const QString &text)
}
#endif
+ setWordWrap(Qt::mightBeRichText(text));
setText(text);
QFontMetrics fm(font());
QSize extra(1, 0);
diff --git a/src/gui/kernel/qwhatsthis.cpp b/src/gui/kernel/qwhatsthis.cpp
index 5e5e56f..0da3a9b 100644
--- a/src/gui/kernel/qwhatsthis.cpp
+++ b/src/gui/kernel/qwhatsthis.cpp
@@ -194,9 +194,9 @@ QWhatsThat::QWhatsThat(const QString& txt, QWidget* parent, QWidget *showTextFor
#ifndef QT_NO_CURSOR
setCursor(Qt::ArrowCursor);
#endif
-
QRect r;
doc = 0;
+ ensurePolished(); // Ensures style sheet font before size calc
if (Qt::mightBeRichText(text)) {
doc = new QTextDocument();
doc->setUndoRedoEnabled(false);
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 1abbd9f..88d90ee 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -115,6 +115,7 @@
#include "private/qevent_p.h"
#include "private/qgraphicssystem_p.h"
+#include "private/qgesturemanager_p.h"
// widget/widget data creation count
//#define QWIDGET_EXTRA_DEBUG
@@ -901,9 +902,8 @@ void QWidget::setAutoFillBackground(bool enabled)
\sa QEvent, QPainter, QGridLayout, QBoxLayout
\section1 Softkeys
- \since 4.6
- Softkeys are usually physical keys on a device that have a corresponding label or
+ Since Qt 4.6, Softkeys are usually physical keys on a device that have a corresponding label or
other visual representation on the screen that is generally located next to its
physical counterpart. They are most often found on mobile phone platforms. In
modern touch based user interfaces it is also possible to have softkeys that do
@@ -923,7 +923,7 @@ void QWidget::setAutoFillBackground(bool enabled)
Note: Currently softkeys are only supported on the Symbian Platform.
- \sa addAction, QAction, QMenuBar
+ \sa addAction(), QAction, QMenuBar
*/
@@ -1177,10 +1177,6 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
if (f & Qt::MSWindowsOwnDC)
q->setAttribute(Qt::WA_NativeWindow);
-#ifdef Q_WS_WINCE
- data.window_state_internal = 0;
-#endif
-
q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute()
adjustQuitOnCloseAttribute();
@@ -5140,7 +5136,8 @@ void QWidgetPrivate::render_helper(QPainter *painter, const QPoint &targetOffset
return;
QPixmap pixmap(size);
- if (!(renderFlags & QWidget::DrawWindowBackground))
+ if (!(renderFlags & QWidget::DrawWindowBackground)
+ || !q->palette().brush(q->backgroundRole()).isOpaque())
pixmap.fill(Qt::transparent);
q->render(&pixmap, QPoint(), toBePainted, renderFlags);
@@ -8342,12 +8339,9 @@ bool QWidget::event(QEvent *event)
(void) QApplication::sendEvent(this, &mouseEvent);
break;
}
- case QEvent::SymbianDeferredFocusChanged: {
-#ifdef Q_OS_SYMBIAN
- d->handleSymbianDeferredFocusChanged();
-#endif
+ case QEvent::Gesture:
+ event->ignore();
break;
- }
#ifndef QT_NO_PROPERTIES
case QEvent::DynamicPropertyChange: {
const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName();
@@ -11466,18 +11460,31 @@ QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction)
int shortestDistance = INT_MAX;
foreach(QWidget *targetCandidate, QApplication::allWidgets()) {
- if (targetCandidate->focusProxy()) //skip if focus proxy set
+ const QRect targetCandidateRect = targetCandidate->rect().translated(targetCandidate->mapToGlobal(QPoint()));
+
+ // For focus proxies, the child widget handling the focus can have keypad navigation focus,
+ // but the owner of the proxy cannot.
+ // Additionally, empty widgets should be ignored.
+ if (targetCandidate->focusProxy() || targetCandidateRect.isEmpty())
continue;
- const QRect targetCandidateRect = targetCandidate->rect().translated(targetCandidate->mapToGlobal(QPoint()));
+ // Only navigate to a target widget that...
if ( targetCandidate != sourceWidget
+ // ...takes the focus,
&& targetCandidate->focusPolicy() & Qt::TabFocus
+ // ...is above if DirectionNorth,
&& !(direction == DirectionNorth && targetCandidateRect.bottom() > sourceRect.top())
+ // ...is on the right if DirectionEast,
&& !(direction == DirectionEast && targetCandidateRect.left() < sourceRect.right())
+ // ...is below if DirectionSouth,
&& !(direction == DirectionSouth && targetCandidateRect.top() < sourceRect.bottom())
+ // ...is on the left if DirectionWest,
&& !(direction == DirectionWest && targetCandidateRect.right() > sourceRect.left())
+ // ...is enabled,
&& targetCandidate->isEnabled()
+ // ...is visible,
&& targetCandidate->isVisible()
+ // ...is in the same window,
&& targetCandidate->window() == sourceWindow) {
const int targetCandidateDistance = pointToRect(sourcePoint, targetCandidateRect);
if (targetCandidateDistance < shortestDistance) {
@@ -11676,6 +11683,19 @@ QGraphicsProxyWidget *QWidget::graphicsProxyWidget() const
Synonym for QList<QWidget *>.
*/
+/*!
+ Subscribes the widget to a given \a gesture with a \a context.
+
+ \sa QGestureEvent
+ \since 4.6
+*/
+void QWidget::grabGesture(Qt::GestureType gesture, Qt::GestureContext context)
+{
+ Q_D(QWidget);
+ d->gestureContext.insert(gesture, context);
+ (void)QGestureManager::instance(); // create a gesture manager
+}
+
QT_END_NAMESPACE
#include "moc_qwidget.cpp"
diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h
index 7e250e2..3501c6e 100644
--- a/src/gui/kernel/qwidget.h
+++ b/src/gui/kernel/qwidget.h
@@ -96,7 +96,6 @@ class QIcon;
class QWindowSurface;
class QLocale;
class QGraphicsProxyWidget;
-class QGestureManager;
class QGraphicsEffect;
#if defined(Q_WS_X11)
class QX11Info;
@@ -133,9 +132,6 @@ public:
int alloc_region_index;
// int alloc_region_revision;
#endif
-#if defined(Q_WS_WINCE)
- uint window_state_internal : 4;
-#endif
QRect wrect;
};
@@ -358,6 +354,8 @@ public:
QGraphicsEffect *graphicsEffect() const;
void setGraphicsEffect(QGraphicsEffect *effect);
+ void grabGesture(Qt::GestureType type, Qt::GestureContext context = Qt::WidgetWithChildrenGesture);
+
public Q_SLOTS:
void setWindowTitle(const QString &);
#ifndef QT_NO_STYLE_STYLESHEET
@@ -740,6 +738,8 @@ private:
friend class QGraphicsProxyWidgetPrivate;
friend class QStyleSheetStyle;
friend struct QWidgetExceptionCleaner;
+ friend class QGestureManager;
+ friend class QWinNativePanGestureRecognizer;
#ifdef Q_WS_MAC
friend class QCoreGraphicsPaintEnginePrivate;
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 521c36d..6403518 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -64,6 +64,8 @@
#include "QtGui/qapplication.h"
#include <private/qgraphicseffect_p.h>
+#include <private/qgesture_p.h>
+
#ifdef Q_WS_WIN
#include "QtCore/qt_windows.h"
#include <private/qdnd_p.h>
@@ -293,8 +295,8 @@ public:
void setMask_sys(const QRegion &);
#ifdef Q_OS_SYMBIAN
- void handleSymbianDeferredFocusChanged();
void setSoftKeys_sys(const QList<QAction*> &softkeys);
+ void activateSymbianWindow();
#endif
void raise_sys();
@@ -578,6 +580,7 @@ public:
#ifndef QT_NO_ACTION
QList<QAction*> actions;
#endif
+ QMap<Qt::GestureType, Qt::GestureContext> gestureContext;
// Bit fields.
uint high_attributes[3]; // the low ones are in QWidget::widget_attributes
@@ -604,6 +607,7 @@ public:
bool isBackgroundInherited() const;
#elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN
uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine()
+ uint nativeGesturePanEnabled : 1;
bool shouldShowMaximizeButton();
void winUpdateIsOpaque();
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index d6e0a97..b0d405a 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -194,8 +194,8 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &)
}
if (jump && data.winid) {
- RWindow *const window = static_cast<RWindow *>(data.winid->DrawableWindow());
- window->Invalidate(TRect(0, 0, wrect.width(), wrect.height()));
+ RWindow *const window = static_cast<RWindow *>(data.winid->DrawableWindow());
+ window->Invalidate(TRect(0, 0, wrect.width(), wrect.height()));
}
}
@@ -367,7 +367,10 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
} else {
stackingFlags = ECoeStackFlagStandard;
}
+ control->MakeVisible(false);
QT_TRAP_THROWING(control->ControlEnv()->AppUi()->AddToStackL(control, ECoeStackPriorityDefault, stackingFlags));
+ // Avoid keyboard focus to a hidden window.
+ control->setFocusSafely(false);
RDrawableWindow *const drawableWindow = control->DrawableWindow();
// Request mouse move events.
@@ -399,12 +402,23 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
} else {
stackingFlags = ECoeStackFlagStandard;
}
+ control->MakeVisible(false);
QT_TRAP_THROWING(control->ControlEnv()->AppUi()->AddToStackL(control, ECoeStackPriorityDefault, stackingFlags));
+ // Avoid keyboard focus to a hidden window.
+ control->setFocusSafely(false);
q->setAttribute(Qt::WA_WState_Created);
int x, y, w, h;
data.crect.getRect(&x, &y, &w, &h);
control->SetRect(TRect(TPoint(x, y), TSize(w, h)));
+
+ RDrawableWindow *const drawableWindow = control->DrawableWindow();
+ // Request mouse move events.
+ drawableWindow->PointerFilter(EPointerFilterEnterExit
+ | EPointerFilterMove | EPointerFilterDrag, 0);
+
+ if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
+ activateSymbianWindow();
}
if (destroyw) {
@@ -420,7 +434,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
void QWidgetPrivate::show_sys()
{
Q_Q(QWidget);
-
+
if (q->testAttribute(Qt::WA_OutsideWSRange))
return;
@@ -434,16 +448,15 @@ void QWidgetPrivate::show_sys()
}
if (q->internalWinId()) {
-
- WId id = q->internalWinId();
- if (!extra->activated) {
- QT_TRAP_THROWING(id->ActivateL());
- extra->activated = 1;
- }
+ if (!extra->activated)
+ activateSymbianWindow();
+
+ QSymbianControl *id = static_cast<QSymbianControl *>(q->internalWinId());
+
id->MakeVisible(true);
-
+
if(q->isWindow())
- id->SetFocus(true);
+ id->setFocusSafely(true);
// Force setting of the icon after window is made visible,
// this is needed even WA_SetWindowIcon is not set, as in that case we need
@@ -455,17 +468,35 @@ void QWidgetPrivate::show_sys()
invalidateBuffer(q->rect());
}
+void QWidgetPrivate::activateSymbianWindow()
+{
+ Q_Q(QWidget);
+
+ Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
+ Q_ASSERT(q->testAttribute(Qt::WA_Mapped));
+ Q_ASSERT(!extra->activated);
+
+ WId id = q->internalWinId();
+ QT_TRAP_THROWING(id->ActivateL());
+ extra->activated = 1;
+}
+
void QWidgetPrivate::hide_sys()
{
Q_Q(QWidget);
Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
deactivateWidgetCleanup();
- WId id = q->internalWinId();
+ QSymbianControl *id = static_cast<QSymbianControl *>(q->internalWinId());
if (id) {
- if(id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
- id->SetFocus(false);
+ //Incorrect optimisation - for popup windows, Qt's focus is moved before
+ //hide_sys is called, resulting in the popup window keeping its elevated
+ //position in the CONE control stack.
+ //This can result in keyboard focus being in an invisible widget in some
+ //conditions - e.g. QTBUG-4733
+ //if(id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
+ id->setFocusSafely(false);
id->MakeVisible(false);
if (QWidgetBackingStore *bs = maybeBackingStore())
bs->releaseBuffer();
@@ -481,36 +512,7 @@ void QWidgetPrivate::setFocus_sys()
Q_Q(QWidget);
if (q->testAttribute(Qt::WA_WState_Created) && q->window()->windowType() != Qt::Popup)
if (!q->effectiveWinId()->IsFocused()) // Avoid unnecessry calls to FocusChanged()
- q->effectiveWinId()->SetFocus(true);
-}
-
-void QWidgetPrivate::handleSymbianDeferredFocusChanged()
-{
- Q_Q(QWidget);
- WId control = q->internalWinId();
-
- if (!control) {
- // This could happen if the widget was reparented, while the focuschange
- // was in the event queue.
- return;
- }
-
- if (control->IsFocused()) {
- QApplication::setActiveWindow(q);
-#ifdef Q_WS_S60
- // If widget is fullscreen, hide status pane and button container
- // otherwise show them.
- CEikStatusPane* statusPane = S60->statusPane();
- CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
- bool isFullscreen = q->windowState() & Qt::WindowFullScreen;
- if (statusPane && (statusPane->IsVisible() == isFullscreen))
- statusPane->MakeVisible(!isFullscreen);
- if (buttonGroup && (buttonGroup->IsVisible() == isFullscreen))
- buttonGroup->MakeVisible(!isFullscreen);
-#endif
- } else {
- QApplication::setActiveWindow(0);
- }
+ static_cast<QSymbianControl *>(q->effectiveWinId())->setFocusSafely(true);
}
void QWidgetPrivate::raise_sys()
@@ -597,7 +599,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
if (q->testAttribute(Qt::WA_DropSiteRegistered))
q->setAttribute(Qt::WA_DropSiteRegistered, false);
- WId old_winid = wasCreated ? data.winid : 0;
+ QSymbianControl *old_winid = static_cast<QSymbianControl *>(wasCreated ? data.winid : 0);
if ((q->windowType() == Qt::Desktop))
old_winid = 0;
setWinId(0);
@@ -607,7 +609,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
if (wasCreated && old_winid) {
old_winid->MakeVisible(false);
if (old_winid->IsFocused()) // Avoid unnecessary calls to FocusChanged()
- old_winid->SetFocus(false);
+ old_winid->setFocusSafely(false);
old_winid->SetParent(0);
}
@@ -1039,9 +1041,9 @@ QPoint QWidget::mapFromGlobal(const QPoint &pos) const
}
// Native window case
- const TPoint widgetScreenOffset = internalWinId()->PositionRelativeToScreen();
- const QPoint widgetPos = pos - QPoint(widgetScreenOffset.iX, widgetScreenOffset.iY);
- return widgetPos;
+ const TPoint widgetScreenOffset = internalWinId()->PositionRelativeToScreen();
+ const QPoint widgetPos = pos - QPoint(widgetScreenOffset.iX, widgetScreenOffset.iY);
+ return widgetPos;
}
void QWidget::setWindowState(Qt::WindowStates newstate)
@@ -1124,17 +1126,17 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
if (newstate & Qt::WindowMinimized) {
if (isVisible()) {
- WId id = effectiveWinId();
+ QSymbianControl *id = static_cast<QSymbianControl *>(effectiveWinId());
if (id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
- id->SetFocus(false);
+ id->setFocusSafely(false);
id->MakeVisible(false);
}
} else {
if (isVisible()) {
- WId id = effectiveWinId();
+ QSymbianControl *id = static_cast<QSymbianControl *>(effectiveWinId());
id->MakeVisible(true);
if (!id->IsFocused()) // Avoid unnecessary calls to FocusChanged()
- id->SetFocus(true);
+ id->setFocusSafely(true);
}
const QRect normalGeometry = geometry();
const QRect r = top->normalGeometry;
@@ -1161,7 +1163,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
if (!isWindow() && parentWidget())
parentWidget()->d_func()->invalidateBuffer(geometry());
d->deactivateWidgetCleanup();
- WId id = internalWinId();
+ QSymbianControl *id = static_cast<QSymbianControl *>(internalWinId());
if (testAttribute(Qt::WA_WState_Created)) {
#ifndef QT_NO_IM
@@ -1189,7 +1191,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
}
if (destroyWindow && !(windowType() == Qt::Desktop) && id) {
if (id->IsFocused()) // Avoid unnecessry calls to FocusChanged()
- id->SetFocus(false);
+ id->setFocusSafely(false);
id->ControlEnv()->AppUi()->RemoveFromStack(id);
// Hack to activate window under destroyed one. With this activation
@@ -1256,7 +1258,7 @@ void QWidget::grabMouse()
WId id = effectiveWinId();
id->SetPointerCapture(true);
QWidgetPrivate::mouseGrabber = this;
-
+
#ifndef QT_NO_CURSOR
QApplication::setOverrideCursor(cursor());
#endif
@@ -1299,8 +1301,8 @@ void QWidget::activateWindow()
QWidget *tlw = window();
if (tlw->isVisible()) {
window()->createWinId();
- WId id = tlw->internalWinId();
- id->SetFocus(true);
+ QSymbianControl *id = static_cast<QSymbianControl *>(tlw->internalWinId());
+ id->setFocusSafely(true);
}
}
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index c705e2a..2b11bec 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -1402,7 +1402,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
SetWindowPlacement(q->internalWinId(), &wndpl);
} else {
#else
- if (data.window_state_internal & Qt::WindowMaximized) {
+ if (data.window_state & Qt::WindowMaximized) {
qt_wince_maximize(q);
} else {
#endif
@@ -2029,11 +2029,6 @@ void QWidgetPrivate::winSetupGestures()
if (!q || !q->isVisible())
return;
QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
- QApplicationPrivate::WidgetStandardGesturesMap::const_iterator it =
- qAppPriv->widgetGestures.find(q);
- if (it == qAppPriv->widgetGestures.end())
- return;
- const QStandardGestures &gestures = it.value();
WId winid = q->effectiveWinId();
bool needh = false;
@@ -2052,10 +2047,10 @@ void QWidgetPrivate::winSetupGestures()
singleFingerPanEnabled = asa->d_func()->singleFingerPanEnabled;
}
if (winid && qAppPriv->SetGestureConfig) {
- GESTURECONFIG gc[3];
+ GESTURECONFIG gc[1];
memset(gc, 0, sizeof(gc));
gc[0].dwID = GID_PAN;
- if (gestures.pan) {
+ if (nativeGesturePanEnabled) {
gc[0].dwWant = GC_PAN;
if (needv && singleFingerPanEnabled)
gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
@@ -2069,16 +2064,16 @@ 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;
+// 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/qwidget_wince.cpp b/src/gui/kernel/qwidget_wince.cpp
index 32e8e7f..4a0d30c 100644
--- a/src/gui/kernel/qwidget_wince.cpp
+++ b/src/gui/kernel/qwidget_wince.cpp
@@ -416,6 +416,10 @@ void QWidgetPrivate::show_sys() {
SetWindowLong(q->internalWinId(), GWL_STYLE, style | WS_MAXIMIZEBOX);
}
} else
+#else
+ // Imitate minimizing on Windows mobile by hiding the widget.
+ if (q->isMinimized())
+ sm = SW_HIDE;
#endif
if (q->isHidden()) {
sm = SW_HIDE;
@@ -428,8 +432,7 @@ void QWidgetPrivate::show_sys() {
sm = SW_SHOWNOACTIVATE;
}
- if (!(data.window_state & Qt::WindowMinimized))
- ShowWindow(q->internalWinId(), sm);
+ ShowWindow(q->internalWinId(), sm);
if (q->isMaximized() && q->isWindow())
qt_wince_maximize(q);
@@ -438,7 +441,7 @@ void QWidgetPrivate::show_sys() {
if (!qt_wince_is_mobile() && q->isFullScreen()) {
HWND handle = FindWindow(L"HHTaskBar", L"");
if (handle) {
- ShowWindow(handle, 0);
+ ShowWindow(handle, SW_HIDE);
EnableWindow(handle, false);
}
}
@@ -468,21 +471,15 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
return;
int max = SW_SHOWNORMAL;
- int min = SW_SHOWNOACTIVATE;
-
int normal = SW_SHOWNOACTIVATE;
if ((oldstate & Qt::WindowMinimized) && !(newstate & Qt::WindowMinimized))
newstate |= Qt::WindowActive;
- if (newstate & Qt::WindowActive) {
- max = SW_SHOWNORMAL;
- min = SW_SHOWNORMAL;
+ if (newstate & Qt::WindowActive)
normal = SW_SHOWNORMAL;
- }
if (isWindow()) {
createWinId();
Q_ASSERT(testAttribute(Qt::WA_WState_Created));
- data->window_state_internal = newstate;
// Ensure the initial size is valid, since we store it as normalGeometry below.
if ((!testAttribute(Qt::WA_Resized) && !isVisible()))
adjustSize();
@@ -556,13 +553,11 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
}
}
if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
- if (isVisible()) {
- ShowWindow(internalWinId(), (newstate & Qt::WindowMinimized) ? min :
- (newstate & Qt::WindowMaximized) ? max : normal);
- if (newstate & Qt::WindowMaximized)
- qt_wince_maximize(this);
if (newstate & Qt::WindowMinimized)
qt_wince_minimize(internalWinId());
+ else if (newstate & Qt::WindowMaximized) {
+ ShowWindow(internalWinId(), max);
+ qt_wince_maximize(this);
}
}
if ((newstate & Qt::WindowMaximized) && !(newstate & Qt::WindowFullScreen)) {
@@ -577,7 +572,6 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
}
}
data->window_state = newstate;
- data->window_state_internal = newstate;
QWindowStateChangeEvent e(oldstate);
QApplication::sendEvent(this, &e);
}
@@ -588,7 +582,7 @@ void QWidgetPrivate::deleteSysExtra()
if (!qt_wince_is_mobile() && q->isFullScreen()) {
HWND handle = FindWindow(L"HHTaskBar", L"");
if (handle) {
- ShowWindow(handle, 1);
+ ShowWindow(handle, SW_SHOWNORMAL);
EnableWindow(handle, true);
}
}
diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp
new file mode 100644
index 0000000..4619594
--- /dev/null
+++ b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** 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 QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** 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$
+**
+****************************************************************************/
+
+#include "private/qwinnativepangesturerecognizer_win_p.h"
+
+#include "qevent.h"
+#include "qgraphicsitem.h"
+#include "qgesture.h"
+
+#include "private/qgesture_p.h"
+#include "private/qevent_p.h"
+#include "private/qapplication_p.h"
+#include "private/qwidget_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QWinNativePanGestureRecognizer::QWinNativePanGestureRecognizer()
+{
+}
+
+QGesture* QWinNativePanGestureRecognizer::createGesture(QObject *target) const
+{
+ if (!target)
+ return new QPanGesture; // a special case
+ if (qobject_cast<QGraphicsObject*>(target))
+ return 0;
+ if (!target->isWidgetType())
+ return 0;
+
+ QWidget *q = static_cast<QWidget*>(target);
+ QWidgetPrivate *d = q->d_func();
+ d->nativeGesturePanEnabled = true;
+ d->winSetupGestures();
+
+ return new QPanGesture;
+}
+
+QGestureRecognizer::Result QWinNativePanGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event)
+{
+ QPanGesture *q = static_cast<QPanGesture*>(state);
+ QPanGesturePrivate *d = q->d_func();
+
+ QGestureRecognizer::Result result = QGestureRecognizer::Ignore;
+ if (event->type() == QEvent::NativeGesture) {
+ QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
+ switch(ev->gestureType) {
+ case QNativeGestureEvent::GestureBegin:
+ break;
+ case QNativeGestureEvent::Pan:
+ result = QGestureRecognizer::GestureTriggered;
+ event->accept();
+ break;
+ case QNativeGestureEvent::GestureEnd:
+ if (q->state() == Qt::NoGesture)
+ return QGestureRecognizer::Ignore; // some other gesture has ended
+ result = QGestureRecognizer::GestureFinished;
+ break;
+ default:
+ return QGestureRecognizer::Ignore;
+ }
+ if (q->state() == Qt::NoGesture) {
+ d->lastOffset = d->totalOffset = d->offset = QSize();
+ } else {
+ d->lastOffset = d->offset;
+ d->offset = QSize(ev->position.x() - d->lastPosition.x(),
+ ev->position.y() - d->lastPosition.y());
+ d->totalOffset += d->offset;
+ }
+ d->lastPosition = ev->position;
+ }
+ return result;
+}
+
+void QWinNativePanGestureRecognizer::reset(QGesture *state)
+{
+ QPanGesture *pan = static_cast<QPanGesture*>(state);
+ QPanGesturePrivate *d = pan->d_func();
+
+ d->totalOffset = d->lastOffset = d->offset = QSizeF();
+ d->lastPosition = QPoint();
+ d->acceleration = 0;
+
+ QGestureRecognizer::reset(state);
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h
new file mode 100644
index 0000000..a1e8511
--- /dev/null
+++ b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** 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$
+**
+****************************************************************************/
+
+#ifndef QWINNATIVEPANGESTURERECOGNIZER_WIN_P_H
+#define QWINNATIVEPANGESTURERECOGNIZER_WIN_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QGestureRecognizer>
+
+QT_BEGIN_NAMESPACE
+
+class QWinNativePanGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QWinNativePanGestureRecognizer();
+
+ QGesture* createGesture(QObject *target) const;
+
+ QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event);
+ void reset(QGesture *state);
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINNATIVEPANGESTURERECOGNIZER_WIN_P_H
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 62e08f3..4da993b 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -176,22 +176,25 @@ QT_BEGIN_NAMESPACE
\section1 Predefined Colors
- There are 20 predefined QColors: Qt::white, Qt::black,
- Qt::red, Qt::darkRed, Qt::green, Qt::darkGreen, Qt::blue,
- Qt::darkBlue, Qt::cyan, Qt::darkCyan, Qt::magenta,
- Qt::darkMagenta, Qt::yellow, Qt::darkYellow, Qt::gray,
- Qt::darkGray, Qt::lightGray, Qt::color0, Qt::color1, and
- Qt::transparent.
+ There are 20 predefined QColors described by the Qt::GlobalColor enum,
+ including black, white, primary and secondary colors, darker versions
+ of these colors and three shades of gray. QColor also recognizes a
+ variety of color names; the static colorNames() function returns a
+ QStringList color names that QColor knows about.
\img qt-colors.png Qt Colors
- QColor provides the static colorNames() function which returns a
- QStringList containing the color names Qt knows about.
+ Additionally, the Qt::color0, Qt::color1 and Qt::transparent colors
+ are used for special purposes.
- The colors Qt::color0 (zero pixel value) and Qt::color1 (non-zero
- pixel value) are special colors for drawing in QBitmaps. Painting with
- Qt::color0 sets the bitmap bits to 0 (transparent, i.e. background), and
- painting with Qt::color1 sets the bits to 1 (opaque, i.e. foreground).
+ Qt::color0 (zero pixel value) and Qt::color1 (non-zero pixel value)
+ are special colors for drawing in QBitmaps. Painting with Qt::color0
+ sets the bitmap bits to 0 (transparent; i.e., background), and painting
+ with Qt::color1 sets the bits to 1 (opaque; i.e., foreground).
+
+ Qt::transparent is used to indicate a transparent pixel. When painting
+ with this value, a pixel value will be used that is appropriate for the
+ underlying pixel format in use.
\section1 The HSV Color Model
@@ -514,7 +517,7 @@ QString QColor::name() const
\i #RRRRGGGGBBBB
\i A name from the list of colors defined in the list of \l{SVG color keyword names}
provided by the World Wide Web Consortium; for example, "steelblue" or "gainsboro".
- These color names work on all platforms. Note that these color names are \i not the
+ These color names work on all platforms. Note that these color names are \e not the
same as defined by the Qt::GlobalColor enums, e.g. "green" and Qt::green does not
refer to the same color.
\i \c transparent - representing the absence of a color.
diff --git a/src/gui/painting/qdrawutil.cpp b/src/gui/painting/qdrawutil.cpp
index 716300e..1182b9a 100644
--- a/src/gui/painting/qdrawutil.cpp
+++ b/src/gui/painting/qdrawutil.cpp
@@ -45,6 +45,9 @@
#include "qapplication.h"
#include "qpainter.h"
#include "qpalette.h"
+#include <private/qpaintengineex_p.h>
+#include <qvarlengtharray.h>
+#include <qmath.h>
QT_BEGIN_NAMESPACE
@@ -1078,91 +1081,7 @@ void qDrawItem(QPainter *p, Qt::GUIStyle gs,
according to the \a margins structure.
*/
-static inline void qVerticalRepeat(QPainter *painter,
- const QRect &target,
- const QPixmap &pixmap,
- const QRect &source,
- void (*drawPixmap)(QPainter*,
- const QRect&,
- const QPixmap&,
- const QRect&))
-{
- const int x = target.x();
- const int width = target.width();
- const int height = source.height();
- const int bottom = target.bottom() - height;
- int y = target.y();
- for (; y < bottom; y += height)
- (*drawPixmap)(painter, QRect(x, y, width, height), pixmap, source);
- const QRect remaining(source.x(), source.y(), source.width(), target.bottom() - y + 1);
- (*drawPixmap)(painter, QRect(x, y, width, remaining.height()), pixmap, remaining);
-}
-
-static inline void qHorizontalRepeat(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source,
- void (*drawPixmap)(QPainter*, const QRect&, const QPixmap&, const QRect&))
-{
- const int y = target.y();
- const int width = source.width();
- const int height = target.height();
- const int right = target.right() - width;
- int x = target.x();
- for (; x < right; x += width)
- (*drawPixmap)(painter, QRect(x, y, width, height), pixmap, source);
- const QRect remaining(source.x(), source.y(), target.right() - x + 1, source.height());
- (*drawPixmap)(painter, QRect(x, y, remaining.width(), height), pixmap, remaining);
-}
-
-static inline void qVerticalRound(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source,
- void (*drawPixmap)(QPainter*, const QRect&, const QPixmap&, const QRect&))
-{
- // qreal based - slow on non-fpu devices
- const qreal x = target.x();
- const qreal width = target.width();
- const qreal verticalFactor = static_cast<qreal>(target.height()) / static_cast<qreal>(source.height());
- const qreal verticalIncrement = static_cast<qreal>(target.height()) / static_cast<int>(verticalFactor + 0.5);
- const qreal bottom = target.bottom();
- for (qreal y = static_cast<qreal>(target.y()); y < bottom; y += verticalIncrement)
- (*drawPixmap)(painter, QRectF(x, y, width, verticalIncrement).toRect(), pixmap, source);
-
-}
-
-static inline void qHorizontalRound(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source,
- void (*drawPixmap)(QPainter*, const QRect&, const QPixmap&, const QRect&))
-{
- // qreal based - slow on non-fpu devices
- const qreal y = target.y();
- const qreal height = target.height();
- const qreal horizontalFactor = static_cast<qreal>(target.width()) / static_cast<qreal>(source.width());
- const qreal horizontalIncrement = static_cast<qreal>(target.width()) / static_cast<int>(horizontalFactor + 0.5);
- const qreal right = target.right();
- for (qreal x = target.x(); x < right; x += horizontalIncrement)
- (*drawPixmap)(painter, QRectF(x, y, horizontalIncrement, height).toRect(), pixmap, source);
-}
-
-static inline void qDrawPixmap(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source)
-{
- painter->drawPixmap(target, pixmap, source);
-}
-
-static inline void qDrawVerticallyRepeatedPixmap(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source)
-{
- qVerticalRepeat(painter, target, pixmap, source, qDrawPixmap);
-}
-
-static inline void qDrawHorizontallyRepeatedPixmap(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source)
-{
- qHorizontalRepeat(painter, target, pixmap, source, qDrawPixmap);
-}
-
-static inline void qDrawVerticallyRoundedPixmap(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source)
-{
- qVerticalRound(painter, target, pixmap, source, qDrawPixmap);
-}
-
-static inline void qDrawHorizontallyRoundedPixmap(QPainter *painter, const QRect &target, const QPixmap &pixmap, const QRect &source)
-{
- qHorizontalRound(painter, target, pixmap, source, qDrawPixmap);
-}
+typedef QVarLengthArray<QDrawPixmaps::Data, 16> QDrawPixmapsDataArray;
/*!
\since 4.6
@@ -1179,176 +1098,282 @@ static inline void qDrawHorizontallyRoundedPixmap(QPainter *painter, const QRect
\sa Qt::TileRule, QTileRules, QMargins
*/
-void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins, const QPixmap &pixmap,
- const QRect &sourceRect, const QMargins &sourceMargins, const QTileRules &rules)
+void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins,
+ const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins,
+ const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints)
{
+ QDrawPixmaps::Data d;
+ d.opacity = 1.0;
+ d.rotation = 0.0;
+
+ QDrawPixmapsDataArray opaqueData;
+ QDrawPixmapsDataArray translucentData;
+
// source center
- const int sourceTop = sourceRect.top();
- const int sourceLeft = sourceRect.left();
- const int sourceCenterTop = sourceTop + sourceMargins.top();
- const int sourceCenterLeft = sourceLeft + sourceMargins.left();
+ const int sourceCenterTop = sourceRect.top() + sourceMargins.top();
+ const int sourceCenterLeft = sourceRect.left() + sourceMargins.left();
const int sourceCenterBottom = sourceRect.bottom() - sourceMargins.bottom() + 1;
const int sourceCenterRight = sourceRect.right() - sourceMargins.right() + 1;
- const int sourceCenterWidth = sourceCenterRight - sourceMargins.left();
- const int sourceCenterHeight = sourceCenterBottom - sourceMargins.top();
+ const int sourceCenterWidth = sourceCenterRight - sourceCenterLeft;
+ const int sourceCenterHeight = sourceCenterBottom - sourceCenterTop;
// target center
- const int targetTop = targetRect.top();
- const int targetLeft = targetRect.left();
- const int targetCenterTop = targetTop + targetMargins.top();
- const int targetCenterLeft = targetLeft + targetMargins.left();
+ const int targetCenterTop = targetRect.top() + targetMargins.top();
+ const int targetCenterLeft = targetRect.left() + targetMargins.left();
const int targetCenterBottom = targetRect.bottom() - targetMargins.bottom() + 1;
const int targetCenterRight = targetRect.right() - targetMargins.right() + 1;
const int targetCenterWidth = targetCenterRight - targetCenterLeft;
const int targetCenterHeight = targetCenterBottom - targetCenterTop;
+ QVarLengthArray<qreal, 16> xTarget; // x-coordinates of target rectangles
+ QVarLengthArray<qreal, 16> yTarget; // y-coordinates of target rectangles
+
+ int columns = 3;
+ int rows = 3;
+ if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0)
+ columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth)));
+ if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0)
+ rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight)));
+
+ xTarget.resize(columns + 1);
+ yTarget.resize(rows + 1);
+
+ xTarget[0] = targetRect.left();
+ xTarget[1] = targetCenterLeft;
+ xTarget[columns - 1] = targetCenterRight;
+ xTarget[columns] = targetRect.left() + targetRect.width();
+
+ yTarget[0] = targetRect.top();
+ yTarget[1] = targetCenterTop;
+ yTarget[rows - 1] = targetCenterBottom;
+ yTarget[rows] = targetRect.top() + targetRect.height();
+
+ qreal dx = targetCenterWidth;
+ qreal dy = targetCenterHeight;
+
+ switch (rules.horizontal) {
+ case Qt::StretchTile:
+ dx = targetCenterWidth;
+ break;
+ case Qt::RepeatTile:
+ dx = sourceCenterWidth;
+ break;
+ case Qt::RoundTile:
+ dx = targetCenterWidth / qreal(columns - 2);
+ break;
+ }
+
+ for (int i = 2; i < columns - 1; ++i)
+ xTarget[i] = xTarget[i - 1] + dx;
+
+ switch (rules.vertical) {
+ case Qt::StretchTile:
+ dy = targetCenterHeight;
+ break;
+ case Qt::RepeatTile:
+ dy = sourceCenterHeight;
+ break;
+ case Qt::RoundTile:
+ dy = targetCenterHeight / qreal(rows - 2);
+ break;
+ }
+
+ for (int i = 2; i < rows - 1; ++i)
+ yTarget[i] = yTarget[i - 1] + dy;
+
// corners
if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left
- const QRect targetTopLeftRect(targetLeft, targetTop, targetMargins.left(), targetMargins.top());
- const QRect sourceTopLeftRect(sourceLeft, sourceTop, sourceMargins.left(), sourceMargins.top());
- qDrawPixmap(painter, targetTopLeftRect, pixmap, sourceTopLeftRect);
+ d.point.setX(0.5 * (xTarget[1] + xTarget[0]));
+ d.point.setY(0.5 * (yTarget[1] + yTarget[0]));
+ d.source = QRectF(sourceRect.left(), sourceRect.top(), sourceMargins.left(), sourceMargins.top());
+ d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width();
+ d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height();
+ if (hints & QDrawBorderPixmap::OpaqueTopLeft)
+ opaqueData.append(d);
+ else
+ translucentData.append(d);
}
if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right
- const QRect targetTopRightRect(targetCenterRight, targetTop, targetMargins.right(), targetMargins.top());
- const QRect sourceTopRightRect(sourceCenterRight, sourceTop, sourceMargins.right(), sourceMargins.top());
- qDrawPixmap(painter, targetTopRightRect, pixmap, sourceTopRightRect);
+ d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1]));
+ d.point.setY(0.5 * (yTarget[1] + yTarget[0]));
+ d.source = QRectF(sourceCenterRight, sourceRect.top(), sourceMargins.right(), sourceMargins.top());
+ d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width();
+ d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height();
+ if (hints & QDrawBorderPixmap::OpaqueTopRight)
+ opaqueData.append(d);
+ else
+ translucentData.append(d);
}
if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left
- const QRect targetBottomLeftRect(targetLeft, targetCenterBottom, targetMargins.left(), targetMargins.bottom());
- const QRect sourceBottomLeftRect(sourceLeft, sourceCenterBottom, sourceMargins.left(), sourceMargins.bottom());
- qDrawPixmap(painter, targetBottomLeftRect, pixmap, sourceBottomLeftRect);
+ d.point.setX(0.5 * (xTarget[1] + xTarget[0]));
+ d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1]));
+ d.source = QRectF(sourceRect.left(), sourceCenterBottom, sourceMargins.left(), sourceMargins.bottom());
+ d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width();
+ d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height();
+ if (hints & QDrawBorderPixmap::OpaqueBottomLeft)
+ opaqueData.append(d);
+ else
+ translucentData.append(d);
}
if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right
- const QRect targetBottomRightRect(targetCenterRight, targetCenterBottom, targetMargins.right(), targetMargins.bottom());
- const QRect sourceBottomRightRect(sourceCenterRight, sourceCenterBottom, sourceMargins.right(), sourceMargins.bottom());
- qDrawPixmap(painter, targetBottomRightRect, pixmap, sourceBottomRightRect);
+ d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1]));
+ d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1]));
+ d.source = QRectF(sourceCenterRight, sourceCenterBottom, sourceMargins.right(), sourceMargins.bottom());
+ d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width();
+ d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height();
+ if (hints & QDrawBorderPixmap::OpaqueBottomRight)
+ opaqueData.append(d);
+ else
+ translucentData.append(d);
}
// horizontal edges
- switch (rules.horizontal) {
- case Qt::Stretch:
- if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top
- const QRect targetTopRect(targetCenterLeft, targetTop, targetCenterWidth, targetMargins.top());
- const QRect sourceTopRect(sourceCenterLeft, sourceTop, sourceCenterWidth, sourceMargins.top());
- qDrawPixmap(painter, targetTopRect, pixmap, sourceTopRect);
- }
- if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom
- const QRect targetBottomRect(targetCenterLeft, targetCenterBottom, targetCenterWidth, targetMargins.bottom());
- const QRect sourceBottomRect(sourceCenterLeft, sourceCenterBottom, sourceCenterWidth, sourceMargins.bottom());
- qDrawPixmap(painter, targetBottomRect, pixmap, sourceBottomRect);
- }
- break;
- case Qt::Repeat:
- if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top
- const QRect targetTopRect(targetCenterLeft, targetTop, targetCenterWidth, targetMargins.top());
- const QRect sourceTopRect(sourceCenterLeft, sourceTop, sourceCenterWidth, sourceMargins.top());
- qDrawHorizontallyRepeatedPixmap(painter, targetTopRect, pixmap, sourceTopRect);
- }
- if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom
- const QRect targetBottomRect(targetCenterLeft, targetCenterBottom, targetCenterWidth, targetMargins.bottom());
- const QRect sourceBottomRect(sourceCenterLeft, sourceCenterBottom, sourceCenterWidth, sourceMargins.bottom());
- qDrawHorizontallyRepeatedPixmap(painter, targetBottomRect, pixmap, sourceBottomRect);
- }
- break;
- case Qt::Round:
+ if (targetCenterWidth > 0 && sourceCenterWidth > 0) {
if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top
- const QRect targetTopRect(targetCenterLeft, targetTop, targetCenterWidth, targetMargins.top());
- const QRect sourceTopRect(sourceCenterLeft, sourceTop, sourceCenterWidth, sourceMargins.top());
- qDrawHorizontallyRoundedPixmap(painter, targetTopRect, pixmap, sourceTopRect);
+ QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData;
+ d.source = QRectF(sourceCenterLeft, sourceRect.top(), sourceCenterWidth, sourceMargins.top());
+ d.point.setY(0.5 * (yTarget[1] + yTarget[0]));
+ d.scaleX = dx / d.source.width();
+ d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.source.height();
+ for (int i = 1; i < columns - 1; ++i) {
+ d.point.setX(0.5 * (xTarget[i + 1] + xTarget[i]));
+ data.append(d);
+ }
+ if (rules.horizontal == Qt::RepeatTile)
+ data[data.size() - 1].source.setWidth((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
}
if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom
- const QRect targetBottomRect(targetCenterLeft, targetCenterBottom, targetCenterWidth, targetMargins.bottom());
- const QRect sourceBottomRect(sourceCenterLeft, sourceCenterBottom, sourceCenterWidth, sourceMargins.bottom());
- qDrawHorizontallyRoundedPixmap(painter, targetBottomRect, pixmap, sourceBottomRect);
+ QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData;
+ d.source = QRectF(sourceCenterLeft, sourceCenterBottom, sourceCenterWidth, sourceMargins.bottom());;
+ d.point.setY(0.5 * (yTarget[rows] + yTarget[rows - 1]));
+ d.scaleX = dx / d.source.width();
+ d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.source.height();
+ for (int i = 1; i < columns - 1; ++i) {
+ d.point.setX(0.5 * (xTarget[i + 1] + xTarget[i]));
+ data.append(d);
+ }
+ if (rules.horizontal == Qt::RepeatTile)
+ data[data.size() - 1].source.setWidth((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
}
- break;
}
// vertical edges
- switch (rules.vertical) {
- case Qt::Stretch:
- if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left
- const QRect targetLeftRect(targetLeft, targetCenterTop, targetMargins.left(), targetCenterHeight);
- const QRect sourceLeftRect(sourceLeft, sourceCenterTop, sourceMargins.left(), sourceCenterHeight);
- qDrawPixmap(painter, targetLeftRect, pixmap, sourceLeftRect);
- }
- if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right
- const QRect targetRightRect(targetCenterRight, targetCenterTop, targetMargins.right(), targetCenterHeight);
- const QRect sourceRightRect(sourceCenterRight, sourceCenterTop, sourceMargins.right(), sourceCenterHeight);
- qDrawPixmap(painter, targetRightRect, pixmap, sourceRightRect);
- }
- break;
- case Qt::Repeat:
- if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left
- const QRect targetLeftRect(targetLeft, targetCenterTop, targetMargins.left(), targetCenterHeight);
- const QRect sourceLeftRect(sourceLeft, sourceCenterTop, sourceMargins.left(), sourceCenterHeight);
- qDrawVerticallyRepeatedPixmap(painter, targetLeftRect, pixmap, sourceLeftRect);
- }
- if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right
- const QRect targetRightRect(targetCenterRight, targetCenterTop, targetMargins.right(), targetCenterHeight);
- const QRect sourceRightRect(sourceCenterRight, sourceCenterTop, sourceMargins.right(), sourceCenterHeight);
- qDrawVerticallyRepeatedPixmap(painter, targetRightRect, pixmap, sourceRightRect);
- }
- break;
- case Qt::Round:
+ if (targetCenterHeight > 0 && sourceCenterHeight > 0) {
if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left
- const QRect targetLeftRect(targetLeft, targetCenterTop, targetMargins.left(), targetCenterHeight);
- const QRect sourceLeftRect(sourceLeft, sourceCenterTop, sourceMargins.left(), sourceCenterHeight);
- qDrawVerticallyRoundedPixmap(painter, targetLeftRect, pixmap, sourceLeftRect);
+ QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData;
+ d.source = QRectF(sourceRect.left(), sourceCenterTop, sourceMargins.left(), sourceCenterHeight);
+ d.point.setX(0.5 * (xTarget[1] + xTarget[0]));
+ d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.source.width();
+ d.scaleY = dy / d.source.height();
+ for (int i = 1; i < rows - 1; ++i) {
+ d.point.setY(0.5 * (yTarget[i + 1] + yTarget[i]));
+ data.append(d);
+ }
+ if (rules.vertical == Qt::RepeatTile)
+ data[data.size() - 1].source.setHeight((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
}
if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right
- const QRect targetRightRect(targetCenterRight, targetCenterTop, targetMargins.right(), targetCenterHeight);
- const QRect sourceRightRect(sourceCenterRight, sourceCenterTop, sourceMargins.right(), sourceCenterHeight);
- qDrawVerticallyRoundedPixmap(painter, targetRightRect, pixmap, sourceRightRect);
+ QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData;
+ d.source = QRectF(sourceCenterRight, sourceCenterTop, sourceMargins.right(), sourceCenterHeight);
+ d.point.setX(0.5 * (xTarget[columns] + xTarget[columns - 1]));
+ d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.source.width();
+ d.scaleY = dy / d.source.height();
+ for (int i = 1; i < rows - 1; ++i) {
+ d.point.setY(0.5 * (yTarget[i + 1] + yTarget[i]));
+ data.append(d);
+ }
+ if (rules.vertical == Qt::RepeatTile)
+ data[data.size() - 1].source.setHeight((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
}
- break;
}
// center
if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) {
- const QRect targetCenterRect(targetCenterLeft, targetCenterTop, targetCenterWidth, targetCenterHeight);
- const QRect sourceCenterRect(sourceCenterLeft, sourceCenterTop, sourceCenterWidth, sourceCenterHeight);
- switch (rules.horizontal) {
- case Qt::Stretch:
- switch (rules.vertical) {
- case Qt::Stretch: // stretch stretch
- qDrawPixmap(painter, targetCenterRect, pixmap, sourceCenterRect);
- break;
- case Qt::Repeat: // stretch repeat
- qVerticalRepeat(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawPixmap);
- break;
- case Qt::Round: // stretch round
- qVerticalRound(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawPixmap);
- break;
- }
- break;
- case Qt::Repeat:
- switch (rules.vertical) {
- case Qt::Stretch: // repeat stretch
- qHorizontalRepeat(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawPixmap);
- break;
- case Qt::Repeat: // repeat repeat
- qVerticalRepeat(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawHorizontallyRepeatedPixmap);
- break;
- case Qt::Round: // repeat round
- qVerticalRound(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawHorizontallyRepeatedPixmap);
- break;
+ QDrawPixmapsDataArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData;
+ d.source = QRectF(sourceCenterLeft, sourceCenterTop, sourceCenterWidth, sourceCenterHeight);
+ d.scaleX = dx / d.source.width();
+ d.scaleY = dy / d.source.height();
+
+ qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX;
+ qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY;
+
+ for (int j = 1; j < rows - 1; ++j) {
+ d.point.setY(0.5 * (yTarget[j + 1] + yTarget[j]));
+ for (int i = 1; i < columns - 1; ++i) {
+ d.point.setX(0.5 * (xTarget[i + 1] + xTarget[i]));
+ data.append(d);
}
- break;
- case Qt::Round:
- switch (rules.vertical) {
- case Qt::Stretch: // round stretch
- qHorizontalRound(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawPixmap);
- break;
- case Qt::Repeat: // round repeat
- qHorizontalRound(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawVerticallyRepeatedPixmap);
- break;
- case Qt::Round: // round round
- qHorizontalRound(painter, targetCenterRect, pixmap, sourceCenterRect, qDrawVerticallyRoundedPixmap);
- break;
- }
- break;
+ if (rules.horizontal == Qt::RepeatTile)
+ data[data.size() - 1].source.setWidth(repeatWidth);
+ }
+ if (rules.vertical == Qt::RepeatTile) {
+ for (int i = 1; i < columns - 1; ++i)
+ data[data.size() - i].source.setHeight(repeatHeight);
}
}
+
+ if (opaqueData.size())
+ qDrawPixmaps(painter, opaqueData.data(), opaqueData.size(), pixmap, QDrawPixmaps::OpaqueHint);
+ if (translucentData.size())
+ qDrawPixmaps(painter, translucentData.data(), translucentData.size(), pixmap);
+}
+
+/*!
+ \class QDrawPixmaps::Data
+ \since 4.6
+ \internal
+
+ This structure is used with the qDrawPixmaps() function.
+
+ QPointF point: Specifies the center of the target rectangle.
+ QRectF source: Specifies the source rectangle in the pixmap passed into the qDrawPixmaps() call.
+ qreal scaleX: Specifies the horizontal scale of the target rectangle.
+ qreal scaleY: Specifies the vertical scale of the target rectangle.
+ qreal rotation: Specifies the rotation of the target rectangle in degrees.
+ The target rectangle is rotated after scaling.
+ qreal opacity: Specifies the opacity of the rectangle.
+*/
+
+/*!
+ \enum QDrawPixmaps::DrawingHint
+ \internal
+*/
+
+/*!
+ \internal
+ \since 4.6
+
+ This function is used to draw \a pixmap, or a sub-rectangle of \a pixmap, at multiple positions
+ with different scale, rotation and opacity on \a painter. \a drawingData is an array of \a
+ dataCount elements specifying the parameters used to draw each pixmap instance.
+ This can be used for example to implement a particle system.
+*/
+void qDrawPixmaps(QPainter *painter, const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints)
+{
+ QPaintEngine *engine = painter->paintEngine();
+ if (!engine)
+ return;
+
+ if (engine->isExtended()) {
+ static_cast<QPaintEngineEx *>(engine)->drawPixmaps(drawingData, dataCount, pixmap, hints);
+ } else {
+ qreal oldOpacity = painter->opacity();
+ QTransform oldTransform = painter->transform();
+
+ for (int i = 0; i < dataCount; ++i) {
+ QTransform transform = oldTransform;
+ transform.translate(drawingData[i].point.x(), drawingData[i].point.y());
+ transform.rotate(drawingData[i].rotation);
+ painter->setOpacity(oldOpacity * drawingData[i].opacity);
+ painter->setTransform(transform);
+
+ qreal w = drawingData[i].scaleX * drawingData[i].source.width();
+ qreal h = drawingData[i].scaleY * drawingData[i].source.height();
+ painter->drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, drawingData[i].source);
+ }
+
+ painter->setOpacity(oldOpacity);
+ painter->setTransform(oldTransform);
+ }
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawutil.h b/src/gui/painting/qdrawutil.h
index 3a2dd0e..fff1cc1 100644
--- a/src/gui/painting/qdrawutil.h
+++ b/src/gui/painting/qdrawutil.h
@@ -137,27 +137,82 @@ struct QTileRules
{
inline QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule)
: horizontal(horizontalRule), vertical(verticalRule) {}
- inline QTileRules(Qt::TileRule rule = Qt::Stretch)
+ inline QTileRules(Qt::TileRule rule = Qt::StretchTile)
: horizontal(rule), vertical(rule) {}
Qt::TileRule horizontal;
Qt::TileRule vertical;
};
-Q_GUI_EXPORT void qDrawBorderPixmap(QPainter *painter,
- const QRect &targetRect,
- const QMargins &targetMargins,
+#ifndef Q_QDOC
+// For internal use only.
+namespace QDrawBorderPixmap
+{
+ enum DrawingHint
+ {
+ OpaqueTopLeft = 0x0001,
+ OpaqueTop = 0x0002,
+ OpaqueTopRight = 0x0004,
+ OpaqueLeft = 0x0008,
+ OpaqueCenter = 0x0010,
+ OpaqueRight = 0x0020,
+ OpaqueBottomLeft = 0x0040,
+ OpaqueBottom = 0x0080,
+ OpaqueBottomRight = 0x0100,
+ OpaqueCorners = OpaqueTopLeft | OpaqueTopRight | OpaqueBottomLeft | OpaqueBottomRight,
+ OpaqueEdges = OpaqueTop | OpaqueLeft | OpaqueRight | OpaqueBottom,
+ OpaqueFrame = OpaqueCorners | OpaqueEdges,
+ OpaqueAll = OpaqueCenter | OpaqueFrame
+ };
+
+ Q_DECLARE_FLAGS(DrawingHints, DrawingHint)
+}
+#endif
+
+Q_GUI_EXPORT void qDrawBorderPixmap(QPainter *painter,
+ const QRect &targetRect,
+ const QMargins &targetMargins,
const QPixmap &pixmap,
- const QRect &sourceRect,
- const QMargins &sourceMargins,
- const QTileRules &rules = QTileRules());
-inline void qDrawBorderPixmap(QPainter *painter,
- const QRect &target,
- const QMargins &margins,
+ const QRect &sourceRect,
+ const QMargins &sourceMargins,
+ const QTileRules &rules = QTileRules()
+#ifndef Q_QDOC
+ , QDrawBorderPixmap::DrawingHints hints = 0
+#endif
+ );
+
+inline void qDrawBorderPixmap(QPainter *painter,
+ const QRect &target,
+ const QMargins &margins,
const QPixmap &pixmap)
{
qDrawBorderPixmap(painter, target, margins, pixmap, pixmap.rect(), margins);
}
+// For internal use only.
+namespace QDrawPixmaps
+{
+ struct Data
+ {
+ QPointF point;
+ QRectF source;
+ qreal scaleX;
+ qreal scaleY;
+ qreal rotation;
+ qreal opacity;
+ };
+
+ enum DrawingHint
+ {
+ OpaqueHint = 0x01
+ };
+
+ Q_DECLARE_FLAGS(DrawingHints, DrawingHint)
+}
+
+// This function is private and may change without notice. Do not use outside Qt!!!
+Q_GUI_EXPORT void qDrawPixmaps(QPainter *painter, const QDrawPixmaps::Data *drawingData,
+ int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints hints = 0);
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/gui/painting/qpaintengine_s60.cpp b/src/gui/painting/qpaintengine_s60.cpp
index e17dba1..6f4f398 100644
--- a/src/gui/painting/qpaintengine_s60.cpp
+++ b/src/gui/painting/qpaintengine_s60.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
class QS60PaintEnginePrivate : public QRasterPaintEnginePrivate
{
public:
- QS60PaintEnginePrivate(QS60PaintEngine *engine) { }
+ QS60PaintEnginePrivate(QS60PaintEngine *engine) { Q_UNUSED(engine); }
};
QS60PaintEngine::QS60PaintEngine(QPaintDevice *device, QS60PixmapData *data)
diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp
index 4d2521a..59482c6 100644
--- a/src/gui/painting/qpaintengine_x11.cpp
+++ b/src/gui/painting/qpaintengine_x11.cpp
@@ -1402,6 +1402,7 @@ void QX11PaintEngine::updateBrush(const QBrush &brush, const QPointF &origin)
mask |= GCTile;
#ifndef QT_NO_XRENDER
if (d->pdev_depth == 32 && d->brush_pm.depth() != 32) {
+ d->brush_pm.detach();
QX11PixmapData *brushData = static_cast<QX11PixmapData*>(d->brush_pm.data.data());
brushData->convertToARGB32();
}
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 60e4df6..195be0a 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -932,6 +932,31 @@ void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, con
fill(path, brush);
}
+void QPaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints /*hints*/)
+{
+ qreal oldOpacity = state()->opacity;
+ QTransform oldTransform = state()->matrix;
+
+ for (int i = 0; i < dataCount; ++i) {
+ QTransform transform = oldTransform;
+ transform.translate(drawingData[i].point.x(), drawingData[i].point.y());
+ transform.rotate(drawingData[i].rotation);
+ state()->opacity = oldOpacity * drawingData[i].opacity;
+ state()->matrix = transform;
+ opacityChanged();
+ transformChanged();
+
+ qreal w = drawingData[i].scaleX * drawingData[i].source.width();
+ qreal h = drawingData[i].scaleY * drawingData[i].source.height();
+ drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, drawingData[i].source);
+ }
+
+ state()->opacity = oldOpacity;
+ state()->matrix = oldTransform;
+ opacityChanged();
+ transformChanged();
+}
+
void QPaintEngineEx::setState(QPainterState *s)
{
QPaintEngine::state = s;
diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h
index 814a0f0..3ec9bd6 100644
--- a/src/gui/painting/qpaintengineex_p.h
+++ b/src/gui/painting/qpaintengineex_p.h
@@ -54,6 +54,7 @@
//
#include <QtGui/qpaintengine.h>
+#include <QtGui/qdrawutil.h>
#include <private/qpaintengine_p.h>
#include <private/qstroker_p.h>
@@ -71,7 +72,6 @@ class QPainterState;
class QPaintEngineExPrivate;
struct StrokeHandler;
-
struct QIntRect {
int x1, y1, x2, y2;
inline void set(const QRect &r) {
@@ -133,8 +133,6 @@ public:
qreal pts[8];
};
-
-
#ifndef QT_NO_DEBUG_STREAM
QDebug Q_GUI_EXPORT &operator<<(QDebug &, const QVectorPath &path);
#endif
@@ -198,6 +196,8 @@ public:
virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
+ virtual void drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QFlags<QDrawPixmaps::DrawingHint> hints);
+
virtual void updateState(const QPaintEngineState &state);
virtual void setState(QPainterState *s);
diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp
index a050cb2..41efc80 100644
--- a/src/gui/painting/qpen.cpp
+++ b/src/gui/painting/qpen.cpp
@@ -411,6 +411,8 @@ Qt::PenStyle QPen::style() const
pattern using the setDashPattern() function which implicitly
converts the style of the pen to Qt::CustomDashLine.
+ \note This function resets the dash offset to zero.
+
\sa style(), {QPen#Pen Style}{Pen Style}
*/
@@ -420,7 +422,9 @@ void QPen::setStyle(Qt::PenStyle s)
return;
detach();
d->style = s;
- static_cast<QPenData *>(d)->dashPattern.clear();
+ QPenData *dd = static_cast<QPenData *>(d);
+ dd->dashPattern.clear();
+ dd->dashOffset = 0;
}
/*!
@@ -538,8 +542,12 @@ void QPen::setDashOffset(qreal offset)
if (qFuzzyCompare(offset, static_cast<QPenData *>(d)->dashOffset))
return;
detach();
- static_cast<QPenData *>(d)->dashOffset = offset;
- d->style = Qt::CustomDashLine;
+ QPenData *dd = static_cast<QPenData *>(d);
+ dd->dashOffset = offset;
+ if (d->style != Qt::CustomDashLine) {
+ dd->dashPattern = dashPattern();
+ d->style = Qt::CustomDashLine;
+ }
}
/*!
diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp
index e73282f..4cccc91 100644
--- a/src/gui/painting/qprintengine_pdf.cpp
+++ b/src/gui/painting/qprintengine_pdf.cpp
@@ -534,7 +534,7 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n
QImage image = img;
QImage::Format format = image.format();
- if (image.depth() == 1 && *bitmap) {
+ if (image.depth() == 1 && *bitmap && img.colorTable().size() == 0) {
if (format == QImage::Format_MonoLSB)
image = image.convertToFormat(QImage::Format_Mono);
format = QImage::Format_Mono;
diff --git a/src/gui/painting/qprintengine_ps.cpp b/src/gui/painting/qprintengine_ps.cpp
index 772a30d..b740fbc 100644
--- a/src/gui/painting/qprintengine_ps.cpp
+++ b/src/gui/painting/qprintengine_ps.cpp
@@ -751,6 +751,7 @@ bool QPSPrintEngine::begin(QPaintDevice *pdev)
d->boundingBox = QRect();
d->fontsUsed = "";
d->hugeDocument = false;
+ d->simplePen = false;
setActive(true);
d->printerState = QPrinter::Active;
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index abe9e5e..8118450 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -52,7 +52,7 @@
QT_BEGIN_NAMESPACE
-#define Q_NEAR_CLIP 0.000001
+#define Q_NEAR_CLIP (sizeof(qreal) == sizeof(double) ? 0.000001 : 0.0001)
#ifdef MAP
# undef MAP
diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp
index 592b34c..3a118bd 100644
--- a/src/gui/painting/qwindowsurface_raster.cpp
+++ b/src/gui/painting/qwindowsurface_raster.cpp
@@ -140,7 +140,7 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
// Not ready for painting yet, bail out. This can happen in
// QWidget::create_sys()
- if (!d->image)
+ if (!d->image || rgn.numRects() == 0)
return;
#ifdef Q_WS_WIN
@@ -203,9 +203,11 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
wrgn.translate(-wOffset);
QRect wbr = wrgn.boundingRect();
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects(wrgn, num);
- XSetClipRectangles(X11->display, d_ptr->gc, 0, 0, rects, num, YXBanded);
+ if (wrgn.numRects() != 1) {
+ int num;
+ XRectangle *rects = (XRectangle *)qt_getClipRects(wrgn, num);
+ XSetClipRectangles(X11->display, d_ptr->gc, 0, 0, rects, num, YXBanded);
+ }
QRect br = rgn.boundingRect().translated(offset);
#ifndef QT_NO_MITSHM
@@ -219,17 +221,23 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi
const QImage &src = d->image->image;
br = br.intersected(src.rect());
if (src.format() != QImage::Format_RGB32 || widget->x11Info().depth() < 24) {
+ Q_ASSERT(src.depth() >= 16);
+ const QImage sub_src(src.scanLine(br.y()) + br.x() * (uint(src.depth()) / 8),
+ br.width(), br.height(), src.bytesPerLine(), src.format());
QX11PixmapData *data = new QX11PixmapData(QPixmapData::PixmapType);
data->xinfo = widget->x11Info();
- data->fromImage(src, Qt::AutoColor);
+ data->fromImage(sub_src, Qt::NoOpaqueDetection);
QPixmap pm = QPixmap(data);
- XCopyArea(X11->display, pm.handle(), widget->handle(), d_ptr->gc, br.x() , br.y() , br.width(), br.height(), wbr.x(), wbr.y());
+ XCopyArea(X11->display, pm.handle(), widget->handle(), d_ptr->gc, 0 , 0 , br.width(), br.height(), wbr.x(), wbr.y());
} else {
// qpaintengine_x11.cpp
extern void qt_x11_drawImage(const QRect &rect, const QPoint &pos, const QImage &image, Drawable hd, GC gc, Display *dpy, Visual *visual, int depth);
qt_x11_drawImage(br, wbr.topLeft(), src, widget->handle(), d_ptr->gc, X11->display, (Visual *)widget->x11Info().visual(), widget->x11Info().depth());
}
}
+
+ if (wrgn.numRects() != 1)
+ XSetClipMask(X11->display, d_ptr->gc, XNone);
#endif // FALCON
#ifdef Q_WS_MAC
diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp
index 664ad48..dc4e43b 100644
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ b/src/gui/painting/qwindowsurface_s60.cpp
@@ -85,7 +85,9 @@ QS60WindowSurface::~QS60WindowSurface()
void QS60WindowSurface::beginPaint(const QRegion &rgn)
{
if (!qt_widget_private(window())->isOpaque) {
- QImage image = static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data())->image;
+ QS60PixmapData *pixmapData = static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data());
+ pixmapData->beginDataAccess();
+ QImage &image = pixmapData->image;
QRgb *data = reinterpret_cast<QRgb *>(image.bits());
const int row_stride = image.bytesPerLine() / 4;
@@ -103,6 +105,7 @@ void QS60WindowSurface::beginPaint(const QRegion &rgn)
row += row_stride;
}
}
+ pixmapData->endDataAccess();
}
}
diff --git a/src/gui/painting/qwindowsurface_x11.cpp b/src/gui/painting/qwindowsurface_x11.cpp
index 5e4433c..46c4c42 100644
--- a/src/gui/painting/qwindowsurface_x11.cpp
+++ b/src/gui/painting/qwindowsurface_x11.cpp
@@ -129,9 +129,12 @@ void QX11WindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint
// qDebug() << "XSetClipRectangles";
// for (int i = 0; i < num; ++i)
// qDebug() << ' ' << i << rects[i].x << rects[i].x << rects[i].y << rects[i].width << rects[i].height;
- XSetClipRectangles(X11->display, gc, 0, 0, rects, num, YXBanded);
+ if (num != 1)
+ XSetClipRectangles(X11->display, gc, 0, 0, rects, num, YXBanded);
XCopyArea(X11->display, d_ptr->device.handle(), widget->handle(), gc,
br.x() + offset.x(), br.y() + offset.y(), br.width(), br.height(), wbr.x(), wbr.y());
+ if (num != 1)
+ XSetClipMask(X11->display, gc, XNone);
}
void QX11WindowSurface::setGeometry(const QRect &rect)
diff --git a/src/gui/s60framework/qs60mainapplication.cpp b/src/gui/s60framework/qs60mainapplication.cpp
index 54fb3b1..82e7743 100644
--- a/src/gui/s60framework/qs60mainapplication.cpp
+++ b/src/gui/s60framework/qs60mainapplication.cpp
@@ -60,27 +60,32 @@ CApaApplication *newS60Application()
_LIT(KQtWrapperResourceFile, "\\resource\\apps\\s60main.rsc");
/*!
- * \class QS60MainApplication
- * \obsolete
- * \since 4.6
- * \brief Helper class for S60 migration
- *
- * The QS60MainApplication provides a helper class for use in migrating from existing S60 based
- * applications to Qt based applications. It is used in the exact same way as the
- * \c CAknApplication class from Symbian, but internally provides extensions used by Qt.
- *
- * When modifying old S60 applications that rely on implementing functions in \c CAknApplication,
- * the class should be modified to inherit from this class instead of \c CAknApplication. Then the
- * application can choose to override only certain functions. To make Qt use the custom application
- * objects, pass a factory function to
- * QApplication::QApplication(QApplication::QS60MainApplicationFactory, int &, char **).
- *
- * For more information on \c CAknApplication, please see the S60 documentation.
- *
- * Unlike other Qt classes, QS60MainApplication behaves like an S60 class, and can throw Symbian
- * leaves.
- *
- * \sa QS60MainDocument, QS60MainAppUi, QApplication::QApplication(QApplication::QS60MainApplicationFactory, int &, char **)
+ \class QS60MainApplication
+ \since 4.6
+ \brief The QS60MainApplication class provides support for migration from S60.
+
+ \warning This class is provided only to get access to S60 specific
+ functionality in the application framework classes. It is not
+ portable. We strongly recommend against using it in new applications.
+
+ The QS60MainApplication provides a helper class for use in migrating
+ from existing S60 based applications to Qt based applications. It is
+ used in the exact same way as the \c CAknApplication class from
+ Symbian, but internally provides extensions used by Qt.
+
+ When modifying old S60 applications that rely on implementing
+ functions in \c CAknApplication, the class should be modified to
+ inherit from this class instead of \c CAknApplication. Then the
+ application can choose to override only certain functions. To make
+ Qt use the custom application objects, pass a factory function to
+ \c{QApplication::QApplication(QApplication::QS60MainApplicationFactory, int &, char **)}.
+
+ For more information on \c CAknApplication, please see the S60 documentation.
+
+ Unlike other Qt classes, QS60MainApplication behaves like an S60 class, and can throw Symbian
+ leaves.
+
+ \sa QS60MainDocument, QS60MainAppUi, QApplication::QS60MainApplicationFactory
*/
/*!
diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp
index 9e2333b..611ca59 100644
--- a/src/gui/s60framework/qs60mainappui.cpp
+++ b/src/gui/s60framework/qs60mainappui.cpp
@@ -51,30 +51,38 @@
#include "qs60mainappui.h"
#include <QtGui/qapplication.h>
#include <QtGui/qmenu.h>
-#include <QtGui/private/qt_s60_p.h>
+#include <private/qmenu_p.h>
+#include <private/qt_s60_p.h>
+#include <qdebug.h>
QT_BEGIN_NAMESPACE
/*!
- * \class QS60MainAppUi
- * \obsolete
- * \since 4.6
- * \brief Helper class for S60 migration
- *
- * The QS60MainAppUi provides a helper class for use in migrating from existing S60 based
- * applications to Qt based applications. It is used in the exact same way as the
- * \c CAknAppUi class from Symbian, but internally provides extensions used by Qt.
- *
- * When modifying old S60 applications that rely on implementing functions in \c CAknAppUi,
- * the class should be modified to inherit from this class instead of \c CAknAppUi. Then the
- * application can choose to override only certain functions.
- *
- * For more information on \c CAknAppUi, please see the S60 documentation.
- *
- * Unlike other Qt classes, QS60MainAppUi behaves like an S60 class, and can throw Symbian
- * leaves.
- *
- * \sa QS60MainDocument, QS60MainApplication
+ \class QS60MainAppUi
+ \since 4.6
+ \brief Helper class for S60 migration
+
+ \warning This class is provided only to get access to S60 specific
+ functionality in the application framework classes. It is not
+ portable. We strongly recommend against using it in new applications.
+
+ The QS60MainAppUi provides a helper class for use in migrating from
+ existing S60 based applications to Qt based applications. It is used
+ in the exact same way as the \c CAknAppUi class from Symbian, but
+ internally provides extensions used by Qt.
+
+ When modifying old S60 applications that rely on implementing
+ functions in \c CAknAppUi, the class should be modified to inherit
+ from this class instead of \c CAknAppUi. Then the application can
+ choose to override only certain functions.
+
+ For more information on \c CAknAppUi, please see the S60
+ documentation.
+
+ Unlike other Qt classes, QS60MainAppUi behaves like an S60 class,
+ and can throw Symbian leaves.
+
+ \sa QS60MainDocument, QS60MainApplication
*/
/*!
@@ -226,17 +234,14 @@ void QS60MainAppUi::DynInitMenuPaneL(TInt resourceId, CEikMenuPane *menuPane)
*/
void QS60MainAppUi::RestoreMenuL(CCoeControl* menuWindow, TInt resourceId, TMenuType menuType)
{
- if ((resourceId == R_QT_WRAPPERAPP_MENUBAR) || (resourceId == R_AVKON_MENUPANE_FEP_DEFAULT)) {
- TResourceReader reader;
- iCoeEnv->CreateResourceReaderLC(reader, resourceId);
- menuWindow->ConstructFromResourceL(reader);
- CleanupStack::PopAndDestroy();
+ if (resourceId >= QT_SYMBIAN_FIRST_MENU_ITEM && resourceId <= QT_SYMBIAN_LAST_MENU_ITEM) {
+ if (menuType == EMenuPane)
+ DynInitMenuPaneL(resourceId, (CEikMenuPane*)menuWindow);
+ else
+ DynInitMenuBarL(resourceId, (CEikMenuBar*)menuWindow);
+ } else {
+ CAknAppUi::RestoreMenuL(menuWindow, resourceId, menuType);
}
-
- if (menuType == EMenuPane)
- DynInitMenuPaneL(resourceId, (CEikMenuPane*)menuWindow);
- else
- DynInitMenuBarL(resourceId, (CEikMenuBar*)menuWindow);
}
QT_END_NAMESPACE
diff --git a/src/gui/s60framework/qs60mainappui.h b/src/gui/s60framework/qs60mainappui.h
index c2c6ef2..321d8d6 100644
--- a/src/gui/s60framework/qs60mainappui.h
+++ b/src/gui/s60framework/qs60mainappui.h
@@ -42,7 +42,7 @@
#ifndef QS60MAINAPPUI_H
#define QS60MAINAPPUI_H
-#include <qglobal.h>
+#include <QtCore/qglobal.h>
#ifdef Q_WS_S60
diff --git a/src/gui/s60framework/qs60maindocument.cpp b/src/gui/s60framework/qs60maindocument.cpp
index 52595db..54df17e 100644
--- a/src/gui/s60framework/qs60maindocument.cpp
+++ b/src/gui/s60framework/qs60maindocument.cpp
@@ -47,25 +47,31 @@
QT_BEGIN_NAMESPACE
/*!
- * \class QS60MainDocument
- * \obsolete
- * \since 4.6
- * \brief Helper class for S60 migration
- *
- * The QS60MainDocument provides a helper class for use in migrating from existing S60 based
- * applications to Qt based applications. It is used in the exact same way as the
- * \c CAknDocument class from Symbian, but internally provides extensions used by Qt.
- *
- * When modifying old S60 applications that rely on implementing functions in \c CAknDocument,
- * the class should be modified to inherit from this class instead of \c CAknDocument. Then the
- * application can choose to override only certain functions.
- *
- * For more information on \c CAknDocument, please see the S60 documentation.
- *
- * Unlike other Qt classes, QS60MainDocument behaves like an S60 class, and can throw Symbian
- * leaves.
- *
- * \sa QS60MainApplication, QS60MainAppUi
+ \class QS60MainDocument
+ \since 4.6
+ \brief Helper class for S60 migration
+
+ \warning This class is provided only to get access to S60 specific
+ functionality in the application framework classes. It is not
+ portable. We strongly recommend against using it in new applications.
+
+ The QS60MainDocument provides a helper class for use in migrating
+ from existing S60 based applications to Qt based applications. It is
+ used in the exact same way as the \c CAknDocument class from
+ Symbian, but internally provides extensions used by Qt.
+
+ When modifying old S60 applications that rely on implementing
+ functions in \c CAknDocument, the class should be modified to
+ inherit from this class instead of \c CAknDocument. Then the
+ application can choose to override only certain functions.
+
+ For more information on \c CAknDocument, please see the S60
+ documentation.
+
+ Unlike other Qt classes, QS60MainDocument behaves like an S60 class,
+ and can throw Symbian leaves.
+
+ \sa QS60MainApplication, QS60MainAppUi
*/
/*!
diff --git a/src/gui/s60framework/qs60maindocument.h b/src/gui/s60framework/qs60maindocument.h
index 366d311..1327349 100644
--- a/src/gui/s60framework/qs60maindocument.h
+++ b/src/gui/s60framework/qs60maindocument.h
@@ -42,7 +42,7 @@
#ifndef QS60MAINDOCUMENT_H
#define QS60MAINDOCUMENT_H
-#include <qglobal.h>
+#include <QtCore/qglobal.h>
#ifdef Q_WS_S60
diff --git a/src/gui/statemachine/qguistatemachine.cpp b/src/gui/statemachine/qguistatemachine.cpp
index e9a0b78..1de5ffa 100644
--- a/src/gui/statemachine/qguistatemachine.cpp
+++ b/src/gui/statemachine/qguistatemachine.cpp
@@ -90,52 +90,38 @@ static QEvent *cloneEvent(QEvent *e)
case QEvent::Close:
return new QCloseEvent(*static_cast<QCloseEvent*>(e));
case QEvent::Quit:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ParentChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ParentAboutToChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ThreadChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::WindowActivate:
case QEvent::WindowDeactivate:
return new QEvent(*e);
case QEvent::ShowToParent:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::HideToParent:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::Wheel:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QWheelEvent(*static_cast<QWheelEvent*>(e));
case QEvent::WindowTitleChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::WindowIconChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ApplicationWindowIconChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ApplicationFontChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ApplicationLayoutDirectionChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ApplicationPaletteChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::PaletteChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::Clipboard:
Q_ASSERT_X(false, "cloneEvent()", "not implemented");
break;
@@ -146,14 +132,11 @@ static QEvent *cloneEvent(QEvent *e)
Q_ASSERT_X(false, "cloneEvent()", "not implemented");
break;
case QEvent::SockAct:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::WinEventAct:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::DeferredDelete:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
#ifndef QT_NO_DRAGANDDROP
case QEvent::DragEnter:
return new QDragEnterEvent(*static_cast<QDragEnterEvent*>(e));
@@ -164,139 +147,99 @@ static QEvent *cloneEvent(QEvent *e)
case QEvent::Drop:
return new QDropEvent(*static_cast<QDragMoveEvent*>(e));
case QEvent::DragResponse:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QDragResponseEvent(*static_cast<QDragResponseEvent*>(e));
#endif
case QEvent::ChildAdded:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QChildEvent(*static_cast<QChildEvent*>(e));
case QEvent::ChildPolished:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QChildEvent(*static_cast<QChildEvent*>(e));
#ifdef QT3_SUPPORT
case QEvent::ChildInsertedRequest:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ChildInserted:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QChildEvent(*static_cast<QChildEvent*>(e));
case QEvent::LayoutHint:
Q_ASSERT_X(false, "cloneEvent()", "not implemented");
break;
#endif
case QEvent::ChildRemoved:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QChildEvent(*static_cast<QChildEvent*>(e));
case QEvent::ShowWindowRequest:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::PolishRequest:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::Polish:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::LayoutRequest:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::UpdateRequest:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::UpdateLater:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::EmbeddingControl:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ActivateControl:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::DeactivateControl:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
+
case QEvent::ContextMenu:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QContextMenuEvent(*static_cast<QContextMenuEvent*>(e));
case QEvent::InputMethod:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QInputMethodEvent(*static_cast<QInputMethodEvent*>(e));
case QEvent::AccessibilityPrepare:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::TabletMove:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QTabletEvent(*static_cast<QTabletEvent*>(e));
case QEvent::LocaleChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::LanguageChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::LayoutDirectionChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::Style:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::TabletPress:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QTabletEvent(*static_cast<QTabletEvent*>(e));
case QEvent::TabletRelease:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QTabletEvent(*static_cast<QTabletEvent*>(e));
case QEvent::OkRequest:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::HelpRequest:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::IconDrag:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QIconDragEvent(*static_cast<QIconDragEvent*>(e));
case QEvent::FontChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::EnabledChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ActivationChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::StyleChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::IconTextChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ModifiedChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::MouseTrackingChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::WindowBlocked:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::WindowUnblocked:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::WindowStateChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QWindowStateChangeEvent(*static_cast<QWindowStateChangeEvent*>(e));
case QEvent::ToolTip:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QHelpEvent(*static_cast<QHelpEvent*>(e));
case QEvent::WhatsThis:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QHelpEvent(*static_cast<QHelpEvent*>(e));
case QEvent::StatusTip:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QStatusTipEvent(*static_cast<QStatusTipEvent*>(e));
#ifndef QT_NO_ACTION
case QEvent::ActionChanged:
case QEvent::ActionAdded:
@@ -304,15 +247,12 @@ static QEvent *cloneEvent(QEvent *e)
return new QActionEvent(*static_cast<QActionEvent*>(e));
#endif
case QEvent::FileOpen:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QFileOpenEvent(*static_cast<QFileOpenEvent*>(e));
case QEvent::Shortcut:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QShortcutEvent(*static_cast<QShortcutEvent*>(e));
case QEvent::ShortcutOverride:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QKeyEvent(*static_cast<QKeyEvent*>(e));
#ifdef QT3_SUPPORT
case QEvent::Accel:
@@ -324,43 +264,30 @@ static QEvent *cloneEvent(QEvent *e)
#endif
case QEvent::WhatsThisClicked:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QWhatsThisClickedEvent(*static_cast<QWhatsThisClickedEvent*>(e));
case QEvent::ToolBarChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QToolBarChangeEvent(*static_cast<QToolBarChangeEvent*>(e));
case QEvent::ApplicationActivate:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ApplicationDeactivate:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::QueryWhatsThis:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QHelpEvent(*static_cast<QHelpEvent*>(e));
case QEvent::EnterWhatsThisMode:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::LeaveWhatsThisMode:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ZOrderChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::HoverEnter:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
case QEvent::HoverLeave:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
case QEvent::HoverMove:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QHoverEvent(*static_cast<QHoverEvent*>(e));
case QEvent::AccessibilityHelp:
Q_ASSERT_X(false, "cloneEvent()", "not implemented");
@@ -371,19 +298,17 @@ static QEvent *cloneEvent(QEvent *e)
#ifdef QT_KEYPAD_NAVIGATION
case QEvent::EnterEditFocus:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::LeaveEditFocus:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
#endif
case QEvent::AcceptDropsChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
+#ifdef QT3_SUPPORT
case QEvent::MenubarUpdated:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QMenubarUpdatedEvent(*static_cast<QMenubarUpdatedEvent*>(e));
+#endif
case QEvent::ZeroTimerEvent:
Q_ASSERT_X(false, "cloneEvent()", "not implemented");
@@ -426,80 +351,82 @@ static QEvent *cloneEvent(QEvent *e)
}
case QEvent::GraphicsSceneHoverEnter:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
case QEvent::GraphicsSceneHoverMove:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
- case QEvent::GraphicsSceneHoverLeave:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ case QEvent::GraphicsSceneHoverLeave: {
+ QGraphicsSceneHoverEvent *he = static_cast<QGraphicsSceneHoverEvent*>(e);
+ QGraphicsSceneHoverEvent *he2 = new QGraphicsSceneHoverEvent(he->type());
+ he2->setPos(he->pos());
+ he2->setScenePos(he->scenePos());
+ he2->setScreenPos(he->screenPos());
+ he2->setLastPos(he->lastPos());
+ he2->setLastScenePos(he->lastScenePos());
+ he2->setLastScreenPos(he->lastScreenPos());
+ he2->setModifiers(he->modifiers());
+ return he2;
+ }
case QEvent::GraphicsSceneHelp:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QHelpEvent(*static_cast<QHelpEvent*>(e));
case QEvent::GraphicsSceneDragEnter:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
case QEvent::GraphicsSceneDragMove:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
case QEvent::GraphicsSceneDragLeave:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
- case QEvent::GraphicsSceneDrop:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
- case QEvent::GraphicsSceneWheel:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ case QEvent::GraphicsSceneDrop: {
+ QGraphicsSceneDragDropEvent *dde = static_cast<QGraphicsSceneDragDropEvent*>(e);
+ QGraphicsSceneDragDropEvent *dde2 = new QGraphicsSceneDragDropEvent(dde->type());
+ dde2->setPos(dde->pos());
+ dde2->setScenePos(dde->scenePos());
+ dde2->setScreenPos(dde->screenPos());
+ dde2->setButtons(dde->buttons());
+ dde2->setModifiers(dde->modifiers());
+ return dde2;
+ }
+ case QEvent::GraphicsSceneWheel: {
+ QGraphicsSceneWheelEvent *we = static_cast<QGraphicsSceneWheelEvent*>(e);
+ QGraphicsSceneWheelEvent *we2 = new QGraphicsSceneWheelEvent(we->type());
+ we2->setPos(we->pos());
+ we2->setScenePos(we->scenePos());
+ we2->setScreenPos(we->screenPos());
+ we2->setButtons(we->buttons());
+ we2->setModifiers(we->modifiers());
+ we2->setOrientation(we->orientation());
+ return we2;
+ }
#endif
case QEvent::KeyboardLayoutChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::DynamicPropertyChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QDynamicPropertyChangeEvent(*static_cast<QDynamicPropertyChangeEvent*>(e));
case QEvent::TabletEnterProximity:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
case QEvent::TabletLeaveProximity:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QTabletEvent(*static_cast<QTabletEvent*>(e));
case QEvent::NonClientAreaMouseMove:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
case QEvent::NonClientAreaMouseButtonPress:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
case QEvent::NonClientAreaMouseButtonRelease:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
case QEvent::NonClientAreaMouseButtonDblClick:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QMouseEvent(*static_cast<QMouseEvent*>(e));
case QEvent::MacSizeChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ContentsRectChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::MacGLWindowChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::FutureCallOut:
Q_ASSERT_X(false, "cloneEvent()", "not implemented");
break;
#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneResize:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ case QEvent::GraphicsSceneResize: {
+ QGraphicsSceneResizeEvent *re = static_cast<QGraphicsSceneResizeEvent*>(e);
+ QGraphicsSceneResizeEvent *re2 = new QGraphicsSceneResizeEvent();
+ re2->setOldSize(re->oldSize());
+ re2->setNewSize(re->newSize());
+ return re2;
+ }
case QEvent::GraphicsSceneMove: {
QGraphicsSceneMoveEvent *me = static_cast<QGraphicsSceneMoveEvent*>(e);
QGraphicsSceneMoveEvent *me2 = new QGraphicsSceneMoveEvent();
@@ -510,11 +437,9 @@ static QEvent *cloneEvent(QEvent *e)
}
#endif
case QEvent::CursorChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::ToolTipChange:
- Q_ASSERT_X(false, "cloneEvent()", "not implemented");
- break;
+ return new QEvent(*e);
case QEvent::NetworkReplyUpdated:
Q_ASSERT_X(false, "cloneEvent()", "not implemented");
@@ -531,6 +456,23 @@ static QEvent *cloneEvent(QEvent *e)
Q_ASSERT_X(false, "cloneEvent()", "not implemented");
break;
#endif
+
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ return new QTouchEvent(*static_cast<QTouchEvent*>(e));
+
+ case QEvent::NativeGesture:
+ Q_ASSERT_X(false, "cloneEvent()", "not implemented");
+ break;
+
+ case QEvent::RequestSoftwareInputPanel:
+ case QEvent::CloseSoftwareInputPanel:
+ return new QEvent(*e);
+
+ case QEvent::UpdateSoftKeys:
+ return new QEvent(*e);
+
case QEvent::User:
case QEvent::MaxUser:
Q_ASSERT_X(false, "cloneEvent()", "not implemented");
diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp
index 1cb0ca4..6ec5796 100644
--- a/src/gui/styles/gtksymbols.cpp
+++ b/src/gui/styles/gtksymbols.cpp
@@ -58,6 +58,7 @@
#include <QtCore/QStringList>
#include <QtCore/QTextStream>
#include <QtCore/QHash>
+#include <QtCore/QUrl>
#include <private/qapplication_p.h>
#include <private/qiconloader_p.h>
@@ -124,6 +125,7 @@ Ptr_gtk_progress_set_adjustment QGtk::gtk_progress_set_adjustment = 0;
Ptr_gtk_range_set_adjustment QGtk::gtk_range_set_adjustment = 0;
Ptr_gtk_range_set_inverted QGtk::gtk_range_set_inverted = 0;
Ptr_gtk_icon_factory_lookup_default QGtk::gtk_icon_factory_lookup_default = 0;
+Ptr_gtk_icon_theme_get_default QGtk::gtk_icon_theme_get_default = 0;
Ptr_gtk_widget_style_get QGtk::gtk_widget_style_get = 0;
Ptr_gtk_icon_set_render_icon QGtk::gtk_icon_set_render_icon = 0;
Ptr_gtk_fixed_new QGtk::gtk_fixed_new = 0;
@@ -196,6 +198,9 @@ Ptr_gconf_client_get_default QGtk::gconf_client_get_default = 0;
Ptr_gconf_client_get_string QGtk::gconf_client_get_string = 0;
Ptr_gconf_client_get_bool QGtk::gconf_client_get_bool = 0;
+Ptr_gnome_icon_lookup_sync QGtk::gnome_icon_lookup_sync = 0;
+Ptr_gnome_vfs_init QGtk::gnome_vfs_init = 0;
+
static QString classPath(GtkWidget *widget)
{
char* class_path;
@@ -281,6 +286,7 @@ static void resolveGtk()
QGtk::gtk_range_set_inverted = (Ptr_gtk_range_set_inverted)libgtk.resolve("gtk_range_set_inverted");
QGtk::gtk_container_add = (Ptr_gtk_container_add)libgtk.resolve("gtk_container_add");
QGtk::gtk_icon_factory_lookup_default = (Ptr_gtk_icon_factory_lookup_default)libgtk.resolve("gtk_icon_factory_lookup_default");
+ QGtk::gtk_icon_theme_get_default = (Ptr_gtk_icon_theme_get_default)libgtk.resolve("gtk_icon_theme_get_default");
QGtk::gtk_widget_style_get = (Ptr_gtk_widget_style_get)libgtk.resolve("gtk_widget_style_get");
QGtk::gtk_icon_set_render_icon = (Ptr_gtk_icon_set_render_icon)libgtk.resolve("gtk_icon_set_render_icon");
QGtk::gtk_fixed_new = (Ptr_gtk_fixed_new)libgtk.resolve("gtk_fixed_new");
@@ -325,6 +331,9 @@ static void resolveGtk()
QGtk::pango_font_description_get_weight = (Ptr_pango_font_description_get_weight)libgtk.resolve("pango_font_description_get_weight");
QGtk::pango_font_description_get_family = (Ptr_pango_font_description_get_family)libgtk.resolve("pango_font_description_get_family");
QGtk::pango_font_description_get_style = (Ptr_pango_font_description_get_style)libgtk.resolve("pango_font_description_get_style");
+
+ QGtk::gnome_icon_lookup_sync = (Ptr_gnome_icon_lookup_sync)QLibrary::resolve( QLS("gnomeui-2"), 0, "gnome_icon_lookup_sync");
+ QGtk::gnome_vfs_init= (Ptr_gnome_vfs_init)QLibrary::resolve( QLS("gnomevfs-2"), 0, "gnome_vfs_init");
}
void QGtk::cleanup_gtk_widgets()
@@ -969,6 +978,28 @@ QString QGtk::saveFilename(QWidget *parent, const QString &caption, const QStrin
return filename;
}
+QIcon QGtk::getFilesystemIcon(const QFileInfo &info)
+{
+ QIcon icon;
+ if (QGtk::gnome_vfs_init && QGtk::gnome_icon_lookup_sync) {
+ QGtk::gnome_vfs_init();
+ GtkIconTheme *theme = QGtk::gtk_icon_theme_get_default();
+ QByteArray fileurl = QUrl::fromLocalFile(info.absoluteFilePath()).toEncoded();
+ char * icon_name = QGtk::gnome_icon_lookup_sync(theme,
+ NULL,
+ fileurl.data(),
+ NULL,
+ GNOME_ICON_LOOKUP_FLAGS_NONE,
+ NULL);
+ QString iconName = QString::fromUtf8(icon_name);
+ g_free(icon_name);
+ if (iconName.startsWith(QLatin1Char('/')))
+ return QIcon(iconName);
+ return QIcon::fromTheme(iconName);
+ }
+ return icon;
+}
+
QT_END_NAMESPACE
#endif // !defined(QT_NO_STYLE_GTK)
diff --git a/src/gui/styles/gtksymbols_p.h b/src/gui/styles/gtksymbols_p.h
index 4fb193d..313d948 100644
--- a/src/gui/styles/gtksymbols_p.h
+++ b/src/gui/styles/gtksymbols_p.h
@@ -121,6 +121,7 @@ typedef void (*Ptr_gtk_progress_set_adjustment)(GtkProgress *, GtkAdjustment *);
typedef void (*Ptr_gtk_range_set_inverted)(GtkRange*, bool);
typedef void (*Ptr_gtk_container_add)(GtkContainer *container, GtkWidget *widget);
typedef GtkIconSet* (*Ptr_gtk_icon_factory_lookup_default) (const gchar*);
+typedef GtkIconTheme* (*Ptr_gtk_icon_theme_get_default) (void);
typedef void (*Ptr_gtk_widget_style_get)(GtkWidget *, const gchar *first_property_name, ...);
typedef GtkTreeViewColumn* (*Ptr_gtk_tree_view_column_new)(void);
typedef GtkWidget* (*Ptr_gtk_fixed_new)(void);
@@ -195,6 +196,29 @@ typedef void (*Ptr_gdk_x11_window_set_user_time) (GdkWindow *window, guint32);
typedef XID (*Ptr_gdk_x11_drawable_get_xid) (GdkDrawable *);
typedef Display* (*Ptr_gdk_x11_drawable_get_xdisplay) ( GdkDrawable *);
+
+typedef enum {
+ GNOME_ICON_LOOKUP_FLAGS_NONE = 0,
+ GNOME_ICON_LOOKUP_FLAGS_EMBEDDING_TEXT = 1<<0,
+ GNOME_ICON_LOOKUP_FLAGS_SHOW_SMALL_IMAGES_AS_THEMSELVES = 1<<1,
+ GNOME_ICON_LOOKUP_FLAGS_ALLOW_SVG_AS_THEMSELVES = 1<<2
+} GnomeIconLookupFlags;
+
+typedef enum {
+ GNOME_ICON_LOOKUP_RESULT_FLAGS_NONE = 0,
+ GNOME_ICON_LOOKUP_RESULT_FLAGS_THUMBNAIL = 1<<0
+} GnomeIconLookupResultFlags;
+
+struct GnomeThumbnailFactory;
+typedef gboolean (*Ptr_gnome_vfs_init) (void);
+typedef char* (*Ptr_gnome_icon_lookup_sync) (
+ GtkIconTheme *icon_theme,
+ GnomeThumbnailFactory *,
+ const char *file_uri,
+ const char *custom_icon,
+ GnomeIconLookupFlags flags,
+ GnomeIconLookupResultFlags *result);
+
QT_BEGIN_NAMESPACE
class QGtk
@@ -219,6 +243,7 @@ public:
QString *selectedFilter, QFileDialog::Options options);
static QString getGConfString(const QString &key, const QString &fallback = QString());
static bool getGConfBool(const QString &key, bool fallback = 0);
+ static QIcon getFilesystemIcon(const QFileInfo &);
static Ptr_gtk_container_forall gtk_container_forall;
static Ptr_gtk_init gtk_init;
@@ -263,6 +288,7 @@ public:
static Ptr_gtk_range_set_adjustment gtk_range_set_adjustment;
static Ptr_gtk_range_set_inverted gtk_range_set_inverted;
static Ptr_gtk_icon_factory_lookup_default gtk_icon_factory_lookup_default;
+ static Ptr_gtk_icon_theme_get_default gtk_icon_theme_get_default;
static Ptr_gtk_widget_style_get gtk_widget_style_get;
static Ptr_gtk_icon_set_render_icon gtk_icon_set_render_icon;
static Ptr_gtk_fixed_new gtk_fixed_new;
@@ -333,6 +359,9 @@ public:
static Ptr_gconf_client_get_default gconf_client_get_default;
static Ptr_gconf_client_get_string gconf_client_get_string;
static Ptr_gconf_client_get_bool gconf_client_get_bool;
+
+ static Ptr_gnome_icon_lookup_sync gnome_icon_lookup_sync;
+ static Ptr_gnome_vfs_init gnome_vfs_init;
};
// Helper to ensure that we have polished all our gtk widgets
diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp
index df4f866..5886512 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/gui/styles/qcommonstyle.cpp
@@ -63,7 +63,6 @@
#include <qtoolbar.h>
#include <qtoolbutton.h>
#include <qrubberband.h>
-#include <../kernel/qkde_p.h>
#include <private/qcommonstylepixmaps_p.h>
#include <private/qmath_p.h>
#include <private/qstylehelper_p.h>
@@ -75,6 +74,7 @@
#include <qdir.h>
#include <qsettings.h>
#include <qpixmapcache.h>
+#include <private/qguiplatformplugin_p.h>
#include <limits.h>
@@ -837,35 +837,6 @@ static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbut
}
#endif // QT_NO_TOOLBUTTON
-
-#ifdef Q_WS_X11 // These functions are used to parse the X11 freedesktop icon spec
-
-/*!internal
-
-Checks if you are running KDE and looks up the toolbar
-from the KDE configuration file
-
-*/
-int QCommonStylePrivate::lookupToolButtonStyle() const
-{
- int result = Qt::ToolButtonIconOnly;
- if (X11->desktopEnvironment == DE_KDE && X11->desktopVersion >= 4) {
- QSettings settings(QKde::kdeHome() +
- QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
- settings.beginGroup(QLatin1String("Toolbar style"));
- QString toolbarStyle = settings.value(QLatin1String("ToolButtonStyle"), QLatin1String("TextBesideIcon")).toString();
- if (toolbarStyle == QLatin1String("TextBesideIcon"))
- result = Qt::ToolButtonTextBesideIcon;
- else if (toolbarStyle == QLatin1String("TextOnly"))
- result = Qt::ToolButtonTextOnly;
- else if (toolbarStyle == QLatin1String("TextUnderIcon"))
- result = Qt::ToolButtonTextUnderIcon;
- }
- return result;
-}
-
-#endif //Q_WS_X11
-
#ifndef QT_NO_ITEMVIEWS
QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItemV4 *option, int role) const
@@ -4688,19 +4659,8 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
break;
case PM_ToolBarIconSize:
-#ifdef Q_WS_X11
- if (X11->desktopVersion >= 4) {
- static int iconSize = 0;
- if (!iconSize) {
- QSettings settings(QKde::kdeHome() +
- QLatin1String("/share/config/kdeglobals"),
- QSettings::IniFormat);
- settings.beginGroup(QLatin1String("ToolbarIcons"));
- iconSize = settings.value(QLatin1String("Size"), QLatin1String("22")).toInt();
- }
- ret = iconSize;
- } else
-#endif
+ ret = qt_guiPlatformPlugin()->platformHint(QGuiPlatformPlugin::PH_ToolBarIconSize);
+ if (!ret)
ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
break;
@@ -5098,7 +5058,7 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
break;
case SH_ItemView_ActivateItemOnSingleClick:
- ret = false;
+ ret = qt_guiPlatformPlugin()->platformHint(QGuiPlatformPlugin::PH_ItemView_ActivateItemOnSingleClick);
break;
case SH_TitleBar_ModifyNotification:
@@ -5192,13 +5152,7 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
ret = true;
break;
case SH_ToolButtonStyle:
- ret = Qt::ToolButtonIconOnly;
-#ifdef Q_WS_X11
- {
- static int buttonStyle = d_func()->lookupToolButtonStyle();
- return buttonStyle;
- }
-#endif
+ ret = qt_guiPlatformPlugin()->platformHint(QGuiPlatformPlugin::PH_ToolButtonStyle);
break;
case SH_RequestSoftwareInputPanel:
ret = RSIP_OnMouseClickAndAlreadyFocused;
diff --git a/src/gui/styles/qcommonstyle_p.h b/src/gui/styles/qcommonstyle_p.h
index 7162392..a905601 100644
--- a/src/gui/styles/qcommonstyle_p.h
+++ b/src/gui/styles/qcommonstyle_p.h
@@ -122,7 +122,6 @@ public:
}
#endif
mutable QIcon tabBarcloseButtonIcon;
- int lookupToolButtonStyle() const;
#ifndef QT_NO_TABBAR
void tabLayout(const QStyleOptionTabV3 *opt, const QWidget *widget, QRect *textRect, QRect *pixmapRect) const;
#endif
diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp
index 5052755..ce2109a 100644
--- a/src/gui/styles/qplastiquestyle.cpp
+++ b/src/gui/styles/qplastiquestyle.cpp
@@ -3309,7 +3309,7 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op
// Draw the text centered
QFont font = painter->font();
- font.setPointSize(font.pointSize() - 1);
+ font.setPointSize(QFontInfo(font).pointSize() - 1);
painter->setFont(font);
painter->setPen(dockWidget->palette.windowText().color());
painter->drawText(titleRect,
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index 6bdb79e..4fa1d03 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -706,11 +706,10 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const
palette->setColor(QPalette::AlternateBase, Qt::transparent);
palette->setBrush(QPalette::Base, Qt::transparent);
// set button and tooltipbase based on pixel colors
-// After natitive pixmap support, colorFromFrameGraphics caused reproducable crashes on some setups.
-// const QColor buttonColor = colorFromFrameGraphics(SF_ButtonNormal);
-// palette->setColor(QPalette::Button, buttonColor);
-// const QColor toolTipColor = colorFromFrameGraphics(SF_ToolTip);
-// palette->setColor(QPalette::ToolTipBase, toolTipColor);
+ const QColor buttonColor = colorFromFrameGraphics(SF_ButtonNormal);
+ palette->setColor(QPalette::Button, buttonColor);
+ const QColor toolTipColor = colorFromFrameGraphics(SF_ToolTip);
+ palette->setColor(QPalette::ToolTipBase, toolTipColor);
palette->setColor(QPalette::Light, palette->color(QPalette::Button).lighter());
palette->setColor(QPalette::Dark, palette->color(QPalette::Button).darker());
palette->setColor(QPalette::Midlight, palette->color(QPalette::Button).lighter(125));
@@ -1865,7 +1864,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
painter->setOpacity(opacity);
- painter->setPen(QPen(option->palette.color(QPalette::Highlight), penWidth));
+ painter->setPen(QPen(option->palette.color(QPalette::Text), penWidth));
painter->drawRoundedRect(adjustedRect, roundRectRadius, roundRectRadius);
painter->restore();
}
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index 131d8bc..cde48d8 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -635,8 +635,18 @@ bool QS60StylePrivate::isToolBarBackground()
QPoint qt_s60_fill_background_offset(const QWidget *targetWidget)
{
CCoeControl *control = targetWidget->effectiveWinId();
- TPoint globalPos = control ? control->PositionRelativeToScreen() : TPoint(0,0);
- return QPoint(globalPos.iX, globalPos.iY);
+ TPoint pos(0,0);
+ if (control) {
+ // FIXME properly: S60 3.1 has a bug that CCoeControl::PositionRelativeToScreen sometimes
+ // freezes the device, possibly in cases where we run out of memory.
+ // We use CCoeControl::Position instead in S60 3.1, which returns same values
+ // in most cases.
+ if (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1)
+ pos = control->Position();
+ else
+ pos = control->PositionRelativeToScreen();
+ }
+ return QPoint(pos.iX, pos.iY);
}
QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(
@@ -1137,11 +1147,11 @@ QPixmap QS60StylePrivate::part(QS60StyleEnums::SkinParts part,
const QSize &size, SkinElementFlags flags)
{
QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
-
+
QPixmap result = (flags & SF_ColorSkinned)?
QS60StyleModeSpecifics::colorSkinnedGraphics(part, size, flags)
: QS60StyleModeSpecifics::skinnedGraphics(part, size, flags);
-
+
lock.relock();
if (flags & SF_StateDisabled && !QS60StyleModeSpecifics::disabledPartGraphic(part)) {
diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp
index 0f3a88b..707b05e 100644
--- a/src/gui/styles/qstylesheetstyle.cpp
+++ b/src/gui/styles/qstylesheetstyle.cpp
@@ -1126,7 +1126,7 @@ void QRenderRule::fixupBorder(int nativeWidth)
void QRenderRule::drawBorderImage(QPainter *p, const QRect& rect)
{
static const Qt::TileRule tileMode2TileRule[] = {
- Qt::Stretch, Qt::Round, Qt::Stretch, Qt::Repeat, Qt::Stretch };
+ Qt::StretchTile, Qt::RoundTile, Qt::StretchTile, Qt::RepeatTile, Qt::StretchTile };
const QStyleSheetBorderImageData *borderImageData = border()->borderImage();
const int *targetBorders = border()->borders;
diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp
index b062a3f..6cb8b40 100644
--- a/src/gui/styles/qwindowsvistastyle.cpp
+++ b/src/gui/styles/qwindowsvistastyle.cpp
@@ -731,14 +731,11 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
{
const QStyleOptionViewItemV4 *vopt;
const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
- bool newStyle = false;
+ bool newStyle = true;
+
+ if (qobject_cast<const QTableView*>(widget))
+ newStyle = false;
- if (const QListView *listview = qobject_cast<const QListView *>(widget)) {
- if (listview->viewMode() == QListView::IconMode)
- newStyle = true;
- } else if (qobject_cast<const QTreeView *>(widget)) {
- newStyle = true;
- }
if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))) {
bool selected = vopt->state & QStyle::State_Selected;
bool hover = vopt->state & QStyle::State_MouseOver;
@@ -1496,14 +1493,11 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
{
const QStyleOptionViewItemV4 *vopt;
const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
- bool newStyle = false;
+ bool newStyle = true;
+
+ if (qobject_cast<const QTableView*>(widget))
+ newStyle = false;
- if (const QListView *listview = qobject_cast<const QListView *>(widget)) {
- if (listview->viewMode() == QListView::IconMode)
- newStyle = true;
- } else if (qobject_cast<const QTreeView *>(widget)) {
- newStyle = true;
- }
if (newStyle && view && (vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option))) {
/*
// We cannot currently get the correct selection color for "explorer style" views
diff --git a/src/gui/styles/qwindowsvistastyle_p.h b/src/gui/styles/qwindowsvistastyle_p.h
index d4170aa..e9bbb77 100644
--- a/src/gui/styles/qwindowsvistastyle_p.h
+++ b/src/gui/styles/qwindowsvistastyle_p.h
@@ -84,6 +84,7 @@
#include <qinputdialog.h>
#include <qtreeview.h>
#include <qlistview.h>
+#include <qtableview.h>
#include <qbasictimer.h>
#include <qcommandlinkbutton.h>
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index 5635811..10932a6 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -309,6 +309,7 @@ private:
friend class QPicturePaintEngine;
friend class QPainterReplayer;
friend class QPaintBufferEngine;
+ friend class QCommandLinkButtonPrivate;
#ifndef QT_NO_DATASTREAM
friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QFont &);
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index d8d2730..a4817ab 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -951,7 +951,7 @@ struct QtFontDesc
#if !defined(Q_WS_MAC)
static void match(int script, const QFontDef &request,
const QString &family_name, const QString &foundry_name, int force_encoding_id,
- QtFontDesc *desc, const QList<int> &blacklistedFamilies = QList<int>());
+ QtFontDesc *desc, const QList<int> &blacklistedFamilies = QList<int>(), bool forceXLFD=false);
#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_LITE)
static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef)
@@ -1318,7 +1318,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
*/
static void match(int script, const QFontDef &request,
const QString &family_name, const QString &foundry_name, int force_encoding_id,
- QtFontDesc *desc, const QList<int> &blacklistedFamilies)
+ QtFontDesc *desc, const QList<int> &blacklistedFamilies, bool forceXLFD)
{
Q_UNUSED(force_encoding_id);
@@ -1353,7 +1353,12 @@ static void match(int script, const QFontDef &request,
unsigned int score = ~0u;
+#ifdef Q_WS_X11
+ load(family_name, script, forceXLFD);
+#else
+ Q_UNUSED(forceXLFD);
load(family_name, script);
+#endif
QFontDatabasePrivate *db = privateDb();
for (int x = 0; x < db->count; ++x) {
diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp
index ae93f90..382c4fe 100644
--- a/src/gui/text/qfontdatabase_x11.cpp
+++ b/src/gui/text/qfontdatabase_x11.cpp
@@ -1204,9 +1204,9 @@ static void loadFontConfig()
static void initializeDb();
-static void load(const QString &family = QString(), int script = -1)
+static void load(const QString &family = QString(), int script = -1, bool forceXLFD = false)
{
- if (X11->has_fontconfig) {
+ if (X11->has_fontconfig && !forceXLFD) {
initializeDb();
return;
}
@@ -1784,7 +1784,7 @@ QFontEngine *QFontDatabase::loadXlfd(int screen, int script, const QFontDef &req
QString family, foundry;
QT_PREPEND_NAMESPACE(parseFontName)(families_and_foundries.at(i), foundry, family);
FM_DEBUG("loadXlfd: >>>>>>>>>>>>>>trying to match '%s' encoding=%d", family.toLatin1().data(), force_encoding_id);
- QT_PREPEND_NAMESPACE(match)(script, request, family, foundry, force_encoding_id, &desc);
+ QT_PREPEND_NAMESPACE(match)(script, request, family, foundry, force_encoding_id, &desc, QList<int>(), true);
if (desc.family)
break;
}
@@ -1847,23 +1847,26 @@ QFontEngine *QFontDatabase::loadXlfd(int screen, int script, const QFontDef &req
}
} else {
QList<int> encodings;
- if (desc.encoding)
- encodings.append(int(desc.encoding->encoding));
+ if (desc.encoding) {
+ if (desc.encoding->encoding >= 0)
+ encodings.append(int(desc.encoding->encoding));
+ }
if (desc.size) {
// append all other encodings for the matched font
for (int i = 0; i < desc.size->count; ++i) {
QtFontEncoding *e = desc.size->encodings + i;
- if (e == desc.encoding)
- continue;
+ if (e == desc.encoding || e->encoding < 0)
+ continue;
encodings.append(int(e->encoding));
}
}
// fill in the missing encodings
const XlfdEncoding *enc = xlfd_encoding;
for (; enc->name; ++enc) {
- if (!encodings.contains(enc->id))
+ if (!encodings.contains(enc->id) && enc->id >= 0) {
encodings.append(enc->id);
+ }
}
#if defined(FONT_MATCH_DEBUG)
@@ -1925,6 +1928,13 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
#ifndef QT_NO_FONTCONFIG
} else if (X11->has_fontconfig) {
fe = loadFc(d, script, req);
+
+ if (fe != 0 && fe->fontDef.pixelSize != req.pixelSize) {
+ delete fe;
+ fe = loadXlfd(d->screen, script, req);
+ }
+
+
#endif
} else if (mainThread) {
fe = loadXlfd(d->screen, script, req);
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 728cef4..37f9674 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -1160,7 +1160,7 @@ Q_GLOBAL_STATIC_WITH_INITIALIZER(QVector<QRgb>, qt_grayPalette, {
QRgb *it = x->data();
for (int i = 0; i < x->size(); ++i, ++it)
*it = 0xff000000 | i | (i<<8) | (i<<16);
-});
+})
const QVector<QRgb> &QFontEngine::grayPalette()
{
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index 40db7b4..758d8af 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -138,9 +138,10 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, con
QCFString name;
ATSFontGetName(atsFontRef, kATSOptionFlagsDefault, &name);
- QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pointSize);
- QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pointSize, 0);
- ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pointSize, 0, symbolicTraits, symbolicTraits);
+
+ QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize);
+ QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, 0);
+ ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, 0, symbolicTraits, symbolicTraits);
// CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does
// not exist for the given font. (for example italic)
diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp
index 5ea4554..ff3f628 100644
--- a/src/gui/text/qfontengine_x11.cpp
+++ b/src/gui/text/qfontengine_x11.cpp
@@ -488,9 +488,10 @@ glyph_metrics_t QFontEngineXLFD::boundingBox(const QGlyphLayout &glyphs)
QFixed y = overall.yoff + glyphs.offsets[i].y - xcs->ascent;
overall.x = qMin(overall.x, x);
overall.y = qMin(overall.y, y);
+ // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
xmax = qMax(xmax, overall.xoff + glyphs.offsets[i].x + xcs->rbearing);
ymax = qMax(ymax, y + xcs->ascent + xcs->descent);
- overall.xoff += glyphs.advances_x[i];
+ overall.xoff += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
} else {
QFixed size = _fs->ascent;
overall.x = qMin(overall.x, overall.xoff);
@@ -511,6 +512,8 @@ glyph_metrics_t QFontEngineXLFD::boundingBox(glyph_t glyph)
glyph_metrics_t gm;
XCharStruct *xcs = charStruct(_fs, glyph);
if (xcs) {
+ // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
+ // XCharStruct::width is defined as the advance
gm = glyph_metrics_t(xcs->lbearing, -xcs->ascent, xcs->rbearing- xcs->lbearing, xcs->ascent + xcs->descent,
xcs->width, 0);
} else {
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index 6def06e..ee8b751 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -505,9 +505,13 @@ void QTextControlPrivate::startDrag()
drag->setMimeData(data);
Qt::DropActions actions = Qt::CopyAction;
- if (interactionFlags & Qt::TextEditable)
+ Qt::DropAction action;
+ if (interactionFlags & Qt::TextEditable) {
actions |= Qt::MoveAction;
- Qt::DropAction action = drag->exec(actions, Qt::MoveAction);
+ action = drag->exec(actions, Qt::MoveAction);
+ } else {
+ action = drag->exec(actions, Qt::CopyAction);
+ }
if (action == Qt::MoveAction && drag->target() != contextWidget)
cursor.removeSelectedText();
@@ -1223,11 +1227,13 @@ void QTextControlPrivate::keyPressEvent(QKeyEvent *e)
cursor.deleteChar();
}
else if (e == QKeySequence::DeleteEndOfWord) {
- cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor);
+ if (!cursor.hasSelection())
+ cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor);
cursor.removeSelectedText();
}
else if (e == QKeySequence::DeleteStartOfWord) {
- cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
+ if (!cursor.hasSelection())
+ cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
cursor.removeSelectedText();
}
else if (e == QKeySequence::DeleteEndOfLine) {
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index 3521ade..9b7e8de 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -550,9 +550,9 @@ void QTextOdfWriter::writeCharacterFormat(QXmlStreamWriter &writer, QTextCharFor
}
}
if (format.hasProperty(QTextFormat::FontLetterSpacing))
- writer.writeAttribute(foNS, QString::fromLatin1("letter-spacing"), pixelToPoint(format.fontLetterSpacing()) );
+ writer.writeAttribute(foNS, QString::fromLatin1("letter-spacing"), pixelToPoint(format.fontLetterSpacing()));
if (format.hasProperty(QTextFormat::FontWordSpacing))
- writer.writeAttribute(foNS, QString::fromLatin1("letter-spacing"), pixelToPoint(format.fontWordSpacing()) );
+ writer.writeAttribute(foNS, QString::fromLatin1("word-spacing"), pixelToPoint(format.fontWordSpacing()));
if (format.hasProperty(QTextFormat::FontUnderline))
writer.writeAttribute(styleNS, QString::fromLatin1("text-underline-type"),
format.fontUnderline() ? QString::fromLatin1("single") : QString::fromLatin1("none"));
diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp
index facc8dc..bdab3f2 100644
--- a/src/gui/text/qtextoption.cpp
+++ b/src/gui/text/qtextoption.cpp
@@ -345,9 +345,9 @@ QList<QTextOption::Tab> QTextOption::tabs() const
This enum holds the different types of tabulator
- \value LeftTab, A left-tab
- \value RightTab, A right-tab
- \value CenterTab, A centered-tab
+ \value LeftTab A left-tab
+ \value RightTab A right-tab
+ \value CenterTab A centered-tab
\value DelimiterTab A tab stopping at a certain delimiter-character
*/
diff --git a/src/gui/util/qdesktopservices_win.cpp b/src/gui/util/qdesktopservices_win.cpp
index 9ae3a15..c0bd5e7 100644
--- a/src/gui/util/qdesktopservices_win.cpp
+++ b/src/gui/util/qdesktopservices_win.cpp
@@ -41,6 +41,7 @@
#include <qsettings.h>
#include <qdir.h>
+#include <qlibrary.h>
#include <qurl.h>
#include <qstringlist.h>
#include <qprocess.h>
@@ -58,6 +59,11 @@
# endif
#endif
+#if defined(Q_CC_MINGW) && !defined(CSIDL_MYMUSIC)
+#define CSIDL_MYMUSIC 13
+#define CSIDL_MYVIDEO 14
+#endif
+
#ifndef QT_NO_DESKTOPSERVICES
QT_BEGIN_NAMESPACE
@@ -168,50 +174,76 @@ static bool launchWebBrowser(const QUrl &url)
QString QDesktopServices::storageLocation(StandardLocation type)
{
-#if !defined(QT_NO_SETTINGS)
- QSettings settings(QSettings::UserScope, QLatin1String("Microsoft"), QLatin1String("Windows"));
- settings.beginGroup(QLatin1String("CurrentVersion/Explorer/Shell Folders"));
+ QString result;
+
+#ifndef Q_OS_WINCE
+ QLibrary library(QLatin1String("shell32"));
+#else
+ QLibrary library(QLatin1String("coredll"));
+#endif // Q_OS_WINCE
+ typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL);
+ static GetSpecialFolderPath SHGetSpecialFolderPath =
+ (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
+ if (!SHGetSpecialFolderPath)
+ return QString();
+
+ wchar_t path[MAX_PATH];
+
switch (type) {
- case CacheLocation:
- // Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache
- // location for everyone. Most applications seem to be using a
- // cache directory located in their AppData directory
- return storageLocation(DataLocation) + QLatin1String("\\cache");
case DataLocation:
- if (!settings.contains(QLatin1String("Local AppData")))
- break;
- return settings.value(QLatin1String("Local AppData")).toString()
- + QLatin1String("\\") + QCoreApplication::organizationName()
- + QLatin1String("\\") + QCoreApplication::applicationName();
+#if defined Q_WS_WINCE
+ if (SHGetSpecialFolderPath(0, path, CSIDL_APPDATA, FALSE))
+#else
+ if (SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, FALSE))
+#endif
+ result = QString::fromWCharArray(path);
+ if (!QCoreApplication::organizationName().isEmpty())
+ result = result + QLatin1String("\\") + QCoreApplication::organizationName();
+ if (!QCoreApplication::applicationName().isEmpty())
+ result = result + QLatin1String("\\") + QCoreApplication::applicationName();
break;
+
case DesktopLocation:
- return settings.value(QLatin1String("Desktop")).toString();
+ if (SHGetSpecialFolderPath(0, path, CSIDL_DESKTOPDIRECTORY, FALSE))
+ result = QString::fromWCharArray(path);
break;
case DocumentsLocation:
- return settings.value(QLatin1String("Personal")).toString();
+ if (SHGetSpecialFolderPath(0, path, CSIDL_PERSONAL, FALSE))
+ result = QString::fromWCharArray(path);
break;
case FontsLocation:
- return settings.value(QLatin1String("Fonts")).toString();
+ if (SHGetSpecialFolderPath(0, path, CSIDL_FONTS, FALSE))
+ result = QString::fromWCharArray(path);
break;
case ApplicationsLocation:
- return settings.value(QLatin1String("Programs")).toString();
+ if (SHGetSpecialFolderPath(0, path, CSIDL_PROGRAMS, FALSE))
+ result = QString::fromWCharArray(path);
break;
case MusicLocation:
- return settings.value(QLatin1String("My Music")).toString();
+ if (SHGetSpecialFolderPath(0, path, CSIDL_MYMUSIC, FALSE))
+ result = QString::fromWCharArray(path);
break;
case MoviesLocation:
- return settings.value(QLatin1String("My Video")).toString();
+ if (SHGetSpecialFolderPath(0, path, CSIDL_MYVIDEO, FALSE))
+ result = QString::fromWCharArray(path);
break;
case PicturesLocation:
- return settings.value(QLatin1String("My Pictures")).toString();
+ if (SHGetSpecialFolderPath(0, path, CSIDL_MYPICTURES, FALSE))
+ result = QString::fromWCharArray(path);
break;
+ case CacheLocation:
+ // Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache
+ // location for everyone. Most applications seem to be using a
+ // cache directory located in their AppData directory
+ return storageLocation(DataLocation) + QLatin1String("\\cache");
+
case QDesktopServices::HomeLocation:
return QDir::homePath(); break;
@@ -221,8 +253,7 @@ QString QDesktopServices::storageLocation(StandardLocation type)
default:
break;
}
-#endif
- return QString();
+ return result;
}
QString QDesktopServices::displayName(StandardLocation type)
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp
index d8702cf..0896256 100644
--- a/src/gui/widgets/qabstractscrollarea.cpp
+++ b/src/gui/widgets/qabstractscrollarea.cpp
@@ -52,11 +52,6 @@
#include "qboxlayout.h"
#include "qpainter.h"
-#ifdef Q_WS_WIN
-#include "qstandardgestures.h"
-#include <private/qstandardgestures_p.h>
-#endif
-
#include "qabstractscrollarea_p.h"
#include <qwidget.h>
@@ -165,7 +160,7 @@ QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate()
viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0),
xoffset(0), yoffset(0), viewportFilter(0)
#ifdef Q_WS_WIN
- , panGesture(0), singleFingerPanEnabled(false)
+ , singleFingerPanEnabled(false)
#endif
{
}
@@ -298,14 +293,6 @@ void QAbstractScrollAreaPrivate::init()
q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layoutChildren();
-
-#ifdef Q_WS_WIN
- panGesture = new QPanGesture(viewport, q);
- panGesture->d_func()->implicitGesture = true;
- QObject::connect(panGesture, SIGNAL(started()), q, SLOT(_q_gestureTriggered()));
- QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered()));
- QObject::connect(panGesture, SIGNAL(finished()), q, SLOT(_q_gestureTriggered()));
-#endif // Q_WS_WIN
}
#ifdef Q_WS_WIN
@@ -556,9 +543,6 @@ void QAbstractScrollArea::setViewport(QWidget *widget)
if (isVisible())
d->viewport->show();
QMetaObject::invokeMethod(this, "setupViewport", Q_ARG(QWidget *, widget));
-#ifdef Q_WS_WIN
- d->panGesture->setGestureTarget(widget);
-#endif
delete oldViewport;
}
}
@@ -1351,26 +1335,24 @@ void QAbstractScrollArea::setupViewport(QWidget *viewport)
Q_UNUSED(viewport);
}
-#ifdef Q_WS_WIN
-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);
- }
-}
-#endif
+//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
diff --git a/src/gui/widgets/qabstractscrollarea.h b/src/gui/widgets/qabstractscrollarea.h
index 3773477..b3a1861 100644
--- a/src/gui/widgets/qabstractscrollarea.h
+++ b/src/gui/widgets/qabstractscrollarea.h
@@ -129,10 +129,6 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_vslide(int))
Q_PRIVATE_SLOT(d_func(), void _q_showOrHideScrollBars())
-#ifdef Q_WS_WIN
- Q_PRIVATE_SLOT(d_func(), void _q_gestureTriggered())
-#endif
-
friend class QStyleSheetStyle;
friend class QWidgetPrivate;
};
diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h
index 0bb2851..bfb8917 100644
--- a/src/gui/widgets/qabstractscrollarea_p.h
+++ b/src/gui/widgets/qabstractscrollarea_p.h
@@ -60,7 +60,6 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_SCROLLAREA
-class QPanGesture;
class QScrollBar;
class QAbstractScrollAreaScrollBarContainer;
class Q_AUTOTEST_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate
@@ -102,8 +101,6 @@ public:
QScopedPointer<QObject> viewportFilter;
#ifdef Q_WS_WIN
- QPanGesture *panGesture;
- virtual void _q_gestureTriggered();
bool singleFingerPanEnabled;
void setSingleFingerPanEnabled(bool on = true);
#endif
diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp
index a50c105..588a48e 100644
--- a/src/gui/widgets/qabstractslider.cpp
+++ b/src/gui/widgets/qabstractslider.cpp
@@ -215,7 +215,8 @@ QT_BEGIN_NAMESPACE
QAbstractSliderPrivate::QAbstractSliderPrivate()
: minimum(0), maximum(99), singleStep(1), pageStep(10),
- value(0), position(0), pressValue(-1), tracking(true), blocktracking(false), pressed(false),
+ value(0), position(0), pressValue(-1), offset_accumulated(0), tracking(true),
+ blocktracking(false), pressed(false),
invertedAppearance(false), invertedControls(false),
orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction)
{
@@ -691,38 +692,43 @@ void QAbstractSlider::wheelEvent(QWheelEvent * e)
e->ignore();
if (e->orientation() != d->orientation && !rect().contains(e->pos()))
return;
- static qreal offset = 0;
- static QAbstractSlider *offset_owner = 0;
- if (offset_owner != this){
- offset_owner = this;
- offset = 0;
+
+ qreal currentOffset = qreal(e->delta()) / 120;
+ d->offset_accumulated += currentOffset;
+ if (int(d->offset_accumulated) == 0) {
+ // QAbstractSlider works on integer values. So if the accumulated
+ // offset is less than +/- 1, we need to wait until we get more
+ // wheel events (this means that the wheel resolution is higher than
+ // 15 degrees, e.g. when using mac mighty mouse/trackpad):
+ return;
}
- // On Mac/Cocoa, always scroll one step. The mouse wheel acceleration
- // is higher than on other systems, so this works well in practice.
-#ifdef QT_MAC_USE_COCOA
- int step = 1;
+ int stepsToScroll;
+ if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) {
+ stepsToScroll = currentOffset > 0 ? d->pageStep : -d->pageStep;
+ } else {
+ // Calculate the number of steps to scroll (per 15 degrees of rotate):
+#ifdef Q_OS_MAC
+ // On mac, since mouse wheel scrolling is accelerated and
+ // fine tuned by the OS, we skip applying acceleration:
+ stepsToScroll = int(d->offset_accumulated);
#else
- int step = qMin(QApplication::wheelScrollLines() * d->singleStep, d->pageStep);
+ stepsToScroll = int(d->offset_accumulated) * QApplication::wheelScrollLines() * d->singleStep;
#endif
- if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier))
- step = d->pageStep;
- int currentOffset = qRound(qreal(e->delta()) * step / 120);
- if (currentOffset == 0)
- currentOffset = (e->delta() < 0 ? -1 : 1);
- offset += currentOffset;
+ stepsToScroll = qBound(-d->pageStep, stepsToScroll, d->pageStep);
+ }
if (d->invertedControls)
- offset = -offset;
+ stepsToScroll = -stepsToScroll;
int prevValue = d->value;
- d->position = d->overflowSafeAdd(int(offset)); // value will be updated by triggerAction()
-
+ d->position = d->overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction()
triggerAction(SliderMove);
+
if (prevValue == d->value) {
- offset = 0;
+ d->offset_accumulated = 0;
} else {
- offset -= int(offset);
+ d->offset_accumulated -= int(d->offset_accumulated);
e->accept();
}
}
diff --git a/src/gui/widgets/qabstractslider_p.h b/src/gui/widgets/qabstractslider_p.h
index 071b8df..9324d44 100644
--- a/src/gui/widgets/qabstractslider_p.h
+++ b/src/gui/widgets/qabstractslider_p.h
@@ -69,6 +69,7 @@ public:
void setSteps(int single, int page);
int minimum, maximum, singleStep, pageStep, value, position, pressValue;
+ float offset_accumulated;
uint tracking : 1;
uint blocktracking :1;
uint pressed : 1;
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index 95ff4c1..b606538 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -2443,7 +2443,10 @@ void QComboBox::showPopup()
}
container->setGeometry(listRect);
- bool updatesEnabled = container->updatesEnabled();
+#ifndef Q_WS_MAC
+ const bool updatesEnabled = container->updatesEnabled();
+#endif
+
#if defined(Q_WS_WIN) && !defined(QT_NO_EFFECTS)
bool scrollDown = (listRect.topLeft() == below);
if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo)
diff --git a/src/gui/widgets/qcommandlinkbutton.cpp b/src/gui/widgets/qcommandlinkbutton.cpp
index e64f687..9adf280 100644
--- a/src/gui/widgets/qcommandlinkbutton.cpp
+++ b/src/gui/widgets/qcommandlinkbutton.cpp
@@ -140,23 +140,34 @@ QFont QCommandLinkButtonPrivate::titleFont() const
Q_Q(const QCommandLinkButton);
QFont font = q->font();
if (usingVistaStyle()) {
- if (!q->testAttribute(Qt::WA_SetFont))
- font.setPointSizeF(12.0);
+ font.setPointSizeF(12.0);
} else {
font.setBold(true);
- if (!q->testAttribute(Qt::WA_SetFont))
- font.setPointSizeF(9.0);
+ font.setPointSizeF(9.0);
}
- return font;
+
+ // Note the font will be resolved against
+ // QPainters font, so we need to restore the mask
+ int resolve_mask = font.resolve_mask;
+ QFont modifiedFont = q->font().resolve(font);
+ modifiedFont.detach();
+ modifiedFont.resolve_mask = resolve_mask;
+ return modifiedFont;
}
QFont QCommandLinkButtonPrivate::descriptionFont() const
{
Q_Q(const QCommandLinkButton);
QFont font = q->font();
- if (!q->testAttribute(Qt::WA_SetFont))
- font.setPointSizeF(9.0);
- return font;
+ font.setPointSizeF(9.0);
+
+ // Note the font will be resolved against
+ // QPainters font, so we need to restore the mask
+ int resolve_mask = font.resolve_mask;
+ QFont modifiedFont = q->font().resolve(font);
+ modifiedFont.detach();
+ modifiedFont.resolve_mask = resolve_mask;
+ return modifiedFont;
}
QRect QCommandLinkButtonPrivate::titleRect() const
diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp
index 6cc720d..280ca63 100644
--- a/src/gui/widgets/qdialogbuttonbox.cpp
+++ b/src/gui/widgets/qdialogbuttonbox.cpp
@@ -468,18 +468,6 @@ void QDialogButtonBoxPrivate::layoutButtons()
if (center)
buttonLayout->addStretch();
-
-#ifdef QT_SOFTKEYS_ENABLED
- QWidget *dialog = 0;
- QWidget *p = q;
- while (p && !p->isWindow()) {
- p = p->parentWidget();
- if (dialog = qobject_cast<QDialog *>(p))
- break;
- }
- if (dialog)
- q->setFixedSize(0, 0);
-#endif
}
QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardButton sbutton,
@@ -1196,10 +1184,12 @@ bool QDialogButtonBox::event(QEvent *event)
if (!hasDefault && firstAcceptButton)
firstAcceptButton->setDefault(true);
#ifdef QT_SOFTKEYS_ENABLED
- if (dialog)
+ if (dialog) {
+ setFixedSize(0,0);
dialog->addActions(d->softKeyActions.values());
- else
+ } else {
addActions(d->softKeyActions.values());
+ }
#endif
}else if (event->type() == QEvent::LanguageChange) {
d->retranslateStrings();
diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp
index 5ff323a..3d908a1 100644
--- a/src/gui/widgets/qlabel.cpp
+++ b/src/gui/widgets/qlabel.cpp
@@ -886,7 +886,18 @@ void QLabel::focusInEvent(QFocusEvent *ev)
void QLabel::focusOutEvent(QFocusEvent *ev)
{
Q_D(QLabel);
- d->sendControlEvent(ev);
+ if (d->control) {
+ d->sendControlEvent(ev);
+ QTextCursor cursor = d->control->textCursor();
+ Qt::FocusReason reason = ev->reason();
+ if (reason != Qt::ActiveWindowFocusReason
+ && reason != Qt::PopupFocusReason
+ && cursor.hasSelection()) {
+ cursor.clearSelection();
+ d->control->setTextCursor(cursor);
+ }
+ }
+
QFrame::focusOutEvent(ev);
}
@@ -989,8 +1000,10 @@ void QLabel::paintEvent(QPaintEvent *)
d->ensureTextLayouted();
QAbstractTextDocumentLayout::PaintContext context;
-
- if (!isEnabled() && style->styleHint(QStyle::SH_EtchDisabledText, &opt, this)) {
+ if (!isEnabled() && !d->control &&
+ // We cannot support etched for rich text controls because custom
+ // colors and links will override the light palette
+ style->styleHint(QStyle::SH_EtchDisabledText, &opt, this)) {
context.palette = opt.palette;
context.palette.setColor(QPalette::Text, context.palette.light().color());
painter.save();
diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
index 0947e1b..501e62f 100644
--- a/src/gui/widgets/qmainwindow.cpp
+++ b/src/gui/widgets/qmainwindow.cpp
@@ -119,7 +119,7 @@ void QMainWindowPrivate::init()
q->setAttribute(Qt::WA_Hover);
#ifdef QT_SOFTKEYS_ENABLED
menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, q);
- menuBarAction->setObjectName("_q_menuSoftKeyAction");
+ menuBarAction->setObjectName(QLatin1String("_q_menuSoftKeyAction"));
#endif
}
@@ -933,7 +933,7 @@ static bool checkDockWidgetArea(Qt::DockWidgetArea area, const char *where)
}
#ifndef QT_NO_TABBAR
-/*!
+/*!
\property QMainWindow::documentMode
\brief whether the tab bar for tabbed dockwidgets is set to document mode.
\since 4.5
@@ -954,7 +954,7 @@ void QMainWindow::setDocumentMode(bool enabled)
#endif // QT_NO_TABBAR
#ifndef QT_NO_TABWIDGET
-/*!
+/*!
\property QMainWindow::tabShape
\brief the tab shape used for tabbed dock widgets.
\since 4.5
diff --git a/src/gui/widgets/qmenu.h b/src/gui/widgets/qmenu.h
index 3d41727..0346a55 100644
--- a/src/gui/widgets/qmenu.h
+++ b/src/gui/widgets/qmenu.h
@@ -52,19 +52,11 @@
#endif
QT_BEGIN_HEADER
-#ifdef Q_WS_S60
- class CEikMenuPane;
-#endif
QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
-#ifdef Q_WS_S60
-void qt_symbian_show_toplevel(CEikMenuPane* menuPane);
-void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id);
-#endif // Q_WS_S60
-
#ifndef QT_NO_MENU
class QMenuPrivate;
diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h
index 2d5632e..9c4f260 100644
--- a/src/gui/widgets/qmenu_p.h
+++ b/src/gui/widgets/qmenu_p.h
@@ -63,11 +63,18 @@
#ifdef Q_WS_S60
class CEikMenuPane;
+#define QT_SYMBIAN_FIRST_MENU_ITEM 32000
+#define QT_SYMBIAN_LAST_MENU_ITEM 41999 // 10000 items ought to be enough for anybody...
#endif
QT_BEGIN_NAMESPACE
#ifndef QT_NO_MENU
+#ifdef Q_WS_S60
+void qt_symbian_show_toplevel(CEikMenuPane* menuPane);
+void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id);
+#endif // Q_WS_S60
+
class QTornOffMenu;
class QEventLoop;
diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp
index 6fc4371..d757f98 100644
--- a/src/gui/widgets/qmenu_symbian.cpp
+++ b/src/gui/widgets/qmenu_symbian.cpp
@@ -66,8 +66,6 @@ QT_BEGIN_NAMESPACE
typedef QMultiHash<QWidget *, QMenuBarPrivate *> MenuBarHash;
Q_GLOBAL_STATIC(MenuBarHash, menubars)
-#define QT_FIRST_MENU_ITEM 32000
-
struct SymbianMenuItem
{
int id;
@@ -76,12 +74,13 @@ struct SymbianMenuItem
QAction* action;
};
+Q_GLOBAL_STATIC_WITH_ARGS(QAction, contextAction, (0))
+
static QList<SymbianMenuItem*> symbianMenus;
static QList<QMenuBar*> nativeMenuBars;
-static uint qt_symbian_menu_static_cmd_id = QT_FIRST_MENU_ITEM;
+static uint qt_symbian_menu_static_cmd_id = QT_SYMBIAN_FIRST_MENU_ITEM;
static QPointer<QWidget> widgetWithContextMenu;
static QList<QAction*> contextMenuActionList;
-static QAction contextAction(0);
static int contexMenuCommand=0;
bool menuExists()
@@ -145,6 +144,9 @@ static void qt_symbian_insert_action(QSymbianMenuAction* action, QList<SymbianMe
if (action->action->isSeparator())
return;
+ Q_ASSERT_X(action->command <= QT_SYMBIAN_LAST_MENU_ITEM, "qt_symbian_insert_action",
+ "Too many menu actions");
+
const int underlineShortCut = QApplication::style()->styleHint(QStyle::SH_UnderlineShortcut);
QString iconText = action->action->iconText();
TPtrC menuItemText = qt_QString2TPtrC( underlineShortCut ? action->action->text() : iconText);
@@ -213,7 +215,7 @@ static void rebuildMenu()
if (w) {
mb = menubars()->value(w);
- qt_symbian_menu_static_cmd_id = QT_FIRST_MENU_ITEM;
+ qt_symbian_menu_static_cmd_id = QT_SYMBIAN_FIRST_MENU_ITEM;
deleteAll( &symbianMenus );
if (!mb)
return;
@@ -250,12 +252,12 @@ void QMenuBarPrivate::symbianCommands(int command)
int size = nativeMenuBars.size();
for (int i = 0; i < nativeMenuBars.size(); ++i) {
- SymbianMenuItem* menu = qt_symbian_find_menu_item(command, symbianMenus);
- if (!menu)
+ SymbianMenuItem* menu = qt_symbian_find_menu_item(command, symbianMenus);
+ if (!menu)
continue;
emit nativeMenuBars.at(i)->triggered(menu->action);
- menu->action->activate(QAction::Trigger);
+ menu->action->activate(QAction::Trigger);
break;
}
}
@@ -289,6 +291,7 @@ QMenuBarPrivate::QSymbianMenuBarPrivate::QSymbianMenuBarPrivate(QMenuBarPrivate
QMenuBarPrivate::QSymbianMenuBarPrivate::~QSymbianMenuBarPrivate()
{
+ qt_symbian_menu_static_cmd_id = QT_SYMBIAN_FIRST_MENU_ITEM;
deleteAll( &symbianMenus );
symbianMenus.clear();
d = 0;
@@ -390,16 +393,16 @@ void QMenuBarPrivate::QSymbianMenuBarPrivate::insertNativeMenuItems(const QList<
void QMenuBarPrivate::QSymbianMenuBarPrivate::rebuild()
{
contexMenuCommand = 0;
- qt_symbian_menu_static_cmd_id = QT_FIRST_MENU_ITEM;
+ qt_symbian_menu_static_cmd_id = QT_SYMBIAN_FIRST_MENU_ITEM;
deleteAll( &symbianMenus );
if (d)
insertNativeMenuItems(d->actions);
contextMenuActionList.clear();
if (widgetWithContextMenu) {
- contexMenuCommand = qt_symbian_menu_static_cmd_id;
- contextAction.setText(QMenuBar::tr("Actions"));
- contextMenuActionList.append(&contextAction);
+ contexMenuCommand = qt_symbian_menu_static_cmd_id; // Increased inside insertNativeMenuItems
+ contextAction()->setText(QMenuBar::tr("Actions"));
+ contextMenuActionList.append(contextAction());
insertNativeMenuItems(contextMenuActionList);
}
}
diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp
index d519bfe..22438bf 100644
--- a/src/gui/widgets/qplaintextedit.cpp
+++ b/src/gui/widgets/qplaintextedit.cpp
@@ -65,11 +65,6 @@
#include <limits.h>
#include <qtexttable.h>
#include <qvariant.h>
-
-#ifdef Q_WS_WIN
-#include <qstandardgestures.h>
-#endif
-
#include <qinputcontext.h>
#ifndef QT_NO_TEXTEDIT
@@ -519,6 +514,9 @@ QTextBlock QPlainTextEditControl::firstVisibleBlock() const
int QPlainTextEditControl::hitTest(const QPointF &point, Qt::HitTestAccuracy ) const {
int currentBlockNumber = topBlock;
QTextBlock currentBlock = document()->findBlockByNumber(currentBlockNumber);
+ if (!currentBlock.isValid())
+ return -1;
+
QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document()->documentLayout());
Q_ASSERT(documentLayout);
@@ -1578,7 +1576,35 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e)
}
#endif
- if (!(d->control->textInteractionFlags() & Qt::TextEditable)) {
+#ifndef QT_NO_SHORTCUT
+
+ Qt::TextInteractionFlags tif = d->control->textInteractionFlags();
+
+ if (tif & Qt::TextSelectableByKeyboard){
+ if (e == QKeySequence::SelectPreviousPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
+ return;
+ } else if (e ==QKeySequence::SelectNextPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
+ return;
+ }
+ }
+ if (tif & (Qt::TextSelectableByKeyboard | Qt::TextEditable)) {
+ if (e == QKeySequence::MoveToPreviousPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
+ return;
+ } else if (e == QKeySequence::MoveToNextPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
+ return;
+ }
+ }
+#endif // QT_NO_SHORTCUT
+
+ if (!(tif & Qt::TextEditable)) {
switch (e->key()) {
case Qt::Key_Space:
e->accept();
@@ -1605,27 +1631,6 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e)
return;
}
-#ifndef QT_NO_SHORTCUT
- if (e == QKeySequence::MoveToPreviousPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
- return;
- } else if (e == QKeySequence::MoveToNextPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
- return;
- } else if (e == QKeySequence::SelectPreviousPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
- return;
- } else if (e ==QKeySequence::SelectNextPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
- return;
- }
-#endif // QT_NO_SHORTCUT
-
-
d->sendControlEvent(e);
#ifdef QT_KEYPAD_NAVIGATION
if (!e->isAccepted()) {
@@ -2927,33 +2932,29 @@ QAbstractTextDocumentLayout::PaintContext QPlainTextEdit::getPaintContext() cons
(\a available is true) or unavailable (\a available is false).
*/
-#ifdef Q_WS_WIN
-
-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);
- }
-}
-
-#endif
+//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
diff --git a/src/gui/widgets/qplaintextedit.h b/src/gui/widgets/qplaintextedit.h
index 1d6881b..60aed1d 100644
--- a/src/gui/widgets/qplaintextedit.h
+++ b/src/gui/widgets/qplaintextedit.h
@@ -270,10 +270,6 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_verticalScrollbarActionTriggered(int))
Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged())
-#ifdef Q_WS_WIN
- Q_PRIVATE_SLOT(d_func(), void _q_gestureTriggered())
-#endif
-
friend class QPlainTextEditControl;
};
diff --git a/src/gui/widgets/qplaintextedit_p.h b/src/gui/widgets/qplaintextedit_p.h
index 5fe6f4d..7adf403 100644
--- a/src/gui/widgets/qplaintextedit_p.h
+++ b/src/gui/widgets/qplaintextedit_p.h
@@ -72,7 +72,6 @@ class QMimeData;
class QPlainTextEdit;
class ExtraArea;
-class QPanGesture;
class QPlainTextEditControl : public QTextControl
{
@@ -179,10 +178,6 @@ public:
void _q_modificationChanged(bool);
int originalOffsetY;
-
-#ifdef Q_WS_WIN
- void _q_gestureTriggered();
-#endif
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp
index dc78fd5..b894aa8 100644
--- a/src/gui/widgets/qtextedit.cpp
+++ b/src/gui/widgets/qtextedit.cpp
@@ -1220,8 +1220,35 @@ void QTextEdit::keyPressEvent(QKeyEvent *e)
break;
}
#endif
+#ifndef QT_NO_SHORTCUT
- if (!(d->control->textInteractionFlags() & Qt::TextEditable)) {
+ Qt::TextInteractionFlags tif = d->control->textInteractionFlags();
+
+ if (tif & Qt::TextSelectableByKeyboard){
+ if (e == QKeySequence::SelectPreviousPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
+ return;
+ } else if (e ==QKeySequence::SelectNextPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
+ return;
+ }
+ }
+ if (tif & (Qt::TextSelectableByKeyboard | Qt::TextEditable)) {
+ if (e == QKeySequence::MoveToPreviousPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
+ return;
+ } else if (e == QKeySequence::MoveToNextPage) {
+ e->accept();
+ d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
+ return;
+ }
+ }
+#endif // QT_NO_SHORTCUT
+
+ if (!(tif & Qt::TextEditable)) {
switch (e->key()) {
case Qt::Key_Space:
e->accept();
@@ -1248,26 +1275,6 @@ void QTextEdit::keyPressEvent(QKeyEvent *e)
return;
}
-#ifndef QT_NO_SHORTCUT
- if (e == QKeySequence::MoveToPreviousPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Up, QTextCursor::MoveAnchor);
- return;
- } else if (e == QKeySequence::MoveToNextPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Down, QTextCursor::MoveAnchor);
- return;
- } else if (e == QKeySequence::SelectPreviousPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Up, QTextCursor::KeepAnchor);
- return;
- } else if (e ==QKeySequence::SelectNextPage) {
- e->accept();
- d->pageUpDown(QTextCursor::Down, QTextCursor::KeepAnchor);
- return;
- }
-#endif // QT_NO_SHORTCUT
-
{
QTextCursor cursor = d->control->textCursor();
const QString text = e->text();
diff --git a/src/gui/widgets/qtoolbarextension_p.h b/src/gui/widgets/qtoolbarextension_p.h
index 5d622ec..5fe74a9 100644
--- a/src/gui/widgets/qtoolbarextension_p.h
+++ b/src/gui/widgets/qtoolbarextension_p.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_TOOLBUTTON
-class QToolBarExtension : public QToolButton
+class Q_AUTOTEST_EXPORT QToolBarExtension : public QToolButton
{
Q_OBJECT
Qt::Orientation orientation;