summaryrefslogtreecommitdiffstats
path: root/dist/changes-3.1.0
blob: 4e5876d20f2df63f5b537ab2afceda0d7c2f0bdd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
Qt 3.1 introduces many significant new features and many improvements
over the 3.0.x series. This file provides an overview of the main
changes since version 3.0.x. For further details see the online
documentation which is included in this distribution, and also
available at http://qt.nokia.com/doc/.

The Qt version 3.1 series is binary compatible with the 3.0.x series:
applications compiled for 3.0 will continue to run with 3.1.


****************************************************************************
*                                 General                                  *
****************************************************************************

Qt Script for Applications
--------------------------
Qt 3.1 is the first Qt release that can be used with Qt Script for
Applications (QSA). QSA provides a scripting engine, an IDE for
creating and editing scripts and script forms, and bindings to the Qt
API. Script-enabling a Qt application is not difficult and the IDE
makes it easy for resellers and end-users to write their own scripts.
QSA is due for release after Qt 3.1.


Qt Designer
-----------
Qt Designer, the visual GUI builder, has undergone several usability
improvements. A new dialog for creating and editing signals and slots
connections has been created: it is much easier to use and much faster
for setting up multiple connections. The widgets are now presented in
an easy-to-use toolbox rather than in toolbars (although you can still
have the toolbars if you want). The property editor now handles common
properties in multiple widgets simultaneously. By popular demand,
WYSIWYG support for QWidgetStack has been added. Rich text is now
supported with a rich text editor. And the code editor can be used for
ordinary member functions as well as for slots.


Qt Assistant
------------
Qt Assistant, the Qt documentation browser, can now be used with
custom documentation sets. This new functionality combined with the
new QAssistantClient class means that you can use Qt Assistant as a
help browser for your own applications. Qt Assistant has also been
enhanced by the addition of a fast full text search engine.


Motif
-----
The general industry-wide move away from Motif is leaving more and
more companies in need of a migration solution. But converting large
legacy applications in one step is often impractical. To minimize
risks and to manage the workload companies often want to port code on
a module by module basis. Qt 3.1 includeds a completely new Motif
module that supports hybrid applications in which Qt code and Motif
code coexist. (This obsoletes the earlier rudimentary Qt Xt/Motif
extension.)


ActiveX
-------
With the release of Qt 3.1, customers who use Qt for Microsoft Windows
development can now use Qt with ActiveX. The new ActiveQt module
provides a simple API for COM and ActiveX. The module can be used to
create applications which host ActiveX controls, and also to create
applications that serve ActiveX controls (e.g. Internet Explorer
plugins).


Qt/Mac
------
The introduction of Qt/Mac, a Mac OS X port of Qt, with Qt 3.0 has
proved a great success. This port has undergone many improvements in
Qt 3.1, especially with respect to Appearance Manager, anti-aliased
text and user settings. The Qt OpenGL support is greatly improved, and
uses the hardware-accelerated drivers.


Qt/Embedded
-----------
Graphics, mouse and keyboard drivers can now be compiled as plugins.


Qt library
----------
In addition to the new additions and enhancements referred to above,
as with all major Qt releases, Qt 3.1 includes hundreds of
improvements in the existing class library. Here is a brief summary of
the most significant changes:

- QTextEdit has a new text format: LogText. This is a performance and
  memory optimized format especially designed for the fast display of
  large amounts of text. The format supports basic highlighting,
  including bold and colored text.

- The new QSyntaxHighlighter class makes it both easy and efficient to
  add syntax highlighting capabilities to a QTextEdit.

- QHttp and QFtp in earlier Qt's were implementations of the
  QNetworkProtocol. Both have been extended to stand in their own
  right. If you missed some flexibility in the network protocol
  abstractions of earlier Qt's, the new QHttp and QFtp classes should
  provide the solution.

- QAccel, used to handle keyboard shortcuts, now gracefully copes with
  shortcut clashes. If a clash occurs, a new signal,
  activatedAmbiguously(), is emitted. Classes that use QAccel, like
  QButton's subclasses and QPopupMenu, make use of this new
  functionality. Futhermore QAccel can now handle multi-key sequences,
  for example, Ctrl+X,Ctrl+F.

- QClipboard has been extended to simplify data exchange between
  programs.

- Thread support: almost all methods in the tools classes have been
  made reentrant. QApplication::postEvent() and a few other methods
  are now thread-safe if Qt is compiled as a multi-threaded library.
  (The documentation now states if a class or function is thread-safe
  or reentrant.)

- A QMutexLocker class has been added to simplify the locking and
  unlocking of mutexes.

- Input methods: A selectionLength() function has been added to
  QIMEvent. Japanese compositions are now handled correctly. Support
  for AIMM based input methods (those working on non-Asian versions of
  Win95/98/Me) has been added.

- Large File support: Qt's internals have been modified to support
  Large Files (> 2GB). QFileDialog will now correctly display and
  select large files.

- SQL module: Support for prepared query execution and value binding
  has been added. Among other benefits, this makes it possible to
  write large BLOBs (> 2 KB) to Oracle databases, and to write Unicode
  strings to SQL Server databases.

- Support for XIM on Solaris.

Build process
-------------
The build process has been improved:

- The configure script does not need QTDIR to be set anymore.

- Improved support for building Qt on MSVC.NET.


****************************************************************************
*			   Library					   *
****************************************************************************

- QAccel:
	Corrected illegal accelerator state when using multiple
	keysequences. (Resulted in no accelerator being triggered when
	there's a partial match). Only triggers on enabled
	accelerators and their enabled items. Eats all keys in a
	keysequence, not just the first and last.

- QCString:
	Speed-optimized replace().

- QDataStream:
	Applies to printable data streams only: If the version number
	of the device is less than 4, use the same streaming format
	that was used in Qt 2.3 and earlier.

- QDataTable:
	Respect read-only columns. Make it possible to swap columns.

- QDockWindow:
	Added a standard widget constructor (taking a QWidget *parent,
	const char *name and WFlags). Improved docking behavior.

- QFileDialog:
	Windows only: make Qt's filedialog work properly with network
	paths.

- QFontMetrics:
	Windows only: Fixed QFontMetrics::boundingRect( QChar c ) to
	work for non-TrueType fonts.

- QHeader:
	Optimized the sectionSizeHint() calculation, which in turn 
	speeds up all QHeader size/label calculations.

- QIconFactory:
	Avoid infinite loops when recursively calling
	QPixmap::pixmap().

- QIconView:
	Fixed navigation and selection with arrow keys. Some speedups
	when repainting.

- QKeySequence:
	Treat Unicode characters in string defined sequences
	correctly. So, now letters like Æ, Ø and Å should work as
	accelerators, even through translation files.

- QLayout:
	alignmentRect() respects the layout's maximum size.

- QLineEdit:
	Added a lostFocus() signal. Double-clicking only uses spaces
	as word bounderies for the selection now, not dots, commas,
	etc. Support double-click+mousemove selection.

- QListBox:
	Fixed the item which is passed into the contextMenuRequested()
	signal (this was sometimes wrong). Don't select items that are
	not selectable.

- QListView:
	Shift selection in Extended mode now follows Windows
	Shift-selection standard. Erase empty area when drawing
	listviews without columns. Only drops on drop-enabled items
	that accept drops.

- QListViewItem:
	Optimized size claculation for multi-line items.

- QMainWindow:
	Base the minimumSizeHint() on the sizeHint()s of the left hand
	dock area (instead of the minimumSize()).

- QMenuBar:
	Fixed broken Alt release detection. Fixed flickering. Fixed
	empty menubars resizing properly.

- QObject:
	Fixed return value of disconnect(). Fixed disconnect()ing
	SIGNALs from SIGNALs and disconnect()ing multiple SLOTs with
	the same name from a SIGNAL.

- QProcess:
	Unix only: Don't eat the file descriptors if a lot of
	processes (with short runtimes) are started immediately after
	each other.

- QPSQLDriver:
	Make the driver compile with the standard PostgreSQL source
	distribution under Windows. Better handling of network,
	datetime and geometrical datatypes.

- QRegion:
	Fixed setRects() to calculate the bounding rectangle
	correctly.

- QScrollView:
	Doesn't reposition the view when the user is scrolling the
	view.

- QSpinBox:
	Fixed setValue() so that any not-yet-interpreted input is
	ignored when setting a new value.

- QString:
	Support QTextCodec::codecForCStrings(). Support
	std::string<==>QString conversion when STL support is on.

- QSyntaxHighlighter:
	Added function rehighlight(). Improved internals to be more
	efficient (less calls to highlightParagraph() necessary).

- QTable:
	Fixed Tab/BackTab handling to always work. Fixed
	setColumnLabels() and setRowLabels().

- QTableItem (and subclasses):
	Now supports global struts. (See QApplication::globalStrut().)

- QTDSDriver:
	Added support for binary datatypes.

- QTextCodec:
	Added QTextCodec::codecForCStrings and QTextCodec::codecForTr.

- QTextEdit:
	Fixed a painting error which resulted in areas of the textedit
	not being erased correctly. Make sure repainting is done after
	changing the underline-links setting. Renamed 'allowTabs'
	property to 'tabChangesFocus' (inverted value). Added a new
	property 'autoFormatting'. When exporting HTML also quote
	quotes. Fixed a background erasing bug which messed up the
	view.

- QUrl:
	Recognize Windows drive letters not only in the form of "c:/"
	but also in the form "c:" (without the '/').

- QWidget:
	Fixed some visibility issues.

****************************************************************************
*			   Qt Designer					   *
****************************************************************************

- Now displays the classname of "gray box" custom widgets in the gray
  box on the form.

- Accept tildes (~) in the project settings.

- A new command line tool conv2ui (in qt/tools/designer/tools) has
  been added, to convert dialog description files from different file
  formats to .ui files without the need to invoke Qt Designer. This
  tool uses the same plugins as Qt Designer for loading other dialog
  description files.

- An import filter for .kdevdlg files has been added.

- Actions in the action editor are now sortable.

- Improved usability of more dialogs (in-place renaming, drag'n'drop,
  etc.)

- Preserve creation order of forward declarations, variables, etc.

- Save comments for actions.

- uic: Fixed generating code for QStringList properties.

****************************************************************************
*			   Qt Assistant					   *
****************************************************************************

- Fixed some accelerator conflicts.

****************************************************************************
*			   Qt Linguist					   *
****************************************************************************

- Handle trailing backslash in strings correctly in lupdate.

******************************** END ***************************************
etween you and Nokia. +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser diff --git a/src/gui/embedded/qscreenqnx_qws.h b/src/gui/embedded/qscreenqnx_qws.h index 837c061..30312fe 100644 --- a/src/gui/embedded/qscreenqnx_qws.h +++ b/src/gui/embedded/qscreenqnx_qws.h @@ -6,11 +6,11 @@ ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -- cgit v0.12 From 4f7170d9d731234c65008b690a95a0e86d397db5 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Tue, 4 Aug 2009 08:15:21 +0200 Subject: Make Cocoa builds 64-bit by default on snow leopard. --- configure | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/configure b/configure index 2f2e284..095d040 100755 --- a/configure +++ b/configure @@ -5707,17 +5707,23 @@ if [ "$CFG_MAC_DWARF2" = "yes" ]; then QT_CONFIG="$QT_CONFIG dwarf2" fi -# Set the default arch. Select 32-bit/carbon if nothing else has -# been specified on the configure line. +# Set the default arch. +# Carbon builds: 32 bit x86/ppc. +# For "-cocoa" builds on snow leopard : compiler default (64-bit). +# For "-cocoa" builds on leopard : compiler default (32-bit). if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_MAC_ARCHS" == "" ]; then source "$mactests/defaultarch.test" "$TEST_COMPILER" "$OPT_VERBOSE" "$mactests" - if [ "$QT_MAC_DEFAULT_ARCH" == "x86_64" ]; then - CFG_MAC_ARCHS=" x86" - elif [ "$QT_MAC_DEFAULT_ARCH" == "ppc64" ]; then - CFG_MAC_ARCHS=" ppc" - else - CFG_MAC_ARCHS=" $QT_MAC_DEFAULT_ARCH" + if [ "$CFG_MAC_COCOA" != "yes" ]; then + if [ "$QT_MAC_DEFAULT_ARCH" == "x86_64" ]; then + CFG_MAC_ARCHS=" x86" + elif [ "$QT_MAC_DEFAULT_ARCH" == "ppc64" ]; then + CFG_MAC_ARCHS=" ppc" + else + CFG_MAC_ARCHS=" $QT_MAC_DEFAULT_ARCH" + fi + else + CFG_MAC_ARCHS=" $QT_MAC_DEFAULT_ARCH" fi [ "$OPT_VERBOSE" == "yes" ] && echo "Setting Mac architechture to$CFG_MAC_ARCHS." -- cgit v0.12 From 83a82f900aa63a350b66d90ed55f63ee77f20250 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Tue, 4 Aug 2009 09:31:56 +0200 Subject: Build on snow leopard. Don't error out when building qmake, just let it build a 64-bit binary (even for carbon) RebBy: Richard Moe Gustavsen --- src/corelib/global/qglobal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 8263bae..c266ca0 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -279,7 +279,7 @@ namespace QT_NAMESPACE {} # endif #endif -#if defined(Q_OS_MAC64) && !defined(QT_MAC_USE_COCOA) +#if defined(Q_OS_MAC64) && !defined(QT_MAC_USE_COCOA) && !defined(QT_BUILD_QMAKE) #error "You are building a 64-bit application, but using a 32-bit version of Qt. Check your build configuration." #endif -- cgit v0.12 From 1f0ea657d33b6851c1f3cb4becd77c63d4b720d8 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Tue, 4 Aug 2009 09:47:05 +0200 Subject: Remove the "preliminary support" warning for 10.6 Also make the "usupported on > 10.6" error a warning. No need to stop the build, the warning will be printed enough times. --- src/corelib/global/qglobal.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index c266ca0..18d5a9f 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -311,11 +311,8 @@ namespace QT_NAMESPACE {} # if !defined(MAC_OS_X_VERSION_10_6) # define MAC_OS_X_VERSION_10_6 MAC_OS_X_VERSION_10_5 + 1 # endif -# if (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_6) -# warning "Support for this version of Mac OS X is still preliminary" -# endif # if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6) -# error "This version of Mac OS X is unsupported" +# warning "This version of Mac OS X is unsupported" # endif #endif -- cgit v0.12 From c96ed4426db7ae3287ee88b0ac7ffd2bd5070310 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 4 Aug 2009 09:43:14 +0200 Subject: Add support for pan gesture on mac (carbon and cocoa) --- src/gui/kernel/qstandardgestures.cpp | 64 ++++++++++++++++++++++++++++++++++++ src/gui/kernel/qstandardgestures_p.h | 6 ++++ 2 files changed, 70 insertions(+) diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index c8b11c5..1a88429 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -73,11 +73,17 @@ QPanGesture::QPanGesture(QWidget *parent) qAppPriv->widgetGestures[parent].pan = this; } #endif + +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + d_func()->panFinishedTimer = 0; +#endif } /*! \internal */ bool QPanGesture::event(QEvent *event) { + Q_D(QPanGesture); + #ifdef Q_WS_WIN QApplicationPrivate* getQApplicationPrivateInternal(); switch (event->type()) { @@ -93,6 +99,21 @@ bool QPanGesture::event(QEvent *event) break; } #endif + +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + if (event->type() == QEvent::Timer) { + const QTimerEvent *te = static_cast(event); + if (te->timerId() == d->panFinishedTimer) { + killTimer(d->panFinishedTimer); + d->panFinishedTimer = 0; + d->lastOffset = QSize(0, 0); + setState(Qt::GestureFinished); + emit triggered(); + setState(Qt::NoGesture); + } + } +#endif + return QObject::event(event); } @@ -133,6 +154,36 @@ bool QPanGesture::filterEvent(QEvent *event) emit triggered(); } } +#ifdef Q_OS_MAC + else if (event->type() == QEvent::Wheel) { + // On Mac, there is really no native panning gesture. Instead, a two + // finger pan is delivered as mouse wheel events. Otoh, on Windows, you + // either get mouse wheel events or pan events. We have decided to make this + // the Qt behaviour as well, meaning that on Mac, wheel + // events will be masked away when listening for pan events. +#ifndef QT_MAC_USE_COCOA + // In Carbon we receive neither touch-, nor pan gesture events. + // So we create pan gestures by converting wheel events. After all, this + // is how things are supposed to work on mac in the first place. + const QWheelEvent *wev = static_cast(event); + int offset = wev->delta() / -120; + d->lastOffset = wev->orientation() == Qt::Horizontal ? QSize(offset, 0) : QSize(0, offset); + + if (state() == Qt::NoGesture) { + setState(Qt::GestureStarted); + d->totalOffset = d->lastOffset; + } else { + setState(Qt::GestureUpdated); + d->totalOffset += d->lastOffset; + } + + killTimer(d->panFinishedTimer); + d->panFinishedTimer = startTimer(200); + emit triggered(); +#endif + return true; + } +#endif return false; } @@ -150,8 +201,13 @@ void QPanGesture::reset() */ QSize QPanGesture::totalOffset() const { +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + Q_D(const QPanGesture); + return d->totalOffset; +#else QPoint pt = pos() - startPos(); return QSize(pt.x(), pt.y()); +#endif } /*! @@ -162,8 +218,13 @@ QSize QPanGesture::totalOffset() const */ QSize QPanGesture::lastOffset() const { +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + Q_D(const QPanGesture); + return d->lastOffset; +#else QPoint pt = pos() - lastPos(); return QSize(pt.x(), pt.y()); +#endif } /*! @@ -252,3 +313,6 @@ void QTapAndHoldGesture::reset() } QT_END_NAMESPACE + +#include "moc_qstandardgestures.cpp" + diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index bb11c9f..0fd42bd 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -70,6 +70,12 @@ public: QPanGesturePrivate() { } QList touchPoints; + QSize totalOffset; + QSize lastOffset; + +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + int panFinishedTimer; +#endif }; class QTapAndHoldGesturePrivate : public QGesturePrivate -- cgit v0.12 From d2e03cc83b5dabc5fd1986a8b8119ff8f0d76179 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 4 Aug 2009 09:45:47 +0200 Subject: Modify imagewidget example so it works with new API --- examples/gestures/imageviewer/imagewidget.cpp | 46 +++++++++------------------ 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/examples/gestures/imageviewer/imagewidget.cpp b/examples/gestures/imageviewer/imagewidget.cpp index 717bb09..0b39997 100644 --- a/examples/gestures/imageviewer/imagewidget.cpp +++ b/examples/gestures/imageviewer/imagewidget.cpp @@ -100,7 +100,7 @@ void ImageWidget::paintEvent(QPaintEvent*) p.setPen(QPen(Qt::gray, 2)); p.drawEllipse(touchFeedback.position, 5, 5); if (touchFeedback.doubleTapped) { - p.setPen(QPen(Qt::gray, 2, Qt::DotLine)); + p.setPen(QPen(Qt::darkGray, 2, Qt::DotLine)); p.drawEllipse(touchFeedback.position, 15, 15); } else if (touchFeedback.tapAndHoldState != 0) { QPoint pts[8] = { @@ -159,51 +159,35 @@ void ImageWidget::gestureTriggered() touchFeedback.tapped = false; touchFeedback.doubleTapped = false; - QGesture *g = qobject_cast(sender()); if (sender() == panGesture) { + QPanGesture *pg = qobject_cast(sender()); if (zoomedIn) { - // usual panning #ifndef QT_NO_CURSOR - if (g->state() == Qt::GestureStarted) - setCursor(Qt::SizeAllCursor); - else - setCursor(Qt::ArrowCursor); + switch (pg->state()) { + case Qt::GestureStarted: + case Qt::GestureUpdated: + setCursor(Qt::SizeAllCursor); + break; + default: + setCursor(Qt::ArrowCursor); + } #endif - const int dx = g->pos().x() - g->lastPos().x(); - const int dy = g->pos().y() - g->lastPos().y(); - horizontalOffset += dx; - verticalOffset += dy; + horizontalOffset += pg->lastOffset().width(); + verticalOffset += pg->lastOffset().height(); update(); } else { // only slide gesture should be accepted - const QPanGesture *pg = static_cast(g); - if (g->state() == Qt::GestureFinished) { + if (pg->state() == Qt::GestureFinished) { touchFeedback.sliding = false; zoomed = rotated = false; - if (pg->totalOffset().width() > 0) { - qDebug() << "slide right"; + if (pg->totalOffset().width() > 0) goNextImage(); - } else { - qDebug() << "slide left"; + else goPrevImage(); - } updateImage(); } } feedbackFadeOutTimer.start(500, this); - } else if (sender() == tapAndHoldGesture) { - if (g->state() == Qt::GestureFinished) { - qDebug() << "tap and hold detected"; - touchFeedback.reset(); - update(); - - QMenu menu; - menu.addAction("Action 1"); - menu.addAction("Action 2"); - menu.addAction("Action 3"); - menu.exec(mapToGlobal(g->pos())); - } - feedbackFadeOutTimer.start(500, this); } } -- cgit v0.12 From 14f9cbbec204ba146205d12cb06577d41b5f974c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 4 Aug 2009 10:00:01 +0200 Subject: Mac: Remove debug work output --- src/gui/painting/qregion_mac.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/painting/qregion_mac.cpp b/src/gui/painting/qregion_mac.cpp index 9b0e99f..6fe7805 100644 --- a/src/gui/painting/qregion_mac.cpp +++ b/src/gui/painting/qregion_mac.cpp @@ -173,7 +173,6 @@ RgnHandle QRegion::toQDRgnForUpdate_sys() const // detect overflow. Tested for use with HIViewSetNeedsDisplayInRegion // in QWidgetPrivate::update_sys(). enum { HIViewSetNeedsDisplayInRegionOverflow = 10000 }; // empirically determined conservative value - qDebug() << qt_r->x() << qt_r->y() << qt_r->right() << qt_r->bottom(); if (qt_r->right() > HIViewSetNeedsDisplayInRegionOverflow || qt_r->bottom() > HIViewSetNeedsDisplayInRegionOverflow) { qt_mac_dispose_rgn(tmp_rgn); qt_mac_dispose_rgn(rgnHandle); -- cgit v0.12 From d3c96863ec17a69c616bdcb12e6a99a874eba66d Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 3 Aug 2009 16:49:46 +0200 Subject: fix warnings on mingw (gcc4.4) basically reordering members initialization in constructors or fixing singed/unsigned checks. Reviewed-by: Trustme --- src/activeqt/container/qaxbase.cpp | 14 +++++++++----- src/activeqt/container/qaxwidget.cpp | 2 +- src/activeqt/shared/qaxtypes.cpp | 2 +- src/gui/painting/qregion_win.cpp | 4 ++-- src/gui/util/qcompleter.cpp | 2 +- src/opengl/qgl.cpp | 5 +++-- 6 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/activeqt/container/qaxbase.cpp b/src/activeqt/container/qaxbase.cpp index 4fc9926..d602946 100644 --- a/src/activeqt/container/qaxbase.cpp +++ b/src/activeqt/container/qaxbase.cpp @@ -3204,12 +3204,12 @@ static const char qt_meta_stringdata_QAxBase[] = { }; static QMetaObject qaxobject_staticMetaObject = { - &QObject::staticMetaObject, qt_meta_stringdata_QAxBase, - qt_meta_data_QAxBase, 0 + { &QObject::staticMetaObject, qt_meta_stringdata_QAxBase, + qt_meta_data_QAxBase, 0 } }; static QMetaObject qaxwidget_staticMetaObject = { - &QWidget::staticMetaObject, qt_meta_stringdata_QAxBase, - qt_meta_data_QAxBase, 0 + { &QWidget::staticMetaObject, qt_meta_stringdata_QAxBase, + qt_meta_data_QAxBase, 0 } }; /*! @@ -3692,6 +3692,8 @@ int QAxBase::qt_metacall(QMetaObject::Call call, int id, void **v) case QMetaMethod::Slot: id = internalInvoke(call, id, v); break; + default: + break; } break; case QMetaObject::ReadProperty: @@ -3706,6 +3708,8 @@ int QAxBase::qt_metacall(QMetaObject::Call call, int id, void **v) case QMetaObject::QueryPropertyUser: id -= mo->propertyCount(); break; + default: + break; } Q_ASSERT(id < 0); return id; @@ -3905,7 +3909,7 @@ bool QAxBase::dynamicCallHelper(const char *name, void *inout, QList & else paramType = d->metaobj->paramType(normFunction, i, &out); - if (!parse && d->useMetaObject && var.type() == QVariant::String || var.type() == QVariant::ByteArray) { + if ((!parse && d->useMetaObject && var.type() == QVariant::String) || var.type() == QVariant::ByteArray) { int enumIndex =mo->indexOfEnumerator(paramType); if (enumIndex != -1) { QMetaEnum metaEnum =mo->enumerator(enumIndex); diff --git a/src/activeqt/container/qaxwidget.cpp b/src/activeqt/container/qaxwidget.cpp index ff6bcb8..e4c9d42 100644 --- a/src/activeqt/container/qaxwidget.cpp +++ b/src/activeqt/container/qaxwidget.cpp @@ -531,7 +531,7 @@ bool axc_FilterProc(void *m) } QAxClientSite::QAxClientSite(QAxWidget *c) -: ref(1), widget(c), host(0), eventTranslated(true) +: eventTranslated(true), ref(1), widget(c), host(0) { aggregatedObject = widget->createAggregate(); if (aggregatedObject) { diff --git a/src/activeqt/shared/qaxtypes.cpp b/src/activeqt/shared/qaxtypes.cpp index 49aa99c..63891c4 100644 --- a/src/activeqt/shared/qaxtypes.cpp +++ b/src/activeqt/shared/qaxtypes.cpp @@ -552,7 +552,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type int maxColumns = col.count(); if (maxColumns) { is2D = true; - SAFEARRAYBOUND rgsabound[2] = {0}; + SAFEARRAYBOUND rgsabound[2] = { {0} }; rgsabound[0].cElements = count; rgsabound[1].cElements = maxColumns; array = SafeArrayCreate(VT_VARIANT, 2, rgsabound); diff --git a/src/gui/painting/qregion_win.cpp b/src/gui/painting/qregion_win.cpp index 2d5e76b..8708461 100644 --- a/src/gui/painting/qregion_win.cpp +++ b/src/gui/painting/qregion_win.cpp @@ -57,7 +57,7 @@ HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, { const int tries = 10; for (int i = 0; i < tries; ++i) { - HRGN region; + HRGN region = 0; switch (type) { case QRegion::Rectangle: region = CreateRectRgn(left, top, right, bottom); @@ -96,7 +96,7 @@ QRegion qt_region_from_HRGN(HRGN rgn) QRegion region; RECT *r = reinterpret_cast(rd->Buffer); - for (int i = 0; i < rd->rdh.nCount; ++i) { + for (uint i = 0; i < rd->rdh.nCount; ++i) { QRect rect; rect.setCoords(r->left, r->top, r->right - 1, r->bottom - 1); ++r; diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp index a0a3756..f4dd87c 100644 --- a/src/gui/util/qcompleter.cpp +++ b/src/gui/util/qcompleter.cpp @@ -772,7 +772,7 @@ QMatchData QUnsortedModelEngine::filter(const QString& part, const QModelIndex& /////////////////////////////////////////////////////////////////////////////// QCompleterPrivate::QCompleterPrivate() : widget(0), proxy(0), popup(0), cs(Qt::CaseSensitive), role(Qt::EditRole), column(0), - sorting(QCompleter::UnsortedModel), wrap(true), maxVisibleItems(7), eatFocusOut(true) + maxVisibleItems(7), sorting(QCompleter::UnsortedModel), wrap(true), eatFocusOut(true) { } diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 48d09ce..0631df5 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -4604,7 +4604,7 @@ QGLFormat QGLDrawable::format() const GLuint QGLDrawable::bindTexture(const QImage &image, GLenum target, GLint format) { - QGLTexture *texture; + QGLTexture *texture = 0; if (widget) texture = widget->d_func()->glcx->d_func()->bindTexture(image, target, format, true); else if (buffer) @@ -4620,7 +4620,7 @@ GLuint QGLDrawable::bindTexture(const QImage &image, GLenum target, GLint format GLuint QGLDrawable::bindTexture(const QPixmap &pixmap, GLenum target, GLint format) { - QGLTexture *texture; + QGLTexture *texture = 0; if (widget) texture = widget->d_func()->glcx->d_func()->bindTexture(pixmap, target, format, true, true); else if (buffer) @@ -4718,6 +4718,7 @@ void QGLShareRegister::removeShare(const QGLContext *context) { int count = it.value().removeAll(context); Q_ASSERT(count == 1); + Q_UNUSED(count); Q_ASSERT(it.value().size() != 0); if (it.value().size() == 1) -- cgit v0.12 From 549736341a2268e33159949e076e0629abeb838a Mon Sep 17 00:00:00 2001 From: Leonardo Sobral Cunha Date: Tue, 28 Jul 2009 15:55:28 +0200 Subject: Fixes selectionModel::hasSelection return value after model::reset After resetting the model, the selectionModel::hasSelection() of the view should return false. Fixed the corresponding autotest, which was wrong. Task-number: 256502 Reviewed-by: thierry --- src/gui/itemviews/qabstractitemview.cpp | 1 + tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 8b6b5cb..94569ec 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -960,6 +960,7 @@ void QAbstractItemView::reset() d->currentIndexSet = false; setState(NoState); setRootIndex(QModelIndex()); + d->selectionModel->reset(); } /*! diff --git a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp index ae64e51..0541b46 100644 --- a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -1547,7 +1547,7 @@ void tst_QItemSelectionModel::resetModel() model.reset(); QVERIFY(view.selectionModel()->selection().isEmpty()); - QVERIFY(view.selectionModel()->hasSelection()); + QVERIFY(view.selectionModel()->hasSelection() == false); view.selectionModel()->select(QItemSelection(model.index(0, 0), model.index(5, 5)), QItemSelectionModel::Select); -- cgit v0.12 From baf3ec81ca5d5cd38b54dc853c12109956a98cb9 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 4 Aug 2009 11:16:01 +0200 Subject: QMenu now takes minimum width into account for the action rects The action now try to take advantage of the space given by a minimum width. Patch proposed initially by Aron Seigo and improved later on. Reviewed-by: Trustme --- src/gui/widgets/qmenu.cpp | 11 ++++++----- tests/auto/qmenu/tst_qmenu.cpp | 12 ++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 0b85eec..67bb10a 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -228,6 +228,10 @@ void QMenuPrivate::updateActionRects() const const int hmargin = style->pixelMetric(QStyle::PM_MenuHMargin, 0, q), vmargin = style->pixelMetric(QStyle::PM_MenuVMargin, 0, q), icone = style->pixelMetric(QStyle::PM_SmallIconSize, 0, q); + const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); + + const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, 0, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width(); + const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin)); //for compatability now - will have to refactor this away.. tabWidth = 0; @@ -300,7 +304,7 @@ void QMenuPrivate::updateActionRects() const if (!sz.isEmpty()) { - max_column_width = qMax(max_column_width, sz.width()); + max_column_width = qMax(min_column_width, qMax(max_column_width, sz.width())); //wrapping if (!scroll && y+sz.height()+vmargin > dh - (style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q) * 2)) { @@ -316,7 +320,6 @@ void QMenuPrivate::updateActionRects() const max_column_width += tabWidth; //finally add in the tab width //calculate position - const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); const int base_y = vmargin + fw + topmargin + (scroll ? scroll->scrollOffset : 0) + (tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q) : 0); @@ -1703,9 +1706,7 @@ QSize QMenu::sizeHint() const QSize s; QStyleOption opt(0); - opt.rect = rect(); - opt.palette = palette(); - opt.state = QStyle::State_None; + opt.init(this); for (int i = 0; i < d->actionRects.count(); ++i) { const QRect &rect = d->actionRects.at(i); if (rect.isNull()) diff --git a/tests/auto/qmenu/tst_qmenu.cpp b/tests/auto/qmenu/tst_qmenu.cpp index ec9c7b4..6ba6466 100644 --- a/tests/auto/qmenu/tst_qmenu.cpp +++ b/tests/auto/qmenu/tst_qmenu.cpp @@ -96,6 +96,7 @@ private slots: void task256918_setFont(); void menuSizeHint(); void task258920_mouseBorder(); + void setFixedWidth(); protected slots: void onActivated(QAction*); void onHighlighted(QAction*); @@ -798,6 +799,17 @@ void tst_QMenu::task258920_mouseBorder() QVERIFY(menu.painted); } +void tst_QMenu::setFixedWidth() +{ + QMenu menu; + menu.addAction("action"); + menu.setFixedWidth(300); + //the sizehint should reflect the minimumwidth because the action will try to + //get as much space as possible + QCOMPARE(menu.sizeHint().width(), menu.minimumWidth()); +} + + QTEST_MAIN(tst_QMenu) #include "tst_qmenu.moc" -- cgit v0.12 From 54d5c7eae26c025015f08bf06d0f9268175317e8 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 4 Aug 2009 11:47:45 +0200 Subject: fix warning on MSVC --- src/gui/kernel/qstandardgestures.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index 1a88429..c4820f0 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -82,8 +82,6 @@ QPanGesture::QPanGesture(QWidget *parent) /*! \internal */ bool QPanGesture::event(QEvent *event) { - Q_D(QPanGesture); - #ifdef Q_WS_WIN QApplicationPrivate* getQApplicationPrivateInternal(); switch (event->type()) { @@ -101,6 +99,7 @@ bool QPanGesture::event(QEvent *event) #endif #if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + Q_D(QPanGesture); if (event->type() == QEvent::Timer) { const QTimerEvent *te = static_cast(event); if (te->timerId() == d->panFinishedTimer) { -- cgit v0.12 From dc0088949822f846983c9a2d8f7dca59433ec555 Mon Sep 17 00:00:00 2001 From: ck Date: Tue, 4 Aug 2009 12:52:38 +0200 Subject: Assistant: Added search history. Task-number: 251278 Reviewed-by: kh --- tools/assistant/lib/qhelpsearchquerywidget.cpp | 295 ++++++++++++++++++++----- 1 file changed, 238 insertions(+), 57 deletions(-) diff --git a/tools/assistant/lib/qhelpsearchquerywidget.cpp b/tools/assistant/lib/qhelpsearchquerywidget.cpp index 00444b1..110df4f 100644 --- a/tools/assistant/lib/qhelpsearchquerywidget.cpp +++ b/tools/assistant/lib/qhelpsearchquerywidget.cpp @@ -43,9 +43,12 @@ #include +#include #include #include +#include +#include #include #include #include @@ -60,8 +63,46 @@ class QHelpSearchQueryWidgetPrivate : public QObject Q_OBJECT private: + struct QueryHistory { + explicit QueryHistory() : curQuery(-1) {} + QList > queries; + int curQuery; + }; + + class CompleterModel : public QAbstractListModel + { + public: + explicit CompleterModel(QObject *parent) + : QAbstractListModel(parent) {} + + int rowCount(const QModelIndex &parent = QModelIndex()) const + { + return parent.isValid() ? 0 : termList.size(); + } + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const + { + if (!index.isValid() || index.row() >= termList.count()|| + (role != Qt::EditRole && role != Qt::DisplayRole)) + return QVariant(); + return termList.at(index.row()); + } + + void addTerm(const QString &term) + { + if (!termList.contains(term)) { + termList.append(term); + reset(); + } + } + + private: + QStringList termList; + }; + QHelpSearchQueryWidgetPrivate() - : QObject() + : QObject(), simpleSearch(true), + searchCompleter(new CompleterModel(this), this) { searchButton = 0; advancedSearchWidget = 0; @@ -136,11 +177,102 @@ private: return wordList; } + void saveQuery(const QList &query, QueryHistory &queryHist) + { + // We only add the query to the list if it is different from the last one. + bool insert = false; + if (queryHist.queries.empty()) + insert = true; + else { + const QList &lastQuery = queryHist.queries.last(); + if (lastQuery.size() != query.size()) { + insert = true; + } else { + for (int i = 0; i < query.size(); ++i) { + if (query.at(i).fieldName != lastQuery.at(i).fieldName + || query.at(i).wordList != lastQuery.at(i).wordList) { + insert = true; + break; + } + } + } + } + if (insert) { + queryHist.queries.append(query); + foreach (const QHelpSearchQuery &queryPart, query) { + static_cast(searchCompleter.model())-> + addTerm(queryPart.wordList.join(" ")); + } + } + } + + void nextOrPrevQuery(int maxOrMinIndex, int addend, + QToolButton *thisButton, QToolButton *otherButton) + { + QueryHistory *queryHist; + QList lineEdits; + if (simpleSearch) { + queryHist = &simpleQueries; + lineEdits << defaultQuery; + } else { + queryHist = &complexQueries; + lineEdits << allQuery << atLeastQuery << similarQuery + << withoutQuery << exactQuery; + } + foreach (QLineEdit *lineEdit, lineEdits) + lineEdit->clear(); + + // Otherwise, the respective button would be disabled. + Q_ASSERT(queryHist->curQuery != maxOrMinIndex); + + queryHist->curQuery += addend; + const QList &query = + queryHist->queries.at(queryHist->curQuery); + foreach (const QHelpSearchQuery &queryPart, query) { + QLineEdit *lineEdit; + switch (queryPart.fieldName) { + case QHelpSearchQuery::DEFAULT: + lineEdit = defaultQuery; + break; + case QHelpSearchQuery::ALL: + lineEdit = allQuery; + break; + case QHelpSearchQuery::ATLEAST: + lineEdit = atLeastQuery; + break; + case QHelpSearchQuery::FUZZY: + lineEdit = similarQuery; + break; + case QHelpSearchQuery::WITHOUT: + lineEdit = withoutQuery; + break; + case QHelpSearchQuery::PHRASE: + lineEdit = exactQuery; + break; + default: + Q_ASSERT(0); + } + lineEdit->setText(queryPart.wordList.join(" ")); + } + + if (queryHist->curQuery == maxOrMinIndex) + thisButton->setEnabled(false); + otherButton->setEnabled(true); + } + + void enableOrDisableToolButtons() + { + const QueryHistory &queryHist = + simpleSearch ? simpleQueries : complexQueries; + prevQueryButton->setEnabled(queryHist.curQuery > 0); + nextQueryButton->setEnabled(queryHist.curQuery < + queryHist.queries.size() - 1); + } + private slots: void showHideAdvancedSearch() { - bool hidden = advancedSearchWidget->isHidden(); - if (hidden) { + if (simpleSearch) { advancedSearchWidget->show(); showHideAdvancedSearchButton->setText((QLatin1String("-"))); } else { @@ -148,12 +280,86 @@ private slots: showHideAdvancedSearchButton->setText((QLatin1String("+"))); } - defaultQuery->setEnabled(!hidden); + simpleSearch = !simpleSearch; + defaultQuery->setEnabled(simpleSearch); + enableOrDisableToolButtons(); + } + + void searchRequested() + { + QList queryList; +#if !defined(QT_CLUCENE_SUPPORT) + queryList.append(QHelSearchQuery(QHelpSearchQuery::DEFAULT, + QStringList(defaultQuery->text()))); + +#else + if (defaultQuery->isEnabled()) { + queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT, + buildTermList(escapeString(defaultQuery->text())))); + } else { + const QRegExp exp(QLatin1String("\\s+")); + QStringList lst = similarQuery->text().split(exp, QString::SkipEmptyParts); + if (!lst.isEmpty()) { + QStringList fuzzy; + foreach (const QString term, lst) + fuzzy += buildTermList(escapeString(term)); + queryList.append(QHelpSearchQuery(QHelpSearchQuery::FUZZY, fuzzy)); + } + + lst = withoutQuery->text().split(exp, QString::SkipEmptyParts); + if (!lst.isEmpty()) { + QStringList without; + foreach (const QString term, lst) + without.append(escapeString(term)); + queryList.append(QHelpSearchQuery(QHelpSearchQuery::WITHOUT, without)); + } + + if (!exactQuery->text().isEmpty()) { + QString phrase = exactQuery->text().remove(QLatin1Char('\"')); + phrase = escapeString(phrase.simplified()); + queryList.append(QHelpSearchQuery(QHelpSearchQuery::PHRASE, QStringList(phrase))); + } + + lst = allQuery->text().split(exp, QString::SkipEmptyParts); + if (!lst.isEmpty()) { + QStringList all; + foreach (const QString term, lst) + all.append(escapeString(term)); + queryList.append(QHelpSearchQuery(QHelpSearchQuery::ALL, all)); + } + + lst = atLeastQuery->text().split(exp, QString::SkipEmptyParts); + if (!lst.isEmpty()) { + QStringList atLeast; + foreach (const QString term, lst) + atLeast += buildTermList(escapeString(term)); + queryList.append(QHelpSearchQuery(QHelpSearchQuery::ATLEAST, atLeast)); + } + } +#endif + QueryHistory &queryHist = simpleSearch ? simpleQueries : complexQueries; + saveQuery(queryList, queryHist); + queryHist.curQuery = queryHist.queries.size() - 1; + if (queryHist.curQuery > 0) + prevQueryButton->setEnabled(true); + nextQueryButton->setEnabled(false); + } + + void nextQuery() + { + nextOrPrevQuery((simpleSearch ? simpleQueries : complexQueries).queries.size() - 1, + 1, nextQueryButton, prevQueryButton); + } + + void prevQuery() + { + nextOrPrevQuery(0, -1, prevQueryButton, nextQueryButton); } private: friend class QHelpSearchQueryWidget; + bool simpleSearch; QPushButton *searchButton; QWidget* advancedSearchWidget; QToolButton *showHideAdvancedSearchButton; @@ -163,6 +369,11 @@ private: QLineEdit *withoutQuery; QLineEdit *allQuery; QLineEdit *atLeastQuery; + QToolButton *nextQueryButton; + QToolButton *prevQueryButton; + QueryHistory simpleQueries; + QueryHistory complexQueries; + QCompleter searchCompleter; }; #include "qhelpsearchquerywidget.moc" @@ -199,13 +410,26 @@ QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent) QHBoxLayout* hBoxLayout = new QHBoxLayout(); QLabel *label = new QLabel(tr("Search for:"), this); d->defaultQuery = new QLineEdit(this); + d->defaultQuery->setCompleter(&d->searchCompleter); + d->prevQueryButton = new QToolButton(this); + d->prevQueryButton->setArrowType(Qt::LeftArrow); + d->prevQueryButton->setToolTip(tr("Previous search")); + d->prevQueryButton->setEnabled(false); + d->nextQueryButton = new QToolButton(this); + d->nextQueryButton->setArrowType(Qt::RightArrow); + d->nextQueryButton->setToolTip(tr("Next search")); + d->nextQueryButton->setEnabled(false); d->searchButton = new QPushButton(tr("Search"), this); hBoxLayout->addWidget(label); hBoxLayout->addWidget(d->defaultQuery); + hBoxLayout->addWidget(d->prevQueryButton); + hBoxLayout->addWidget(d->nextQueryButton); hBoxLayout->addWidget(d->searchButton); vLayout->addLayout(hBoxLayout); + connect(d->prevQueryButton, SIGNAL(clicked()), d, SLOT(prevQuery())); + connect(d->nextQueryButton, SIGNAL(clicked()), d, SLOT(nextQuery())); connect(d->searchButton, SIGNAL(clicked()), this, SIGNAL(search())); connect(d->defaultQuery, SIGNAL(returnPressed()), this, SIGNAL(search())); @@ -236,26 +460,31 @@ QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent) label = new QLabel(tr("words similar to:"), this); gLayout->addWidget(label, 0, 0); d->similarQuery = new QLineEdit(this); + d->similarQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->similarQuery, 0, 1); label = new QLabel(tr("without the words:"), this); gLayout->addWidget(label, 1, 0); d->withoutQuery = new QLineEdit(this); + d->withoutQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->withoutQuery, 1, 1); label = new QLabel(tr("with exact phrase:"), this); gLayout->addWidget(label, 2, 0); d->exactQuery = new QLineEdit(this); + d->exactQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->exactQuery, 2, 1); label = new QLabel(tr("with all of the words:"), this); gLayout->addWidget(label, 3, 0); d->allQuery = new QLineEdit(this); + d->allQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->allQuery, 3, 1); label = new QLabel(tr("with at least one of the words:"), this); gLayout->addWidget(label, 4, 0); d->atLeastQuery = new QLineEdit(this); + d->atLeastQuery->setCompleter(&d->searchCompleter); gLayout->addWidget(d->atLeastQuery, 4, 1); vLayout->addWidget(d->advancedSearchWidget); @@ -269,6 +498,7 @@ QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent) connect(d->showHideAdvancedSearchButton, SIGNAL(clicked()), d, SLOT(showHideAdvancedSearch())); #endif + connect(this, SIGNAL(search()), d, SLOT(searchRequested())); } /*! @@ -285,59 +515,10 @@ QHelpSearchQueryWidget::~QHelpSearchQueryWidget() */ QList QHelpSearchQueryWidget::query() const { -#if !defined(QT_CLUCENE_SUPPORT) - QList queryList; - queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT, - QStringList(d->defaultQuery->text()))); - - return queryList; -#else - QList queryList; - if (d->defaultQuery->isEnabled()) { - queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT, - d->buildTermList(d->escapeString(d->defaultQuery->text())))); - } else { - const QRegExp exp(QLatin1String("\\s+")); - QStringList lst = d->similarQuery->text().split(exp, QString::SkipEmptyParts); - if (!lst.isEmpty()) { - QStringList fuzzy; - foreach (const QString term, lst) - fuzzy += d->buildTermList(d->escapeString(term)); - queryList.append(QHelpSearchQuery(QHelpSearchQuery::FUZZY, fuzzy)); - } - - lst = d->withoutQuery->text().split(exp, QString::SkipEmptyParts); - if (!lst.isEmpty()) { - QStringList without; - foreach (const QString term, lst) - without.append(d->escapeString(term)); - queryList.append(QHelpSearchQuery(QHelpSearchQuery::WITHOUT, without)); - } - - if (!d->exactQuery->text().isEmpty()) { - QString phrase = d->exactQuery->text().remove(QLatin1Char('\"')); - phrase = d->escapeString(phrase.simplified()); - queryList.append(QHelpSearchQuery(QHelpSearchQuery::PHRASE, QStringList(phrase))); - } - - lst = d->allQuery->text().split(exp, QString::SkipEmptyParts); - if (!lst.isEmpty()) { - QStringList all; - foreach (const QString term, lst) - all.append(d->escapeString(term)); - queryList.append(QHelpSearchQuery(QHelpSearchQuery::ALL, all)); - } - - lst = d->atLeastQuery->text().split(exp, QString::SkipEmptyParts); - if (!lst.isEmpty()) { - QStringList atLeast; - foreach (const QString term, lst) - atLeast += d->buildTermList(d->escapeString(term)); - queryList.append(QHelpSearchQuery(QHelpSearchQuery::ATLEAST, atLeast)); - } - } - return queryList; -#endif + const QHelpSearchQueryWidgetPrivate::QueryHistory &queryHist = + d->simpleSearch ? d->simpleQueries : d->complexQueries; + return queryHist.queries.isEmpty() ? + QList() : queryHist.queries.last(); } /*! \reimp -- cgit v0.12 From 40d7153ad17d6eca96cb4718486e8e2654b72f00 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 4 Aug 2009 13:30:00 +0200 Subject: qdoc: Added \annotated list command to qdoc3. Now you can put "\annotatedlist xxx" anywhere in a qdoc comment, and it will generate the class list for the xxx group at that location. xxx must be a group name. --- tools/qdoc3/atom.cpp | 2 ++ tools/qdoc3/atom.h | 1 + tools/qdoc3/cppcodeparser.cpp | 3 +++ tools/qdoc3/doc.cpp | 32 ++++++++++++++++++-------------- tools/qdoc3/htmlgenerator.cpp | 14 ++++++++++++++ tools/qdoc3/tree.cpp | 2 ++ 6 files changed, 40 insertions(+), 14 deletions(-) diff --git a/tools/qdoc3/atom.cpp b/tools/qdoc3/atom.cpp index a82a783..da32735 100644 --- a/tools/qdoc3/atom.cpp +++ b/tools/qdoc3/atom.cpp @@ -93,6 +93,7 @@ QString Atom::UPPERROMAN_ ("upperroman"); \value AbstractLeft \value AbstractRight + \value AnnotatedList \value AutoLink \value BaseName \value BriefLeft @@ -163,6 +164,7 @@ static const struct { } atms[] = { { "AbstractLeft", Atom::AbstractLeft }, { "AbstractRight", Atom::AbstractRight }, + { "AnnotatedList", Atom::AnnotatedList }, { "AutoLink", Atom::AutoLink }, { "BaseName", Atom::BaseName }, { "BriefLeft", Atom::BriefLeft }, diff --git a/tools/qdoc3/atom.h b/tools/qdoc3/atom.h index 6d5af0a..941ac70 100644 --- a/tools/qdoc3/atom.h +++ b/tools/qdoc3/atom.h @@ -58,6 +58,7 @@ class Atom enum Type { AbstractLeft, AbstractRight, + AnnotatedList, AutoLink, BaseName, BriefLeft, diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index 4563f65..562684b 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -1724,6 +1724,9 @@ bool CppCodeParser::matchProperty(InnerNode *parent) value = "?"; } + /* + Task 259071 requires work here. See gui/widgets/qdatetime.h, for example. + */ if (key == "READ") tre->addPropertyFunction(property, value, PropertyNode::Getter); else if (key == "WRITE") diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp index d5aca0e..e2f3525 100644 --- a/tools/qdoc3/doc.cpp +++ b/tools/qdoc3/doc.cpp @@ -73,20 +73,20 @@ struct Macro }; enum { - CMD_A, CMD_ABSTRACT, CMD_BADCODE, CMD_BASENAME, CMD_BOLD, - CMD_BRIEF, CMD_C, CMD_CAPTION, CMD_CHAPTER, CMD_CODE, - CMD_CODELINE, CMD_DOTS, CMD_ELSE, CMD_ENDABSTRACT, - CMD_ENDCHAPTER, CMD_ENDCODE, CMD_ENDFOOTNOTE, CMD_ENDIF, - CMD_ENDLEGALESE, CMD_ENDLINK, CMD_ENDLIST, CMD_ENDOMIT, - CMD_ENDPART, CMD_ENDQUOTATION, CMD_ENDRAW, CMD_ENDSECTION1, - CMD_ENDSECTION2, CMD_ENDSECTION3, CMD_ENDSECTION4, - CMD_ENDSIDEBAR, CMD_ENDTABLE, CMD_EXPIRE, CMD_FOOTNOTE, - CMD_GENERATELIST, CMD_GRANULARITY, CMD_HEADER, CMD_I, - CMD_IF, CMD_IMAGE, CMD_INCLUDE, CMD_INLINEIMAGE, CMD_INDEX, - CMD_KEYWORD, CMD_L, CMD_LEGALESE, CMD_LINK, CMD_LIST, - CMD_META, CMD_NEWCODE, CMD_O, CMD_OLDCODE, CMD_OMIT, - CMD_OMITVALUE, CMD_OVERLOAD, - CMD_PART, CMD_PRINTLINE, CMD_PRINTTO, + CMD_A, CMD_ABSTRACT, CMD_ANNOTATEDLIST, CMD_BADCODE, + CMD_BASENAME, CMD_BOLD, CMD_BRIEF, CMD_C, CMD_CAPTION, + CMD_CHAPTER, CMD_CODE, CMD_CODELINE, CMD_DOTS, CMD_ELSE, + CMD_ENDABSTRACT, CMD_ENDCHAPTER, CMD_ENDCODE, + CMD_ENDFOOTNOTE, CMD_ENDIF, CMD_ENDLEGALESE, CMD_ENDLINK, + CMD_ENDLIST, CMD_ENDOMIT, CMD_ENDPART, CMD_ENDQUOTATION, + CMD_ENDRAW, CMD_ENDSECTION1, CMD_ENDSECTION2, + CMD_ENDSECTION3, CMD_ENDSECTION4, CMD_ENDSIDEBAR, + CMD_ENDTABLE, CMD_EXPIRE, CMD_FOOTNOTE, CMD_GENERATELIST, + CMD_GRANULARITY, CMD_HEADER, CMD_I, CMD_IF, CMD_IMAGE, + CMD_INCLUDE, CMD_INLINEIMAGE, CMD_INDEX, CMD_KEYWORD, + CMD_L, CMD_LEGALESE, CMD_LINK, CMD_LIST, CMD_META, + CMD_NEWCODE, CMD_O, CMD_OLDCODE, CMD_OMIT, CMD_OMITVALUE, + CMD_OVERLOAD, CMD_PART, CMD_PRINTLINE, CMD_PRINTTO, CMD_PRINTUNTIL, CMD_QUOTATION, CMD_QUOTEFILE, CMD_QUOTEFROMFILE, CMD_QUOTEFUNCTION, CMD_RAW, CMD_ROW, CMD_SA, CMD_SECTION1, CMD_SECTION2, CMD_SECTION3, @@ -108,6 +108,7 @@ static struct { } cmds[] = { { "a", CMD_A, 0 }, { "abstract", CMD_ABSTRACT, 0 }, + { "annotatedlist", CMD_ANNOTATEDLIST, 0 }, { "badcode", CMD_BADCODE, 0 }, { "basename", CMD_BASENAME, 0 }, // ### don't document for now { "bold", CMD_BOLD, 0 }, @@ -723,6 +724,9 @@ void DocParser::parse(const QString& source, paraState = OutsidePara; // ### } break; + case CMD_ANNOTATEDLIST: + append(Atom::AnnotatedList, getArgument()); + break; case CMD_GENERATELIST: append(Atom::GeneratedList, getArgument()); break; diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 6590114..425c50b 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -537,6 +537,20 @@ int HtmlGenerator::generateAtom(const Atom *atom, out() << formattingRightMap()[atom->string()]; } break; + case Atom::AnnotatedList: + { + const FakeNode *fake = static_cast(relative); + if (fake && !fake->groupMembers().isEmpty()) { + QList values = tre->groups().values(atom->string()); + QMap nodeMap; + for (int i = 0; i < values.size(); ++i) { + const Node* n = values.at(i); + nodeMap.insert(n->name(),n); + } + generateAnnotatedList(fake, marker, nodeMap); + } + } + break; case Atom::GeneratedList: if (atom->string() == "annotatedclasses") { generateAnnotatedList(relative, marker, nonCompatClasses); diff --git a/tools/qdoc3/tree.cpp b/tools/qdoc3/tree.cpp index e6dd084..d75af70 100644 --- a/tools/qdoc3/tree.cpp +++ b/tools/qdoc3/tree.cpp @@ -419,6 +419,8 @@ void Tree::addPropertyFunction(PropertyNode *property, } /*! + This function adds the \a node to the \a group. The group + can be listed anywhere using the \e{annotated list} command. */ void Tree::addToGroup(Node *node, const QString &group) { -- cgit v0.12 From e888ff9902f193b8797d7993cd7d43e76045dcc1 Mon Sep 17 00:00:00 2001 From: ck Date: Tue, 4 Aug 2009 13:54:42 +0200 Subject: Assistant: Use non-GUI version of QApplication for command-line tasks. Task-number: 259136 Reviewed-by: kh --- tools/assistant/tools/assistant/main.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/assistant/tools/assistant/main.cpp b/tools/assistant/tools/assistant/main.cpp index a0a5a0d..4af2570 100644 --- a/tools/assistant/tools/assistant/main.cpp +++ b/tools/assistant/tools/assistant/main.cpp @@ -181,7 +181,21 @@ QString indexFilesFolder(const QString &collectionFile) int main(int argc, char *argv[]) { - QApplication a(argc, argv); + // First do a quick search for arguments that imply command-line mode. + const char * cmdModeArgs[] = { + "-help", "-register", "-unregister", "-remove-search-index" + }; + bool useGui = true; + for (int i = 1; i < argc; ++i) { + for (size_t j = 0; j < sizeof cmdModeArgs/sizeof *cmdModeArgs; ++j) { + if(strcmp(argv[i], cmdModeArgs[j]) == 0) { + useGui = false; + break; + } + } + } + + QApplication a(argc, argv, useGui); a.addLibraryPath(a.applicationDirPath() + QLatin1String("/plugins")); CmdLineParser cmd; -- cgit v0.12 From 69c379451f496071c51542dab876d41916b62889 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 4 Aug 2009 14:19:12 +0200 Subject: have QPainter::begin() return false on null paint engine Reviewed-by: Samuel --- src/gui/painting/qpainter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 9c7a7fa..8192fb7 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1672,7 +1672,7 @@ bool QPainter::begin(QPaintDevice *pd) if (!d->engine) { qWarning("QPainter::begin: Paint device returned engine == 0, type: %d", pd->devType()); - return true; + return false; } // Slip a painter state into the engine before we do any other operations -- cgit v0.12 From b6275b9dd1a852c86b22b354bfae3c98c8191fda Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 4 Aug 2009 14:26:39 +0200 Subject: Animations: better handling of the timer It could be that if you start lots of animations, they would not be started at the same time and even have their first tick to late. So we needed to only transfer the started animation when receiving the start/stop timer tick. In addition, if the animation timer is already active we don't restart it. This would cause no animation to receive ticks if lots of them are started. --- src/corelib/animation/qabstractanimation.cpp | 30 ++++++---------------------- src/corelib/animation/qabstractanimation_p.h | 3 --- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index ced86d2..1d274c9 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -177,17 +177,6 @@ QUnifiedTimer *QUnifiedTimer::instance() return inst; } -void QUnifiedTimer::updateRecentlyStartedAnimations() -{ - if (animationsToStart.isEmpty()) - return; - - animations += animationsToStart; - updateTimer(); //we make sure we start the timer there - - animationsToStart.clear(); -} - void QUnifiedTimer::timerEvent(QTimerEvent *event) { //this is simply the time we last received a tick @@ -195,15 +184,16 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event) if (time.isValid()) lastTick = consistentTiming ? oldLastTick + timingInterval : time.elapsed(); - //we transfer the waiting animations into the "really running" state - updateRecentlyStartedAnimations(); if (event->timerId() == startStopAnimationTimer.timerId()) { startStopAnimationTimer.stop(); + //we transfer the waiting animations into the "really running" state + animations += animationsToStart; + animationsToStart.clear(); if (animations.isEmpty()) { animationTimer.stop(); time = QTime(); - } else { + } else if (!animationTimer.isActive()) { animationTimer.start(timingInterval, this); lastTick = 0; time.start(); @@ -219,27 +209,19 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event) } } -void QUnifiedTimer::updateTimer() -{ - //we delay the call to start and stop for the animation timer so that if you - //stop and start animations in batch you don't stop/start the timer too often. - if (!startStopAnimationTimer.isActive()) - startStopAnimationTimer.start(0, this); // we delay the actual start of the animation -} - void QUnifiedTimer::registerAnimation(QAbstractAnimation *animation) { if (animations.contains(animation) ||animationsToStart.contains(animation)) return; animationsToStart << animation; - updateTimer(); + startStopAnimationTimer.start(0, this); // we delay the check if we should start/stop the global timer } void QUnifiedTimer::unregisterAnimation(QAbstractAnimation *animation) { animations.removeAll(animation); animationsToStart.removeAll(animation); - updateTimer(); + startStopAnimationTimer.start(0, this); // we delay the check if we should start/stop the global timer } diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 0d8402e..b281aa2 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -135,11 +135,8 @@ public: protected: void timerEvent(QTimerEvent *); - void updateTimer(); private: - void updateRecentlyStartedAnimations(); - QBasicTimer animationTimer, startStopAnimationTimer; QTime time; int lastTick; -- cgit v0.12 From 30e3a39ca2e5e1204cc123dce2f2921d8fda620d Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 4 Aug 2009 15:03:15 +0200 Subject: QParallelAnimationGroup pause resume fixed If you resumed a parallel animation group, it would always restart (ie. stop and start) the animation which would reset its current time to 0 and trigger flickering. autotest included. Task-Number: 259102 --- src/corelib/animation/qparallelanimationgroup.cpp | 3 +- .../tst_qparallelanimationgroup.cpp | 33 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp index 5e4b0d2..8aa04a4 100644 --- a/src/corelib/animation/qparallelanimationgroup.cpp +++ b/src/corelib/animation/qparallelanimationgroup.cpp @@ -214,7 +214,8 @@ void QParallelAnimationGroup::updateState(QAbstractAnimation::State oldState, d->connectUncontrolledAnimations(); for (int i = 0; i < d->animations.size(); ++i) { QAbstractAnimation *animation = d->animations.at(i); - animation->stop(); + if (oldState == Stopped) + animation->stop(); animation->setDirection(d->direction); animation->start(); } diff --git a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp index d7d6b88..16c58b0 100644 --- a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp +++ b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp @@ -74,6 +74,7 @@ private slots: void loopCount_data(); void loopCount(); void autoAdd(); + void pauseResume(); }; tst_QParallelAnimationGroup::tst_QParallelAnimationGroup() @@ -828,5 +829,37 @@ void tst_QParallelAnimationGroup::autoAdd() QCOMPARE(group.duration(), 0); } +void tst_QParallelAnimationGroup::pauseResume() +{ + QParallelAnimationGroup group; + TestAnimation2 *anim = new TestAnimation2(250, &group); // 0, duration = 250; + QSignalSpy spy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State))); + QCOMPARE(group.duration(), 250); + group.start(); + QTest::qWait(100); + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(anim->state(), QAnimationGroup::Running); + QCOMPARE(spy.count(), 1); + spy.clear(); + const int currentTime = group.currentTime(); + QCOMPARE(anim->currentTime(), currentTime); + + group.pause(); + QCOMPARE(group.state(), QAnimationGroup::Paused); + QCOMPARE(group.currentTime(), currentTime); + QCOMPARE(anim->state(), QAnimationGroup::Paused); + QCOMPARE(anim->currentTime(), currentTime); + QCOMPARE(spy.count(), 1); + spy.clear(); + + group.resume(); + QCOMPARE(group.state(), QAnimationGroup::Running); + QCOMPARE(group.currentTime(), currentTime); + QCOMPARE(anim->state(), QAnimationGroup::Running); + QCOMPARE(anim->currentTime(), currentTime); + QCOMPARE(spy.count(), 1); +} + + QTEST_MAIN(tst_QParallelAnimationGroup) #include "tst_qparallelanimationgroup.moc" -- cgit v0.12 From b80a499764bf331880ff0c0d52670a419ec50feb Mon Sep 17 00:00:00 2001 From: jasplin Date: Tue, 4 Aug 2009 15:44:45 +0200 Subject: Added input hints to QGraphicsItem. This patch allows for input hints to be set on a QGraphicsItem. Input methods use such hints to define its appearance/behavior (e.g. to allow for numerical input only). Reviewed-by: ahanssen Task-number: 254493 --- doc/src/classes/qnamespace.qdoc | 24 ++++++++++++++++++ src/corelib/global/qnamespace.h | 16 ++++++++++++ src/gui/graphicsview/qgraphicsitem.cpp | 35 +++++++++++++++++++++++++- src/gui/graphicsview/qgraphicsitem.h | 3 +++ src/gui/graphicsview/qgraphicsitem_p.h | 4 ++- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 13 ++++++++++ 6 files changed, 93 insertions(+), 2 deletions(-) diff --git a/doc/src/classes/qnamespace.qdoc b/doc/src/classes/qnamespace.qdoc index 59e0a95..a49e079 100644 --- a/doc/src/classes/qnamespace.qdoc +++ b/doc/src/classes/qnamespace.qdoc @@ -2418,6 +2418,30 @@ */ /*! + \enum Qt::InputMethodHint + + \value ImhNone No hints. + \value ImhHiddenText Characters should be hidden, as is typically used when entering passwords. + This is automatically set when setting QLineEdit::echoMode to \c Password. + \value ImhNumbersOnly Only number input is allowed. + \value ImhUppercaseOnly Only upper case letter input is allowed. + \value ImhLowercaseOnly Only lower case letter input is allowed. + \value ImhNoAutoUppercase The input method should not try to automatically switch to upper case + when a sentence ends. + \value ImhPreferNumbers Numbers are preferred (but not required). + \value ImhPreferUppercase Upper case letters are preferred (but not required). + \value ImhPreferLowercase Lower case letters are preferred (but not required). + \value ImhNoPredictiveText Do not use predictive text (i.e. dictionary lookup) while typing. + \value ImhDialableCharactersOnly Only characters suitable for phone dialling are allowed. + + \note If several flags ending with \c Only are ORed together, the resulting character set will + consist of the union of the specified sets. For instance specifying \c ImhNumbersOnly and + \c ImhUppercaseOnly would yield a set consisting of numbers and uppercase letters. + + \sa QGraphicsItem::inputMethodHints() +*/ + +/*! \enum Qt::InputMethodQuery \value ImMicroFocus The rectangle covering the area of the input cursor in widget coordinates. diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 7770fd6..f172d77 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1406,6 +1406,21 @@ public: ImCurrentSelection }; + enum InputMethodHint { + ImhNone = 0x0, + ImhHiddenText = 0x1, + ImhNumbersOnly = 0x2, + ImhUppercaseOnly = 0x4, + ImhLowercaseOnly = 0x8, + ImhNoAutoUppercase = 0x10, + ImhPreferNumbers = 0x20, + ImhPreferUppercase = 0x40, + ImhPreferLowercase = 0x80, + ImhNoPredictiveText = 0x100, + ImhDialableCharactersOnly = 0x200 + }; + Q_DECLARE_FLAGS(InputMethodHints, InputMethodHint) + enum ToolButtonStyle { ToolButtonIconOnly, ToolButtonTextOnly, @@ -1591,6 +1606,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ItemFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MatchFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TextInteractionFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TouchPointStates) +Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodHints) typedef bool (*qInternalCallback)(void **); diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index a047e6a..6a21e99 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -6384,7 +6384,7 @@ void QGraphicsItem::inputMethodEvent(QInputMethodEvent *event) surrounding text and reconversions. \a query specifies which property is queried. - \sa inputMethodEvent() + \sa inputMethodEvent(), QInputMethodEvent, QInputContext */ QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const { @@ -6400,6 +6400,39 @@ QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const } /*! + Returns the current input method hints of this item. + + Input method hints are only relevant for input items. + The hints are used by the input method to indicate how it should operate. + For example, if the Qt::ImhNumbersOnly flag is set, the input method may change + its visual components to reflect that only numbers can be entered. + + The effect may vary between input method implementations. + + \since 4.6 + + \sa setInputMethodHints(), inputMethodQuery(), QInputContext +*/ +Qt::InputMethodHints QGraphicsItem::inputMethodHints() const +{ + Q_D(const QGraphicsItem); + return d->imHints; +} + +/*! + Sets the current input method hints of this item to \a hints. + + \since 4.6 + + \sa inputMethodHints(), inputMethodQuery(), QInputContext +*/ +void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints) +{ + Q_D(QGraphicsItem); + d->imHints = hints; +} + +/*! This virtual function is called by QGraphicsItem to notify custom items that some part of the item's state changes. By reimplementing this function, your can react to a change, and in some cases, (depending on \a diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index b94fb97..f142b0f 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -375,6 +375,9 @@ public: QVariant data(int key) const; void setData(int key, const QVariant &value); + Qt::InputMethodHints inputMethodHints() const; + void setInputMethodHints(Qt::InputMethodHints hints); + enum { Type = 1, UserType = 65536 diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 5c3622b..805b554 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -126,6 +126,7 @@ public: depth(0), focusProxy(0), subFocusItem(0), + imHints(Qt::ImhNone), acceptedMouseButtons(0x1f), visible(1), explicitlyHidden(0), @@ -419,8 +420,9 @@ public: int depth; QGraphicsItem *focusProxy; QGraphicsItem *subFocusItem; + Qt::InputMethodHints imHints; - // Packed 32 bytes + // Packed 32 bits quint32 acceptedMouseButtons : 5; quint32 visible : 1; quint32 explicitlyHidden : 1; diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 7f6f322..ef3f0f8 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -169,6 +169,7 @@ private slots: void setParentItem(); void children(); void flags(); + void inputMethodHints(); void toolTip(); void visible(); void explicitlyVisible(); @@ -762,6 +763,18 @@ void tst_QGraphicsItem::flags() } } +class ImhTester : public QGraphicsItem +{ + QRectF boundingRect() const { return QRectF(); } + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {} +}; + +void tst_QGraphicsItem::inputMethodHints() +{ + ImhTester item; + QCOMPARE(item.inputMethodHints(), Qt::ImhNone); +} + void tst_QGraphicsItem::toolTip() { QString toolTip = "Qt rocks!"; -- cgit v0.12 From 69f0ba079899970aa53351a7d6b864f0a2bb8343 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 4 Aug 2009 16:04:55 +0200 Subject: Fix build on Harmattan --- src/gui/egl/qegl_x11.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index daaa4ba..6772592 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -39,15 +39,18 @@ ** ****************************************************************************/ +#include + +#include +#include +#include +#include + #include #include #include -#include #include "qegl_p.h" -#include -#include -#include QT_BEGIN_NAMESPACE -- cgit v0.12 From df373516909d4dc0dfe8149f4cbff17c9c9bfe54 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 4 Aug 2009 14:00:05 +0200 Subject: QHttpNetworkConnection: Moved channel slots to channel object Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkconnection.cpp | 246 +-------------------- src/network/access/qhttpnetworkconnection_p.h | 30 +-- .../access/qhttpnetworkconnectionchannel.cpp | 214 ++++++++++++++++++ .../access/qhttpnetworkconnectionchannel_p.h | 25 +++ src/network/access/qhttpnetworkreply_p.h | 1 + 5 files changed, 249 insertions(+), 267 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 75ab837..d73cd67 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -87,58 +87,11 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate() delete []channels; } -void QHttpNetworkConnectionPrivate::connectSignals(QAbstractSocket *socket) -{ - Q_Q(QHttpNetworkConnection); - - QObject::connect(socket, SIGNAL(bytesWritten(qint64)), - q, SLOT(_q_bytesWritten(qint64)), - Qt::DirectConnection); - QObject::connect(socket, SIGNAL(connected()), - q, SLOT(_q_connected()), - Qt::DirectConnection); - QObject::connect(socket, SIGNAL(readyRead()), - q, SLOT(_q_readyRead()), - Qt::DirectConnection); - QObject::connect(socket, SIGNAL(disconnected()), - q, SLOT(_q_disconnected()), - Qt::DirectConnection); - QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), - q, SLOT(_q_error(QAbstractSocket::SocketError)), - Qt::DirectConnection); -#ifndef QT_NO_NETWORKPROXY - QObject::connect(socket, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), - q, SLOT(_q_proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), - Qt::DirectConnection); -#endif - -#ifndef QT_NO_OPENSSL - QSslSocket *sslSocket = qobject_cast(socket); - if (sslSocket) { - // won't be a sslSocket if encrypt is false - QObject::connect(sslSocket, SIGNAL(encrypted()), - q, SLOT(_q_encrypted()), - Qt::DirectConnection); - QObject::connect(sslSocket, SIGNAL(sslErrors(const QList&)), - q, SLOT(_q_sslErrors(const QList&)), - Qt::DirectConnection); - } -#endif -} - void QHttpNetworkConnectionPrivate::init() { - for (int i = 0; i < channelCount; ++i) { -#ifndef QT_NO_OPENSSL - if (encrypt) - channels[i].socket = new QSslSocket; - else - channels[i].socket = new QTcpSocket; -#else - channels[i].socket = new QTcpSocket; -#endif - - connectSignals(channels[i].socket); + for (int i = 0; i < channelCount; i++) { + channels[i].setConnection(this->q_func()); + channels[i].init(); } } @@ -406,7 +359,7 @@ bool QHttpNetworkConnectionPrivate::sendRequest(QAbstractSocket *socket) QNonContiguousByteDevice* uploadByteDevice = channels[i].request.uploadByteDevice(); if (uploadByteDevice) { // connect the signals so this function gets called again - QObject::connect(uploadByteDevice, SIGNAL(readyRead()), q, SLOT(_q_uploadDataReadyRead())); + QObject::connect(uploadByteDevice, SIGNAL(readyRead()), &channels[i], SLOT(_q_uploadDataReadyRead())); channels[i].bytesTotal = channels[i].request.contentLength(); } else { @@ -485,7 +438,7 @@ bool QHttpNetworkConnectionPrivate::sendRequest(QAbstractSocket *socket) { QNonContiguousByteDevice* uploadByteDevice = channels[i].request.uploadByteDevice(); if (uploadByteDevice) { - QObject::disconnect(uploadByteDevice, SIGNAL(readyRead()), q, SLOT(_q_uploadDataReadyRead())); + QObject::disconnect(uploadByteDevice, SIGNAL(readyRead()), &channels[i], SLOT(_q_uploadDataReadyRead())); } // ensure we try to receive a reply in all cases, even if _q_readyRead_ hat not been called // this is needed if the sends an reply before we have finished sending the request. In that @@ -1004,11 +957,7 @@ void QHttpNetworkConnectionPrivate::unqueueAndSendRequest(QAbstractSocket *socke void QHttpNetworkConnectionPrivate::closeChannel(int channel) { - QAbstractSocket *socket = channels[channel].socket; - socket->blockSignals(true); - socket->close(); - socket->blockSignals(false); - channels[channel].state = QHttpNetworkConnectionChannel::IdleState; + channels[channel].close(); } void QHttpNetworkConnectionPrivate::resendCurrentRequest(QAbstractSocket *socket) @@ -1102,53 +1051,6 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply) } -//private slots -void QHttpNetworkConnectionPrivate::_q_readyRead() -{ - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; // ### error - if (isSocketWaiting(socket) || isSocketReading(socket)) { - int i = indexOf(socket); - channels[i].state = QHttpNetworkConnectionChannel::ReadingState; - if (channels[i].reply) - receiveReply(socket, channels[i].reply); - } - // ### error -} - -void QHttpNetworkConnectionPrivate::_q_bytesWritten(qint64 bytes) -{ - Q_UNUSED(bytes); - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; // ### error - // bytes have been written to the socket. write even more of them :) - if (isSocketWriting(socket)) - sendRequest(socket); - // otherwise we do nothing -} - -void QHttpNetworkConnectionPrivate::_q_disconnected() -{ - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; // ### error - // read the available data before closing - int i = indexOf(socket); - if (isSocketWaiting(socket) || isSocketReading(socket)) { - channels[i].state = QHttpNetworkConnectionChannel::ReadingState; - if (channels[i].reply) - receiveReply(socket, channels[i].reply); - } else if (channels[i].state == QHttpNetworkConnectionChannel::IdleState && channels[i].resendCurrent) { - // re-sending request because the socket was in ClosingState - QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); - } - channels[i].state = QHttpNetworkConnectionChannel::IdleState; -} void QHttpNetworkConnectionPrivate::_q_startNextRequest() { @@ -1188,121 +1090,6 @@ void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests() } } -void QHttpNetworkConnectionPrivate::_q_connected() -{ - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; // ### error - - // improve performance since we get the request sent by the kernel ASAP - socket->setSocketOption(QAbstractSocket::LowDelayOption, 1); - - int i = indexOf(socket); - // ### FIXME: if the server closes the connection unexpectedly, we shouldn't send the same broken request again! - //channels[i].reconnectAttempts = 2; - if (!channels[i].pendingEncrypt) { - channels[i].state = QHttpNetworkConnectionChannel::IdleState; - if (channels[i].reply) - sendRequest(socket); - else - closeChannel(i); - } -} - - -void QHttpNetworkConnectionPrivate::_q_error(QAbstractSocket::SocketError socketError) -{ - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; - bool send2Reply = false; - int i = indexOf(socket); - QNetworkReply::NetworkError errorCode = QNetworkReply::UnknownNetworkError; - - switch (socketError) { - case QAbstractSocket::HostNotFoundError: - errorCode = QNetworkReply::HostNotFoundError; - break; - case QAbstractSocket::ConnectionRefusedError: - errorCode = QNetworkReply::ConnectionRefusedError; - break; - case QAbstractSocket::RemoteHostClosedError: - // try to reconnect/resend before sending an error. - // while "Reading" the _q_disconnected() will handle this. - if (channels[i].state != QHttpNetworkConnectionChannel::IdleState && channels[i].state != QHttpNetworkConnectionChannel::ReadingState) { - if (channels[i].reconnectAttempts-- > 0) { - resendCurrentRequest(socket); - return; - } else { - send2Reply = true; - errorCode = QNetworkReply::RemoteHostClosedError; - } - } else { - return; - } - break; - case QAbstractSocket::SocketTimeoutError: - // try to reconnect/resend before sending an error. - if (channels[i].state == QHttpNetworkConnectionChannel::WritingState && (channels[i].reconnectAttempts-- > 0)) { - resendCurrentRequest(socket); - return; - } - send2Reply = true; - errorCode = QNetworkReply::TimeoutError; - break; - case QAbstractSocket::ProxyAuthenticationRequiredError: - errorCode = QNetworkReply::ProxyAuthenticationRequiredError; - break; - case QAbstractSocket::SslHandshakeFailedError: - errorCode = QNetworkReply::SslHandshakeFailedError; - break; - default: - // all other errors are treated as NetworkError - errorCode = QNetworkReply::UnknownNetworkError; - break; - } - QPointer that = q; - QString errorString = errorDetail(errorCode, socket); - if (send2Reply) { - if (channels[i].reply) { - channels[i].reply->d_func()->errorString = errorString; - // this error matters only to this reply - emit channels[i].reply->finishedWithError(errorCode, errorString); - } - // send the next request - QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection); - } else { - // the failure affects all requests. - emit q->error(errorCode, errorString); - } - if (that) //signals make enter the event loop - closeChannel(i); -} - -#ifndef QT_NO_NETWORKPROXY -void QHttpNetworkConnectionPrivate::_q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator* auth) -{ - Q_Q(QHttpNetworkConnection); - emit q->proxyAuthenticationRequired(proxy, auth, q); -} -#endif - -void QHttpNetworkConnectionPrivate::_q_uploadDataReadyRead() -{ - Q_Q(QHttpNetworkConnection); - // upload data emitted readyRead() - // find out which channel it is for - QObject *sender = q->sender(); - - for (int i = 0; i < channelCount; ++i) { - if (sender == channels[i].request.uploadByteDevice()) { - sendRequest(channels[i].socket); - break; - } - } -} QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt, QObject *parent) : QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt)), parent) @@ -1397,27 +1184,6 @@ QNetworkProxy QHttpNetworkConnection::transparentProxy() const // SSL support below #ifndef QT_NO_OPENSSL -void QHttpNetworkConnectionPrivate::_q_encrypted() -{ - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; // ### error - int i = indexOf(socket); - channels[i].state = QHttpNetworkConnectionChannel::IdleState; - sendRequest(socket); -} - -void QHttpNetworkConnectionPrivate::_q_sslErrors(const QList &errors) -{ - Q_Q(QHttpNetworkConnection); - QAbstractSocket *socket = qobject_cast(q->sender()); - if (!socket) - return; - //QNetworkReply::NetworkError errorCode = QNetworkReply::ProtocolFailure; - emit q->sslErrors(errors); -} - QSslConfiguration QHttpNetworkConnectionPrivate::sslConfiguration(const QHttpNetworkReply &reply) const { if (!encrypt) diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index db6a140..48401d2 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -138,23 +138,10 @@ private: Q_DECLARE_PRIVATE(QHttpNetworkConnection) Q_DISABLE_COPY(QHttpNetworkConnection) friend class QHttpNetworkReply; + friend class QHttpNetworkConnectionChannel; - Q_PRIVATE_SLOT(d_func(), void _q_bytesWritten(qint64)) - Q_PRIVATE_SLOT(d_func(), void _q_readyRead()) - Q_PRIVATE_SLOT(d_func(), void _q_disconnected()) Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest()) Q_PRIVATE_SLOT(d_func(), void _q_restartAuthPendingRequests()) - Q_PRIVATE_SLOT(d_func(), void _q_connected()) - Q_PRIVATE_SLOT(d_func(), void _q_error(QAbstractSocket::SocketError)) -#ifndef QT_NO_NETWORKPROXY - Q_PRIVATE_SLOT(d_func(), void _q_proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)) -#endif - Q_PRIVATE_SLOT(d_func(), void _q_uploadDataReadyRead()) - -#ifndef QT_NO_OPENSSL - Q_PRIVATE_SLOT(d_func(), void _q_encrypted()) - Q_PRIVATE_SLOT(d_func(), void _q_sslErrors(const QList&)) -#endif }; @@ -169,7 +156,6 @@ public: QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt); ~QHttpNetworkConnectionPrivate(); void init(); - void connectSignals(QAbstractSocket *socket); enum { ChunkSize = 4096 }; @@ -189,18 +175,8 @@ public: void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy); // private slots - void _q_bytesWritten(qint64 bytes); // proceed sending - void _q_readyRead(); // pending data to read - void _q_disconnected(); // disconnected from host void _q_startNextRequest(); // send the next request from the queue void _q_restartAuthPendingRequests(); // send the currently blocked request - void _q_connected(); // start sending request - void _q_error(QAbstractSocket::SocketError); // error from socket -#ifndef QT_NO_NETWORKPROXY - void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); // from transparent proxy -#endif - - void _q_uploadDataReadyRead(); void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request); bool ensureConnection(QAbstractSocket *socket); @@ -237,8 +213,6 @@ public: inline bool expectContent(QHttpNetworkReply *reply); #ifndef QT_NO_OPENSSL - void _q_encrypted(); // start sending request (https) - void _q_sslErrors(const QList &errors); // ssl errors from the socket QSslConfiguration sslConfiguration(const QHttpNetworkReply &reply) const; #endif @@ -249,6 +223,8 @@ public: //The request queues QList highPriorityQueue; QList lowPriorityQueue; + + friend class QHttpNetworkConnectionChannel; }; diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index a04b530..6cd46fd 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -57,6 +57,220 @@ QT_BEGIN_NAMESPACE // TODO: Put channel specific stuff here so it does not polute qhttpnetworkconnection.cpp +void QHttpNetworkConnectionChannel::init() +{ +#ifndef QT_NO_OPENSSL + if (connection->d_func()->encrypt) + socket = new QSslSocket; + else + socket = new QTcpSocket; +#else + socket = new QTcpSocket; +#endif + + QObject::connect(socket, SIGNAL(bytesWritten(qint64)), + this, SLOT(_q_bytesWritten(qint64)), + Qt::DirectConnection); + QObject::connect(socket, SIGNAL(connected()), + this, SLOT(_q_connected()), + Qt::DirectConnection); + QObject::connect(socket, SIGNAL(readyRead()), + this, SLOT(_q_readyRead()), + Qt::DirectConnection); + QObject::connect(socket, SIGNAL(disconnected()), + this, SLOT(_q_disconnected()), + Qt::DirectConnection); + QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(_q_error(QAbstractSocket::SocketError)), + Qt::DirectConnection); +#ifndef QT_NO_NETWORKPROXY + QObject::connect(socket, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), + this, SLOT(_q_proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), + Qt::DirectConnection); +#endif + +#ifndef QT_NO_OPENSSL + QSslSocket *sslSocket = qobject_cast(socket); + if (sslSocket) { + // won't be a sslSocket if encrypt is false + QObject::connect(sslSocket, SIGNAL(encrypted()), + this, SLOT(_q_encrypted()), + Qt::DirectConnection); + QObject::connect(sslSocket, SIGNAL(sslErrors(const QList&)), + this, SLOT(_q_sslErrors(const QList&)), + Qt::DirectConnection); + } +#endif +} + + +void QHttpNetworkConnectionChannel::close() +{ + socket->blockSignals(true); + socket->close(); + socket->blockSignals(false); + state = QHttpNetworkConnectionChannel::IdleState; +} + + +//private slots +void QHttpNetworkConnectionChannel::_q_readyRead() +{ + if (!socket) + return; // ### error + if (connection->d_func()->isSocketWaiting(socket) || connection->d_func()->isSocketReading(socket)) { + state = QHttpNetworkConnectionChannel::ReadingState; + if (reply) + connection->d_func()->receiveReply(socket, reply); + } + // ### error +} + +void QHttpNetworkConnectionChannel::_q_bytesWritten(qint64 bytes) +{ + Q_UNUSED(bytes); + if (!socket) + return; // ### error + // bytes have been written to the socket. write even more of them :) + if (connection->d_func()->isSocketWriting(socket)) + connection->d_func()->sendRequest(socket); + // otherwise we do nothing +} + +void QHttpNetworkConnectionChannel::_q_disconnected() +{ + if (!socket) + return; // ### error + // read the available data before closing + if (connection->d_func()->isSocketWaiting(socket) || connection->d_func()->isSocketReading(socket)) { + state = QHttpNetworkConnectionChannel::ReadingState; + if (reply) + connection->d_func()->receiveReply(socket, reply); + } else if (state == QHttpNetworkConnectionChannel::IdleState && resendCurrent) { + // re-sending request because the socket was in ClosingState + QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); + } + state = QHttpNetworkConnectionChannel::IdleState; +} + + +void QHttpNetworkConnectionChannel::_q_connected() +{ + if (!socket) + return; // ### error + + // improve performance since we get the request sent by the kernel ASAP + socket->setSocketOption(QAbstractSocket::LowDelayOption, 1); + + // ### FIXME: if the server closes the connection unexpectedly, we shouldn't send the same broken request again! + //channels[i].reconnectAttempts = 2; + if (!pendingEncrypt) { + state = QHttpNetworkConnectionChannel::IdleState; + if (reply) + connection->d_func()->sendRequest(socket); + else + close(); + } +} + + +void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socketError) +{ + if (!socket) + return; + bool send2Reply = false; + QNetworkReply::NetworkError errorCode = QNetworkReply::UnknownNetworkError; + + switch (socketError) { + case QAbstractSocket::HostNotFoundError: + errorCode = QNetworkReply::HostNotFoundError; + break; + case QAbstractSocket::ConnectionRefusedError: + errorCode = QNetworkReply::ConnectionRefusedError; + break; + case QAbstractSocket::RemoteHostClosedError: + // try to reconnect/resend before sending an error. + // while "Reading" the _q_disconnected() will handle this. + if (state != QHttpNetworkConnectionChannel::IdleState && state != QHttpNetworkConnectionChannel::ReadingState) { + if (reconnectAttempts-- > 0) { + connection->d_func()->resendCurrentRequest(socket); + return; + } else { + send2Reply = true; + errorCode = QNetworkReply::RemoteHostClosedError; + } + } else { + return; + } + break; + case QAbstractSocket::SocketTimeoutError: + // try to reconnect/resend before sending an error. + if (state == QHttpNetworkConnectionChannel::WritingState && (reconnectAttempts-- > 0)) { + connection->d_func()->resendCurrentRequest(socket); + return; + } + send2Reply = true; + errorCode = QNetworkReply::TimeoutError; + break; + case QAbstractSocket::ProxyAuthenticationRequiredError: + errorCode = QNetworkReply::ProxyAuthenticationRequiredError; + break; + case QAbstractSocket::SslHandshakeFailedError: + errorCode = QNetworkReply::SslHandshakeFailedError; + break; + default: + // all other errors are treated as NetworkError + errorCode = QNetworkReply::UnknownNetworkError; + break; + } + QPointer that = connection; + QString errorString = connection->d_func()->errorDetail(errorCode, socket); + if (send2Reply) { + if (reply) { + reply->d_func()->errorString = errorString; + // this error matters only to this reply + emit reply->finishedWithError(errorCode, errorString); + } + // send the next request + QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection); + } else { + // the failure affects all requests. + emit connection->error(errorCode, errorString); + } + if (that) //signal emission triggered event loop + close(); +} + +#ifndef QT_NO_NETWORKPROXY +void QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator* auth) +{ + emit connection->proxyAuthenticationRequired(proxy, auth, connection); +} +#endif + +void QHttpNetworkConnectionChannel::_q_uploadDataReadyRead() +{ + connection->d_func()->sendRequest(socket); +} + +#ifndef QT_NO_OPENSSL +void QHttpNetworkConnectionChannel::_q_encrypted() +{ + if (!socket) + return; // ### error + state = QHttpNetworkConnectionChannel::IdleState; + connection->d_func()->sendRequest(socket); +} + +void QHttpNetworkConnectionChannel::_q_sslErrors(const QList &errors) +{ + if (!socket) + return; + //QNetworkReply::NetworkError errorCode = QNetworkReply::ProtocolFailure; + emit connection->sslErrors(errors); +} +#endif + QT_END_NAMESPACE #include "moc_qhttpnetworkconnectionchannel_p.cpp" diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index cbabc67..013e7a5 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -80,6 +80,7 @@ QT_BEGIN_NAMESPACE class QHttpNetworkRequest; class QHttpNetworkReply; class QByteArray; +class QHttpNetworkConnection; class QHttpNetworkConnectionChannel : public QObject { Q_OBJECT @@ -117,7 +118,31 @@ public: #ifndef QT_NO_OPENSSL , ignoreAllSslErrors(false) #endif + , connection(0) {} + + void setConnection(QHttpNetworkConnection *c) {connection = c;} + QHttpNetworkConnection *connection; + + void init(); + void close(); + + protected slots: + void _q_bytesWritten(qint64 bytes); // proceed sending + void _q_readyRead(); // pending data to read + void _q_disconnected(); // disconnected from host + void _q_connected(); // start sending request + void _q_error(QAbstractSocket::SocketError); // error from socket +#ifndef QT_NO_NETWORKPROXY + void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); // from transparent proxy +#endif + + void _q_uploadDataReadyRead(); + +#ifndef QT_NO_OPENSSL + void _q_encrypted(); // start sending request (https) + void _q_sslErrors(const QList &errors); // ssl errors from the socket +#endif }; diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 575e824..a386b10 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -149,6 +149,7 @@ private: Q_DECLARE_PRIVATE(QHttpNetworkReply) friend class QHttpNetworkConnection; friend class QHttpNetworkConnectionPrivate; + friend class QHttpNetworkConnectionChannel; }; -- cgit v0.12 From 627c5c865d77cca1f0d6508f8facfe6c0bf4d363 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 4 Aug 2009 16:16:32 +0200 Subject: QNAM HTTP Code: Moved append() functions to the reply object Reviewed-by: TrustMe --- src/network/access/qhttpnetworkconnection.cpp | 35 +++------------------------ src/network/access/qhttpnetworkconnection_p.h | 4 --- src/network/access/qhttpnetworkreply.cpp | 30 +++++++++++++++++++++++ src/network/access/qhttpnetworkreply_p.h | 4 +++ 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index d73cd67..4c52545 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -129,35 +129,6 @@ bool QHttpNetworkConnectionPrivate::isSocketReading(QAbstractSocket *socket) con return (i != -1 && (channels[i].state & QHttpNetworkConnectionChannel::ReadingState)); } -void QHttpNetworkConnectionPrivate::appendUncompressedData(QHttpNetworkReply &reply, QByteArray &qba) -{ - reply.d_func()->responseData.append(qba); - - // clear the original! helps with implicit sharing and - // avoiding memcpy when the user is reading the data - qba.clear(); -} - -void QHttpNetworkConnectionPrivate::appendUncompressedData(QHttpNetworkReply &reply, QByteDataBuffer &data) -{ - reply.d_func()->responseData.append(data); - - // clear the original! helps with implicit sharing and - // avoiding memcpy when the user is reading the data - data.clear(); -} - -void QHttpNetworkConnectionPrivate::appendCompressedData(QHttpNetworkReply &reply, QByteDataBuffer &data) -{ - // Work in progress: Later we will directly use a list of QByteArray or a QRingBuffer - // instead of one QByteArray. - for(int i = 0; i < data.bufferCount(); i++) { - QByteArray &byteData = data[i]; - reply.d_func()->compressedData.append(byteData.constData(), byteData.size()); - } - data.clear(); -} - qint64 QHttpNetworkConnectionPrivate::uncompressedBytesAvailable(const QHttpNetworkReply &reply) const { return reply.d_func()->responseData.byteAmount(); @@ -517,7 +488,7 @@ bool QHttpNetworkConnectionPrivate::expand(QAbstractSocket *socket, QHttpNetwork if (ret >= retCheck) { if (inflated.size()) { reply->d_func()->totalProgress += inflated.size(); - appendUncompressedData(*reply, inflated); + reply->d_func()->appendUncompressedReplyData(inflated); if (shouldEmitSignals(reply)) { // important: At the point of this readyRead(), inflated must be cleared, // else implicit sharing will trigger memcpy when the user is reading data! @@ -638,9 +609,9 @@ void QHttpNetworkConnectionPrivate::receiveReply(QAbstractSocket *socket, QHttpN bytes = reply->d_func()->readBody(socket, &byteDatas); if (bytes) { if (reply->d_func()->autoDecompress) - appendCompressedData(*reply, byteDatas); + reply->d_func()->appendCompressedReplyData(byteDatas); else - appendUncompressedData(*reply, byteDatas); + reply->d_func()->appendUncompressedReplyData(byteDatas); if (!reply->d_func()->autoDecompress) { reply->d_func()->totalProgress += bytes; diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 48401d2..d6b0325 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -197,10 +197,6 @@ public: bool pendingAuthSignal; // there is an incomplete authentication signal bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal - void appendUncompressedData(QHttpNetworkReply &reply, QByteArray &qba); - void appendUncompressedData(QHttpNetworkReply &reply, QByteDataBuffer &data); - void appendCompressedData(QHttpNetworkReply &reply, QByteDataBuffer &data); - qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const; qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const; qint64 compressedBytesAvailable(const QHttpNetworkReply &reply) const; diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index a623999..f40f7bf 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -687,6 +687,36 @@ qint64 QHttpNetworkReplyPrivate::getChunkSize(QIODevice *in, qint64 *chunkSize) return bytes; } +void QHttpNetworkReplyPrivate::appendUncompressedReplyData(QByteArray &qba) +{ + responseData.append(qba); + + // clear the original! helps with implicit sharing and + // avoiding memcpy when the user is reading the data + qba.clear(); +} + +void QHttpNetworkReplyPrivate::appendUncompressedReplyData(QByteDataBuffer &data) +{ + responseData.append(data); + + // clear the original! helps with implicit sharing and + // avoiding memcpy when the user is reading the data + data.clear(); +} + +void QHttpNetworkReplyPrivate::appendCompressedReplyData(QByteDataBuffer &data) +{ + // Work in progress: Later we will directly use a list of QByteArray or a QRingBuffer + // instead of one QByteArray. + for(int i = 0; i < data.bufferCount(); i++) { + QByteArray &byteData = data[i]; + compressedData.append(byteData.constData(), byteData.size()); + } + data.clear(); +} + + // SSL support below #ifndef QT_NO_OPENSSL diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index a386b10..fe49799 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -172,6 +172,10 @@ public: qint64 readReplyBodyChunked(QIODevice *in, QByteDataBuffer *out); qint64 getChunkSize(QIODevice *in, qint64 *chunkSize); + void appendUncompressedReplyData(QByteArray &qba); + void appendUncompressedReplyData(QByteDataBuffer &data); + void appendCompressedReplyData(QByteDataBuffer &data); + qint64 bytesAvailable() const; bool isChunked(); bool connectionCloseEnabled(); -- cgit v0.12 From fbee62af06ebe2c8cf6da1cc18a665c69c64eff7 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 3 Aug 2009 15:04:43 +0200 Subject: Renamed internal WinGesture event to NativeGesture. It will also be used on Mac, so it doesn't make sense to keep it windows specific. Reviewed-by: trustme --- src/corelib/kernel/qcoreevent.cpp | 2 +- src/corelib/kernel/qcoreevent.h | 2 +- src/gui/kernel/qapplication.cpp | 2 +- src/gui/kernel/qapplication_win.cpp | 10 +++++----- src/gui/kernel/qevent.cpp | 1 - src/gui/kernel/qevent_p.h | 13 +++++++++++-- src/gui/kernel/qwidget.cpp | 16 ++++++++-------- 7 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index a682fad9..ff00c1c 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -269,7 +269,7 @@ QT_BEGIN_NAMESPACE \omitvalue FutureCallOut \omitvalue CocoaRequestModal \omitvalue Signal - \omitvalue WinGesture + \omitvalue NativeGesture */ /*! diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 1d86f47..d941286 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -276,7 +276,7 @@ public: TouchUpdate = 195, TouchEnd = 196, - WinGesture = 197, + NativeGesture = 197, // Internal for platform gesture support // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index e210556..c24ff49 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -4052,7 +4052,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) touchEvent->setAccepted(eventAccepted); break; } - case QEvent::WinGesture: + case QEvent::NativeGesture: { // only propagate the first gesture event (after the GID_BEGIN) QWidget *w = static_cast(receiver); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index d5c820c..3b5c0c3 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -3735,7 +3735,7 @@ bool QETWidget::translateGestureEvent(const MSG &msg) alienWidget = 0; QWidget *widget = alienWidget ? alienWidget : this; - QWinGestureEvent event; + QNativeGestureEvent event; event.sequenceId = gi.dwSequenceID; event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); if (bResult) { @@ -3744,13 +3744,13 @@ bool QETWidget::translateGestureEvent(const MSG &msg) // we are not interested in this type of event. break; case GID_END: - event.gestureType = QWinGestureEvent::GestureEnd; + event.gestureType = QNativeGestureEvent::GestureEnd; break; case GID_ZOOM: - event.gestureType = QWinGestureEvent::Pinch; + event.gestureType = QNativeGestureEvent::Pinch; break; case GID_PAN: - event.gestureType = QWinGestureEvent::Pan; + event.gestureType = QNativeGestureEvent::Pan; break; case GID_ROTATE: case GID_TWOFINGERTAP: @@ -3758,7 +3758,7 @@ bool QETWidget::translateGestureEvent(const MSG &msg) default: break; } - if (event.gestureType != QWinGestureEvent::None) + if (event.gestureType != QNativeGestureEvent::None) qt_sendSpontaneousEvent(widget, &event); } else { DWORD dwErr = GetLastError(); diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index bc3633c..0fc36e7 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -49,7 +49,6 @@ #include "qmime.h" #include "qdnd_p.h" #include "qevent_p.h" -#include "qgesture.h" QT_BEGIN_NAMESPACE diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index 67441ea..940e587 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -119,7 +119,7 @@ public: qreal pressure; }; -class QWinGestureEvent : public QEvent +class QNativeGestureEvent : public QEvent { public: enum Type { @@ -129,10 +129,19 @@ public: Pinch }; - QWinGestureEvent() : QEvent(QEvent::WinGesture), gestureType(None), sequenceId(0) { } + QNativeGestureEvent() + : QEvent(QEvent::NativeGesture), gestureType(None) +#ifdef Q_WS_WIN + , sequenceId(0) +#endif + { + } + Type gestureType; +#ifdef Q_WS_WIN QPoint position; ulong sequenceId; +#endif }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 43ac37d..5400146 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -7941,8 +7941,8 @@ bool QWidget::event(QEvent *event) break; } #ifdef Q_WS_WIN - case QEvent::WinGesture: { - QWinGestureEvent *ev = static_cast(event); + case QEvent::NativeGesture: { + QNativeGestureEvent *ev = static_cast(event); QApplicationPrivate *qAppPriv = qApp->d_func(); QApplicationPrivate::WidgetStandardGesturesMap::iterator it; it = qAppPriv->widgetGestures.find(this); @@ -7950,15 +7950,15 @@ bool QWidget::event(QEvent *event) Qt::GestureState state = Qt::GestureUpdated; if (qAppPriv->lastGestureId == 0) state = Qt::GestureStarted; - QWinGestureEvent::Type type = ev->gestureType; - if (ev->gestureType == QWinGestureEvent::GestureEnd) { - type = (QWinGestureEvent::Type)qAppPriv->lastGestureId; + QNativeGestureEvent::Type type = ev->gestureType; + if (ev->gestureType == QNativeGestureEvent::GestureEnd) { + type = (QNativeGestureEvent::Type)qAppPriv->lastGestureId; state = Qt::GestureFinished; } QGesture *gesture = 0; switch (type) { - case QWinGestureEvent::Pan: { + case QNativeGestureEvent::Pan: { QPanGesture *pan = it.value().pan; gesture = pan; if (state == Qt::GestureStarted) { @@ -7970,7 +7970,7 @@ bool QWidget::event(QEvent *event) gesture->setPos(ev->position); break; } - case QWinGestureEvent::Pinch: + case QNativeGestureEvent::Pinch: break; default: break; @@ -7984,7 +7984,7 @@ bool QWidget::event(QEvent *event) emit gesture->finished(); event->accept(); } - if (ev->gestureType == QWinGestureEvent::GestureEnd) { + if (ev->gestureType == QNativeGestureEvent::GestureEnd) { qAppPriv->lastGestureId = 0; } else { qAppPriv->lastGestureId = type; -- cgit v0.12 From 6e7a6478279a94a82af46e6814f113244aca46dd Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 3 Aug 2009 18:24:44 +0200 Subject: Moved the native window gesture handling code to the right place. --- src/gui/kernel/qapplication_win.cpp | 2 +- src/gui/kernel/qevent_p.h | 1 + src/gui/kernel/qstandardgestures.cpp | 124 +++++++++++++++++++++++++++++------ src/gui/kernel/qstandardgestures.h | 7 +- src/gui/kernel/qstandardgestures_p.h | 11 +++- src/gui/kernel/qwidget.cpp | 53 --------------- 6 files changed, 121 insertions(+), 77 deletions(-) diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 3b5c0c3..2bded5c 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -3741,7 +3741,7 @@ bool QETWidget::translateGestureEvent(const MSG &msg) if (bResult) { switch (gi.dwID) { case GID_BEGIN: - // we are not interested in this type of event. + event.gestureType = QNativeGestureEvent::GestureBegin; break; case GID_END: event.gestureType = QNativeGestureEvent::GestureEnd; diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index 940e587..92c4fc1 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -124,6 +124,7 @@ class QNativeGestureEvent : public QEvent public: enum Type { None, + GestureBegin, GestureEnd, Pan, Pinch diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index c4820f0..1fbfe15 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -45,9 +45,14 @@ #include #include #include +#include QT_BEGIN_NAMESPACE +#ifdef Q_WS_WIN +QApplicationPrivate* getQApplicationPrivateInternal(); +#endif + /*! \class QPanGesture \since 4.6 @@ -68,15 +73,10 @@ QPanGesture::QPanGesture(QWidget *parent) { #ifdef Q_WS_WIN if (parent) { - QApplicationPrivate* getQApplicationPrivateInternal(); QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); qAppPriv->widgetGestures[parent].pan = this; } #endif - -#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) - d_func()->panFinishedTimer = 0; -#endif } /*! \internal */ @@ -116,6 +116,62 @@ bool QPanGesture::event(QEvent *event) return QObject::event(event); } +bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) +{ +#ifdef Q_WS_WIN + if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) { + QNativeGestureEvent *ev = static_cast(event); + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + QApplicationPrivate::WidgetStandardGesturesMap::iterator it; + it = qAppPriv->widgetGestures.find(static_cast(receiver)); + if (it == qAppPriv->widgetGestures.end()) + return false; + QPanGesture *gesture = it.value().pan; + if (!gesture) + return false; + Qt::GestureState nextState = state(); + switch(ev->gestureType) { + case QNativeGestureEvent::GestureBegin: + // next we might receive the first gesture update event, so we + // prepare for it. + setState(Qt::GestureStarted); + return false; + case QNativeGestureEvent::Pan: + nextState = Qt::GestureUpdated; + break; + case QNativeGestureEvent::GestureEnd: + if (state() != QNativeGestureEvent::Pan) + return false; // some other gesture has ended + setState(Qt::GestureFinished); + nextState = Qt::GestureFinished; + break; + default: + return false; + } + QPanGesturePrivate *d = gesture->d_func(); + if (state() == Qt::GestureStarted) { + d->lastPosition = ev->position; + d->lastOffset = d->totalOffset = QSize(); + } else { + d->lastOffset = QSize(ev->position.x() - d->lastPosition.x(), + ev->position.y() - d->lastPosition.y()); + d->totalOffset += d->lastOffset; + } + d->lastPosition = ev->position; + + if (state() == Qt::GestureStarted) + emit gesture->started(); + emit gesture->triggered(); + if (state() == Qt::GestureFinished) + emit gesture->finished(); + event->accept(); + gesture->setState(nextState); + return true; + } +#endif + return QGesture::eventFilter(receiver, event); +} + /*! \internal */ bool QPanGesture::filterEvent(QEvent *event) { @@ -124,28 +180,34 @@ bool QPanGesture::filterEvent(QEvent *event) return false; const QTouchEvent *ev = static_cast(event); if (event->type() == QEvent::TouchBegin) { - d->touchPoints = ev->touchPoints(); - const QPoint p = ev->touchPoints().at(0).pos().toPoint(); - setStartPos(p); - setLastPos(p); - setPos(p); - return false; + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + d->lastPosition = p.pos().toPoint(); + d->lastOffset = d->totalOffset = QSize(); } else if (event->type() == QEvent::TouchEnd) { if (state() != Qt::NoGesture) { setState(Qt::GestureFinished); - setLastPos(pos()); - setPos(ev->touchPoints().at(0).pos().toPoint()); + if (!ev->touchPoints().isEmpty()) { + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + const QPoint pos = p.pos().toPoint(); + const QPoint lastPos = p.lastPos().toPoint(); + const QPoint startPos = p.startPos().toPoint(); + d->lastOffset = QSize(pos.x() - lastPos.x(), pos.y() - lastPos.y()); + d->totalOffset = QSize(pos.x() - startPos.x(), pos.y() - startPos.y()); + } emit triggered(); emit finished(); } setState(Qt::NoGesture); reset(); } else if (event->type() == QEvent::TouchUpdate) { - d->touchPoints = ev->touchPoints(); - QPointF pt = d->touchPoints.at(0).pos() - d->touchPoints.at(0).startPos(); - setLastPos(pos()); - setPos(ev->touchPoints().at(0).pos().toPoint()); - if (pt.x() > 10 || pt.y() > 10 || pt.x() < -10 || pt.y() < -10) { + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + const QPoint pos = p.pos().toPoint(); + const QPoint lastPos = p.lastPos().toPoint(); + const QPoint startPos = p.startPos().toPoint(); + d->lastOffset = QSize(pos.x() - lastPos.x(), pos.y() - lastPos.y()); + d->totalOffset = QSize(pos.x() - startPos.x(), pos.y() - startPos.y()); + if (d->totalOffset.width() > 10 || d->totalOffset.height() > 10 || + d->totalOffset.width() < -10 || d->totalOffset.height() < -10) { if (state() == Qt::NoGesture) setState(Qt::GestureStarted); else @@ -190,7 +252,14 @@ bool QPanGesture::filterEvent(QEvent *event) void QPanGesture::reset() { Q_D(QPanGesture); - d->touchPoints.clear(); + d->lastOffset = d->totalOffset = QSize(); + d->lastPosition = QPoint(); +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + if (d->panFinishedTimer) { + killTimer(d->panFinishedTimer); + d->panFinishedTimer = 0; + } +#endif } /*! @@ -226,6 +295,23 @@ QSize QPanGesture::lastOffset() const #endif } +QPoint QPanGesture::startPos() const +{ + Q_D(const QPanGesture); + return d->startPos; +} +QPoint QPanGesture::lastPos() const +{ + Q_D(const QPanGesture); + return d->lastPos; +} + +QPoint QPanGesture::pos() const +{ + Q_D(const QPanGesture); + return d->pos; +} + /*! \class QTapAndHoldGesture \since 4.6 diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h index 2234702..030aac8 100644 --- a/src/gui/kernel/qstandardgestures.h +++ b/src/gui/kernel/qstandardgestures.h @@ -70,11 +70,14 @@ public: QSize totalOffset() const; QSize lastOffset() const; + QPoint startPos() const; + QPoint lastPos() const; + QPoint pos() const; -protected: +private: bool event(QEvent *event); + bool eventFilter(QObject *receiver, QEvent *event); -private: friend class QWidget; }; diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index 0fd42bd..dd4fbc0 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -60,6 +60,8 @@ #include "qgesture.h" #include "qgesture_p.h" +#include "qstandardgestures.h" + QT_BEGIN_NAMESPACE class QPanGesturePrivate : public QGesturePrivate @@ -67,11 +69,16 @@ class QPanGesturePrivate : public QGesturePrivate Q_DECLARE_PUBLIC(QPanGesture) public: - QPanGesturePrivate() { } + QPanGesturePrivate() + { +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + panFinishedTimer = 0; +#endif + } - QList touchPoints; QSize totalOffset; QSize lastOffset; + QPoint lastPosition; #if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) int panFinishedTimer; diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 5400146..765b26f 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -7940,59 +7940,6 @@ bool QWidget::event(QEvent *event) (void) QApplication::sendEvent(this, &mouseEvent); break; } -#ifdef Q_WS_WIN - case QEvent::NativeGesture: { - QNativeGestureEvent *ev = static_cast(event); - QApplicationPrivate *qAppPriv = qApp->d_func(); - QApplicationPrivate::WidgetStandardGesturesMap::iterator it; - it = qAppPriv->widgetGestures.find(this); - if (it != qAppPriv->widgetGestures.end()) { - Qt::GestureState state = Qt::GestureUpdated; - if (qAppPriv->lastGestureId == 0) - state = Qt::GestureStarted; - QNativeGestureEvent::Type type = ev->gestureType; - if (ev->gestureType == QNativeGestureEvent::GestureEnd) { - type = (QNativeGestureEvent::Type)qAppPriv->lastGestureId; - state = Qt::GestureFinished; - } - - QGesture *gesture = 0; - switch (type) { - case QNativeGestureEvent::Pan: { - QPanGesture *pan = it.value().pan; - gesture = pan; - if (state == Qt::GestureStarted) { - gesture->setStartPos(ev->position); - gesture->setLastPos(ev->position); - } else { - gesture->setLastPos(gesture->pos()); - } - gesture->setPos(ev->position); - break; - } - case QNativeGestureEvent::Pinch: - break; - default: - break; - } - if (gesture) { - gesture->setState(state); - if (state == Qt::GestureStarted) - emit gesture->started(); - emit gesture->triggered(); - if (state == Qt::GestureFinished) - emit gesture->finished(); - event->accept(); - } - if (ev->gestureType == QNativeGestureEvent::GestureEnd) { - qAppPriv->lastGestureId = 0; - } else { - qAppPriv->lastGestureId = type; - } - } - break; - } -#endif #ifndef QT_NO_PROPERTIES case QEvent::DynamicPropertyChange: { const QByteArray &propName = static_cast(event)->propertyName(); -- cgit v0.12 From 6b85ec8790aad8ac01c04f7e7bd4913d8cd8d104 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 3 Aug 2009 17:02:58 +0200 Subject: Removed the QTapAndHoldGesture Moved the gesture implementation to the imageviewer example as it cannot be fully implemented in a crossplatform way - for example on Windows tap and hold is a system gesture that is transparent to the application. Reviewed-by: trustme --- examples/gestures/imageviewer/imageviewer.pro | 11 +-- examples/gestures/imageviewer/imagewidget.cpp | 15 ++- examples/gestures/imageviewer/imagewidget.h | 4 +- .../gestures/imageviewer/tapandholdgesture.cpp | 97 ++++++++++++++++++++ examples/gestures/imageviewer/tapandholdgesture.h | 32 +++++++ src/gui/kernel/qstandardgestures.cpp | 101 ++++----------------- src/gui/kernel/qstandardgestures.h | 16 ---- src/gui/kernel/qstandardgestures_p.h | 14 --- 8 files changed, 167 insertions(+), 123 deletions(-) create mode 100644 examples/gestures/imageviewer/tapandholdgesture.cpp create mode 100644 examples/gestures/imageviewer/tapandholdgesture.h diff --git a/examples/gestures/imageviewer/imageviewer.pro b/examples/gestures/imageviewer/imageviewer.pro index 4c35dce..efbca00 100644 --- a/examples/gestures/imageviewer/imageviewer.pro +++ b/examples/gestures/imageviewer/imageviewer.pro @@ -1,12 +1,11 @@ -###################################################################### -# Automatically generated by qmake (2.01a) Thu Sep 11 17:18:17 2008 -###################################################################### - TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . # Input -HEADERS += imagewidget.h -SOURCES += imagewidget.cpp main.cpp +HEADERS += imagewidget.h \ + tapandholdgesture.h +SOURCES += imagewidget.cpp \ + tapandholdgesture.cpp \ + main.cpp diff --git a/examples/gestures/imageviewer/imagewidget.cpp b/examples/gestures/imageviewer/imagewidget.cpp index 0b39997..99889ed 100644 --- a/examples/gestures/imageviewer/imagewidget.cpp +++ b/examples/gestures/imageviewer/imagewidget.cpp @@ -65,7 +65,7 @@ ImageWidget::ImageWidget(QWidget *parent) panGesture = new QPanGesture(this); connect(panGesture, SIGNAL(triggered()), this, SLOT(gestureTriggered())); - tapAndHoldGesture = new QTapAndHoldGesture(this); + tapAndHoldGesture = new TapAndHoldGesture(this); connect(tapAndHoldGesture, SIGNAL(triggered()), this, SLOT(gestureTriggered())); } @@ -188,6 +188,19 @@ void ImageWidget::gestureTriggered() } } feedbackFadeOutTimer.start(500, this); + } else if (sender() == tapAndHoldGesture) { + if (tapAndHoldGesture->state() == Qt::GestureFinished) { + qDebug() << "tap and hold detected"; + touchFeedback.reset(); + update(); + + QMenu menu; + menu.addAction("Action 1"); + menu.addAction("Action 2"); + menu.addAction("Action 3"); + menu.exec(mapToGlobal(tapAndHoldGesture->pos())); + } + feedbackFadeOutTimer.start(500, this); } } diff --git a/examples/gestures/imageviewer/imagewidget.h b/examples/gestures/imageviewer/imagewidget.h index e12634d..d8d5f8d 100644 --- a/examples/gestures/imageviewer/imagewidget.h +++ b/examples/gestures/imageviewer/imagewidget.h @@ -48,6 +48,8 @@ #include +#include "tapandholdgesture.h" + class ImageWidget : public QWidget { Q_OBJECT @@ -79,7 +81,7 @@ private: void goToImage(int index); QPanGesture *panGesture; - QTapAndHoldGesture *tapAndHoldGesture; + TapAndHoldGesture *tapAndHoldGesture; QString path; QStringList files; diff --git a/examples/gestures/imageviewer/tapandholdgesture.cpp b/examples/gestures/imageviewer/tapandholdgesture.cpp new file mode 100644 index 0000000..c6f6779 --- /dev/null +++ b/examples/gestures/imageviewer/tapandholdgesture.cpp @@ -0,0 +1,97 @@ +#include "tapandholdgesture.h" + +#include + +/*! + \class TapAndHoldGesture + \since 4.6 + + \brief The TapAndHoldGesture class represents a Tap-and-Hold gesture, + providing additional information. +*/ + +const int TapAndHoldGesture::iterationCount = 40; +const int TapAndHoldGesture::iterationTimeout = 50; + +/*! + Creates a new Tap and Hold gesture handler object and marks it as a child + of \a parent. + + On some platforms like Windows there is a system-wide tap and hold gesture + that cannot be overriden, hence the gesture might never trigger and default + context menu will be shown instead. +*/ +TapAndHoldGesture::TapAndHoldGesture(QWidget *parent) + : QGesture(parent), iteration(0) +{ +} + +/*! \internal */ +bool TapAndHoldGesture::filterEvent(QEvent *event) +{ + if (!event->spontaneous()) + return false; + const QTouchEvent *ev = static_cast(event); + switch (event->type()) { + case QEvent::TouchBegin: { + if (timer.isActive()) + timer.stop(); + timer.start(TapAndHoldGesture::iterationTimeout, this); + const QPoint p = ev->touchPoints().at(0).pos().toPoint(); + position = p; + break; + } + case QEvent::TouchUpdate: + if (ev->touchPoints().size() == 1) { + const QPoint startPos = ev->touchPoints().at(0).startPos().toPoint(); + const QPoint pos = ev->touchPoints().at(0).pos().toPoint(); + if ((startPos - pos).manhattanLength() > 15) + reset(); + } else { + reset(); + } + break; + case QEvent::TouchEnd: + reset(); + break; + default: + break; + } + return false; +} + +/*! \internal */ +void TapAndHoldGesture::timerEvent(QTimerEvent *event) +{ + if (event->timerId() != timer.timerId()) + return; + if (iteration == TapAndHoldGesture::iterationCount) { + timer.stop(); + setState(Qt::GestureFinished); + emit triggered(); + } else { + setState(Qt::GestureStarted); + emit triggered(); + } + ++iteration; +} + +/*! \internal */ +void TapAndHoldGesture::reset() +{ + if (state() != Qt::NoGesture) + emit cancelled(); + setState(Qt::NoGesture); + timer.stop(); + iteration = 0; +} + +/*! + \property TapAndHoldGesture::pos + + \brief The position of the gesture. +*/ +QPoint TapAndHoldGesture::pos() const +{ + return position; +} diff --git a/examples/gestures/imageviewer/tapandholdgesture.h b/examples/gestures/imageviewer/tapandholdgesture.h new file mode 100644 index 0000000..711a1af --- /dev/null +++ b/examples/gestures/imageviewer/tapandholdgesture.h @@ -0,0 +1,32 @@ +#ifndef TAPANDHOLDGESTURE_H +#define TAPANDHOLDGESTURE_H + +#include +#include +#include + +class TapAndHoldGesture : public QGesture +{ + Q_OBJECT + Q_PROPERTY(QPoint pos READ pos) + +public: + TapAndHoldGesture(QWidget *parent); + + bool filterEvent(QEvent *event); + void reset(); + + QPoint pos() const; + +protected: + void timerEvent(QTimerEvent *event); + +private: + QBasicTimer timer; + int iteration; + QPoint position; + static const int iterationCount; + static const int iterationTimeout; +}; + +#endif // TAPANDHOLDGESTURE_H diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index 1fbfe15..e4b9abb 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -295,106 +295,37 @@ QSize QPanGesture::lastOffset() const #endif } +/*! + \property QPanGesture::startPos + + \brief The start position of the gesture. +*/ QPoint QPanGesture::startPos() const { Q_D(const QPanGesture); return d->startPos; } + +/*! + \property QPanGesture::lastPos + + \brief The last recorded position of the gesture. +*/ QPoint QPanGesture::lastPos() const { Q_D(const QPanGesture); return d->lastPos; } -QPoint QPanGesture::pos() const -{ - Q_D(const QPanGesture); - return d->pos; -} - /*! - \class QTapAndHoldGesture - \since 4.6 - - \brief The QTapAndHoldGesture class represents a Tap-and-Hold gesture, - providing additional information. -*/ - -const int QTapAndHoldGesturePrivate::iterationCount = 40; -const int QTapAndHoldGesturePrivate::iterationTimeout = 50; - -/*! - Creates a new Tap and Hold gesture handler object and marks it as a child - of \a parent. + \property QPanGesture::pos - On some platforms like Windows there is a system-wide tap and hold gesture - that cannot be overriden, hence the gesture might never trigger and default - context menu will be shown instead. + \brief The current position of the gesture. */ -QTapAndHoldGesture::QTapAndHoldGesture(QWidget *parent) - : QGesture(*new QTapAndHoldGesturePrivate, parent) -{ -} - -/*! \internal */ -bool QTapAndHoldGesture::filterEvent(QEvent *event) -{ - Q_D(QTapAndHoldGesture); - if (!event->spontaneous()) - return false; - const QTouchEvent *ev = static_cast(event); - switch (event->type()) { - case QEvent::TouchBegin: { - if (d->timer.isActive()) - d->timer.stop(); - d->timer.start(QTapAndHoldGesturePrivate::iterationTimeout, this); - const QPoint p = ev->touchPoints().at(0).pos().toPoint(); - setStartPos(p); - setLastPos(p); - setPos(p); - break; - } - case QEvent::TouchUpdate: - if (ev->touchPoints().size() != 1) - reset(); - else if ((startPos() - ev->touchPoints().at(0).pos().toPoint()).manhattanLength() > 15) - reset(); - break; - case QEvent::TouchEnd: - reset(); - break; - default: - break; - } - return false; -} - -/*! \internal */ -void QTapAndHoldGesture::timerEvent(QTimerEvent *event) -{ - Q_D(QTapAndHoldGesture); - if (event->timerId() != d->timer.timerId()) - return; - if (d->iteration == QTapAndHoldGesturePrivate::iterationCount) { - d->timer.stop(); - setState(Qt::GestureFinished); - emit triggered(); - } else { - setState(Qt::GestureStarted); - emit triggered(); - } - ++d->iteration; -} - -/*! \internal */ -void QTapAndHoldGesture::reset() +QPoint QPanGesture::pos() const { - Q_D(QTapAndHoldGesture); - if (state() != Qt::NoGesture) - emit cancelled(); - setState(Qt::NoGesture); - d->timer.stop(); - d->iteration = 0; + Q_D(const QPanGesture); + return d->pos; } QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h index 030aac8..c6f6d9b 100644 --- a/src/gui/kernel/qstandardgestures.h +++ b/src/gui/kernel/qstandardgestures.h @@ -81,22 +81,6 @@ private: friend class QWidget; }; -class QTapAndHoldGesturePrivate; -class Q_GUI_EXPORT QTapAndHoldGesture : public QGesture -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QTapAndHoldGesture) - -public: - QTapAndHoldGesture(QWidget *parent); - - bool filterEvent(QEvent *event); - void reset(); - -protected: - void timerEvent(QTimerEvent *event); -}; - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index dd4fbc0..0fe24ee 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -85,20 +85,6 @@ public: #endif }; -class QTapAndHoldGesturePrivate : public QGesturePrivate -{ - Q_DECLARE_PUBLIC(QTapAndHoldGesture) - -public: - QTapAndHoldGesturePrivate() - : iteration(0) { } - - QBasicTimer timer; - int iteration; - static const int iterationCount; - static const int iterationTimeout; -}; - QT_END_NAMESPACE #endif // QSTANDARDGESTURES_P_H -- cgit v0.12 From 47c191d3c6b9c3fbe062068167888bed434ab6e2 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 4 Aug 2009 13:37:35 +0200 Subject: Removed the startPos/lastPos/pos from the gesture classes. It doesn't make much sense to have that low-level info neither in the base QGesture class, nor in the QPanGesture, as the latter one has offset properties instead. Reviewed-by: trustme --- src/gui/kernel/qgesture.cpp | 45 ------------------------------------ src/gui/kernel/qgesture.h | 14 ++--------- src/gui/kernel/qgesture_p.h | 11 --------- src/gui/kernel/qstandardgestures.cpp | 43 ---------------------------------- src/gui/kernel/qstandardgestures.h | 3 --- src/gui/widgets/qtextedit.cpp | 8 +++---- 6 files changed, 6 insertions(+), 118 deletions(-) diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index 1f98013..32ac4f8 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -205,51 +205,6 @@ void QGesture::setState(Qt::GestureState state) } /*! - \property QGesture::startPos - - \brief The start position of the gesture (if relevant). -*/ -QPoint QGesture::startPos() const -{ - return d_func()->startPos; -} - -void QGesture::setStartPos(const QPoint &point) -{ - d_func()->startPos = point; -} - -/*! - \property QGesture::lastPos - - \brief The last recorded position of the gesture (if relevant). -*/ -QPoint QGesture::lastPos() const -{ - return d_func()->lastPos; -} - -void QGesture::setLastPos(const QPoint &point) -{ - d_func()->lastPos = point; -} - -/*! - \property QGesture::pos - - \brief The current position of the gesture (if relevant). -*/ -QPoint QGesture::pos() const -{ - return d_func()->pos; -} - -void QGesture::setPos(const QPoint &point) -{ - d_func()->pos = point; -} - -/*! Sets the \a graphicsItem the gesture is filtering events for. The gesture will install an event filter to the \a graphicsItem and diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index 1cd9cae..0735160 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -64,10 +64,6 @@ class Q_GUI_EXPORT QGesture : public QObject Q_PROPERTY(Qt::GestureState state READ state) - Q_PROPERTY(QPoint startPos READ startPos WRITE setStartPos) - Q_PROPERTY(QPoint lastPos READ lastPos WRITE setLastPos) - Q_PROPERTY(QPoint pos READ pos WRITE setPos) - public: explicit QGesture(QObject *parent = 0); ~QGesture(); @@ -80,19 +76,13 @@ public: virtual void reset(); Qt::GestureState state() const; - void setState(Qt::GestureState state); - - QPoint startPos() const; - void setStartPos(const QPoint &point); - QPoint lastPos() const; - void setLastPos(const QPoint &point); - QPoint pos() const; - void setPos(const QPoint &point); protected: QGesture(QGesturePrivate &dd, QObject *parent); bool eventFilter(QObject*, QEvent*); + void setState(Qt::GestureState state); + Q_SIGNALS: void started(); void triggered(); diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index 99f572f..56eaee7 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -73,22 +73,11 @@ public: { } - void init(const QPoint &startPos, const QPoint &lastPos, - const QPoint &pos) - { - this->startPos = startPos; - this->lastPos = lastPos; - this->pos = pos; - } QGraphicsItem *graphicsItem; QGraphicsItem *eventFilterProxyGraphicsItem; Qt::GestureState state; - - QPoint startPos; - QPoint lastPos; - QPoint pos; }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index e4b9abb..4753416 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -269,13 +269,8 @@ void QPanGesture::reset() */ QSize QPanGesture::totalOffset() const { -#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) Q_D(const QPanGesture); return d->totalOffset; -#else - QPoint pt = pos() - startPos(); - return QSize(pt.x(), pt.y()); -#endif } /*! @@ -286,46 +281,8 @@ QSize QPanGesture::totalOffset() const */ QSize QPanGesture::lastOffset() const { -#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) Q_D(const QPanGesture); return d->lastOffset; -#else - QPoint pt = pos() - lastPos(); - return QSize(pt.x(), pt.y()); -#endif -} - -/*! - \property QPanGesture::startPos - - \brief The start position of the gesture. -*/ -QPoint QPanGesture::startPos() const -{ - Q_D(const QPanGesture); - return d->startPos; -} - -/*! - \property QPanGesture::lastPos - - \brief The last recorded position of the gesture. -*/ -QPoint QPanGesture::lastPos() const -{ - Q_D(const QPanGesture); - return d->lastPos; -} - -/*! - \property QPanGesture::pos - - \brief The current position of the gesture. -*/ -QPoint QPanGesture::pos() const -{ - Q_D(const QPanGesture); - return d->pos; } QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h index c6f6d9b..c734fba 100644 --- a/src/gui/kernel/qstandardgestures.h +++ b/src/gui/kernel/qstandardgestures.h @@ -70,9 +70,6 @@ public: QSize totalOffset() const; QSize lastOffset() const; - QPoint startPos() const; - QPoint lastPos() const; - QPoint pos() const; private: bool event(QEvent *event); diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index e80df92..c095f5c 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -2625,12 +2625,12 @@ void QTextEditPrivate::_q_gestureTriggered() return; QScrollBar *hBar = q->horizontalScrollBar(); QScrollBar *vBar = q->verticalScrollBar(); - QPoint delta = g->pos() - (g->lastPos().isNull() ? g->pos() : g->lastPos()); + QSize delta = g->lastOffset(); if (!delta.isNull()) { if (QApplication::isRightToLeft()) - delta.rx() *= -1; - int newX = hBar->value() - delta.x(); - int newY = vBar->value() - delta.y(); + delta.rwidth() *= -1; + int newX = hBar->value() - delta.width(); + int newY = vBar->value() - delta.height(); hbar->setValue(newX); vbar->setValue(newY); } -- cgit v0.12 From 6d9143ebffc10a58d8d62e57e3378adae4af92cd Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 4 Aug 2009 10:37:39 +0200 Subject: Don't try to make direct system calls on Linux. Accept that we cannot do everything, so users using outdated toolchains may have threading problems (leaking file descriptors). It's not like this is a recent problem anyway... Reviewed-By: Bradley T. Hughes --- src/corelib/kernel/qcore_unix.cpp | 73 --------------------------------------- src/corelib/kernel/qcore_unix_p.h | 34 +++++------------- src/network/socket/qnet_unix_p.h | 2 +- 3 files changed, 10 insertions(+), 99 deletions(-) diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp index b57d385..efa9c6d 100644 --- a/src/corelib/kernel/qcore_unix.cpp +++ b/src/corelib/kernel/qcore_unix.cpp @@ -161,76 +161,3 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, } QT_END_NAMESPACE - -#ifdef Q_OS_LINUX -// Don't wait for libc to supply the calls we need -// Make syscalls directly - -# if defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 -// glibc 2.4 has syscall(...) -# include -# include -# else -// no syscall(...) -static inline int syscall(...) { errno = ENOSYS; return -1;} -# endif - -# ifndef __NR_dup3 -# if defined(__i386__) -# define __NR_dup3 330 -# define __NR_pipe2 331 -# elif defined(__x86_64__) -# define __NR_dup3 292 -# define __NR_pipe2 293 -# elif defined(__ia64__) -# define __NR_dup3 1316 -# define __NR_pipe2 1317 -# else -// set the syscalls to absurd numbers so that they'll cause ENOSYS errors -# warning "Please port the pipe2/dup3 code to this platform" -# define __NR_dup3 -1 -# define __NR_pipe2 -1 -# endif -# endif - -# if !defined(__NR_socketcall) && !defined(__NR_accept4) -# if defined(__x86_64__) -# define __NR_accept4 288 -# elif defined(__ia64__) -// not assigned yet to IA-64 -# define __NR_accept4 -1 -# else -// set the syscalls to absurd numbers so that they'll cause ENOSYS errors -# warning "Please port the accept4 code to this platform" -# define __NR_accept4 -1 -# endif -# endif - -QT_BEGIN_NAMESPACE -namespace QtLibcSupplement { - int pipe2(int pipes[], int flags) - { - return syscall(__NR_pipe2, pipes, flags); - } - - int dup3(int oldfd, int newfd, int flags) - { - return syscall(__NR_dup3, oldfd, newfd, flags); - } - - int accept4(int s, sockaddr *addr, QT_SOCKLEN_T *addrlen, int flags) - { -# if defined(__NR_socketcall) - // This platform uses socketcall() instead of raw syscalls - // the SYS_ACCEPT4 number is cross-platform: 18 - return syscall(__NR_socketcall, 18, &s); -# else - return syscall(__NR_accept4, s, addr, addrlen, flags); -# endif - - Q_UNUSED(addr); Q_UNUSED(addrlen); Q_UNUSED(flags); // they're actually used - } -} -QT_END_NAMESPACE -#endif // Q_OS_LINUX - diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 69ebb05..3bdd5ec 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -73,32 +73,16 @@ struct sockaddr; -#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 -// Linux supports thread-safe FD_CLOEXEC +#if defined(Q_OS_LINUX) && defined(O_CLOEXEC) # define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1 - -// add defines for the consts for Linux -# ifndef O_CLOEXEC -# define O_CLOEXEC 02000000 -# endif -# ifndef FD_DUPFD_CLOEXEC -# define F_DUPFD_CLOEXEC 1030 -# endif -# ifndef SOCK_CLOEXEC -# define SOCK_CLOEXEC O_CLOEXEC -# endif -# ifndef SOCK_NONBLOCK -# define SOCK_NONBLOCK O_NONBLOCK -# endif -# ifndef MSG_CMSG_CLOEXEC -# define MSG_CMSG_CLOEXEC 0x40000000 -# endif - QT_BEGIN_NAMESPACE namespace QtLibcSupplement { - Q_CORE_EXPORT int accept4(int, sockaddr *, QT_SOCKLEN_T *, int flags); - Q_CORE_EXPORT int dup3(int oldfd, int newfd, int flags); - Q_CORE_EXPORT int pipe2(int pipes[], int flags); + inline int accept4(int, sockaddr *, QT_SOCKLEN_T *, int) + { errno = ENOSYS; return -1; } + inline int dup3(int, int, int) + { errno = ENOSYS; return -1; } + inline int pipe2(int [], int ) + { errno = ENOSYS; return -1; } } QT_END_NAMESPACE using namespace QT_PREPEND_NAMESPACE(QtLibcSupplement); @@ -190,7 +174,7 @@ static inline int qt_safe_pipe(int pipefd[2], int flags = 0) #endif register int ret; -#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(O_CLOEXEC) // use pipe2 flags |= O_CLOEXEC; ret = ::pipe2(pipefd, flags); // pipe2 is Linux-specific and is documented not to return EINTR @@ -246,7 +230,7 @@ static inline int qt_safe_dup2(int oldfd, int newfd, int flags = FD_CLOEXEC) Q_ASSERT(flags == FD_CLOEXEC || flags == 0); register int ret; -#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC +#if QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC && defined(O_CLOEXEC) // use dup3 if (flags & FD_CLOEXEC) { EINTR_LOOP(ret, ::dup3(oldfd, newfd, O_CLOEXEC)); diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index f38c2fc..040b3ec 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -85,7 +85,7 @@ static inline int qt_safe_socket(int domain, int type, int protocol, int flags = Q_ASSERT((flags & ~O_NONBLOCK) == 0); register int fd; -#ifdef SOCK_CLOEXEC +#if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) int newtype = type | SOCK_CLOEXEC; if (flags & O_NONBLOCK) newtype |= SOCK_NONBLOCK; -- cgit v0.12 From 9081e1e65681aab1c1d8a913b1a493fe1d37e837 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 3 Aug 2009 18:43:54 +0200 Subject: Clean up old Jambi code: there's a way of getting the QObject d-pointer --- src/corelib/kernel/qobject.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 7bf209a..c989d15 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3897,19 +3897,12 @@ QDebug operator<<(QDebug dbg, const QObject *o) { Synonym for QList. */ -#ifdef QT_JAMBI_BUILD -class QDPtrAccessor : public QObject { -public: - QObjectData *d() const { return d_ptr; } -}; -#endif - void qDeleteInEventHandler(QObject *o) { #ifdef QT_JAMBI_BUILD if (!o) return; - ((QDPtrAccessor *) o)->d()->inEventHandler = false; + QObjectPrivate::get(o)->inEventHandler = false; #endif delete o; } -- cgit v0.12 From d6e7238903d381bf2c2c9f89c17085e714384e87 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 31 Jul 2009 18:46:11 +0200 Subject: Reorganise QObjectPrivate so that it's easier to tell what's in it. Also rename QDeclarativeData to QObjectDeletionNotification, since it has no relation to declarative UI. It's just notification of the object's deletion. Make the destructor non-inline and place it in qobject.cpp, so that the virtual table is emitted there and exported from QtCore. Also move the QObjectData destructor to qobject.cpp. This means you cannot create any class deriving directly from QObjectData outside QtCore, which is the intention anyways (it's a private class and only QObjectPrivate derives from it). Reviewed-by: Bradley T. Hughes --- src/corelib/kernel/qobject.cpp | 16 +++--- src/corelib/kernel/qobject_p.h | 113 +++++++++++++++++++++-------------------- src/gui/kernel/qwidget.cpp | 7 ++- 3 files changed, 66 insertions(+), 70 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index c989d15..1938012 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -122,8 +122,11 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *) } } +QObjectData::~QObjectData() {} +QObjectDeletionNotification::~QObjectDeletionNotification() {} + QObjectPrivate::QObjectPrivate(int version) - : threadData(0), currentSender(0), declarativeData(0), connectionLists(0), senders(0) + : threadData(0), connectionLists(0), senders(0), currentSender(0), deletionNotification(0), objectGuards(0) { if (version != QObjectPrivateVersion) qFatal("Cannot mix incompatible Qt libraries"); @@ -144,7 +147,6 @@ QObjectPrivate::QObjectPrivate(int version) inEventHandler = false; inThreadChangeEvent = false; deleteWatch = 0; - objectGuards = 0; metaObject = 0; hasGuards = false; } @@ -767,6 +769,8 @@ QObject::~QObject() } emit destroyed(this); + if (d->deletionNotification) + d->deletionNotification->destroyed(this); { QMutexLocker locker(signalSlotLock(this)); @@ -844,14 +848,6 @@ QObject::~QObject() d->eventFilters.clear(); - // As declarativeData is in a union with currentChildBeingDeleted, this must - // be done (and declarativeData set back to 0) before deleting children. - if(d->declarativeData) { - QDeclarativeData *dd = d->declarativeData; - d->declarativeData = 0; - dd->destroyed(this); - } - if (!d->children.isEmpty()) d->deleteChildren(); diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 0b41c9a..52b4658 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -82,63 +82,21 @@ void Q_CORE_EXPORT qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet extern QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set; -inline QObjectData::~QObjectData() {} - enum { QObjectPrivateVersion = QT_VERSION }; -class QDeclarativeData +class Q_CORE_EXPORT QObjectDeletionNotification { public: - virtual ~QDeclarativeData() {} - virtual void destroyed(QObject *) {} + virtual ~QObjectDeletionNotification(); + virtual void destroyed(QObject *) = 0; }; +typedef QObjectDeletionNotification QDeclarativeData; // remove me when Declarative UI updates class Q_CORE_EXPORT QObjectPrivate : public QObjectData { Q_DECLARE_PUBLIC(QObject) public: - QObjectPrivate(int version = QObjectPrivateVersion); - virtual ~QObjectPrivate(); - -#ifdef QT3_SUPPORT - QList pendingChildInsertedEvents; - void sendPendingChildInsertedEvents(); - void removePendingChildInsertedEvents(QObject *child); -#else - // preserve binary compatibility with code compiled without Qt 3 support - QList unused; -#endif - - // id of the thread that owns the object - QThreadData *threadData; - void moveToThread_helper(); - void setThreadData_helper(QThreadData *currentData, QThreadData *targetData); - void _q_reregisterTimers(void *pointer); - - struct Sender - { - QObject *sender; - int signal; - int ref; - }; - // object currently activating the object - Sender *currentSender; - - QDeclarativeData *declarativeData; - - bool isSender(const QObject *receiver, const char *signal) const; - QObjectList receiverList(const char *signal) const; - QObjectList senderList() const; - - QList > eventFilters; - - void setParent_helper(QObject *); - - void deleteChildren(); - - static void clearGuards(QObject *); - struct ExtraData { #ifndef QT_NO_USERDATA @@ -147,12 +105,7 @@ public: QList propertyNames; QList propertyValues; }; - ExtraData *extraData; - mutable quint32 connectedSignals[2]; - - QString objectName; - // Note: you must hold the signalSlotLock() before accessing the lists below or calling the functions struct Connection { QObject *sender; @@ -167,11 +120,34 @@ public: }; typedef QList ConnectionList; - QObjectConnectionListVector *connectionLists; + struct Sender + { + QObject *sender; + int signal; + int ref; + }; + + + QObjectPrivate(int version = QObjectPrivateVersion); + virtual ~QObjectPrivate(); + void deleteChildren(); + + void setParent_helper(QObject *); + void moveToThread_helper(); + void setThreadData_helper(QThreadData *currentData, QThreadData *targetData); + void _q_reregisterTimers(void *pointer); + + bool isSender(const QObject *receiver, const char *signal) const; + QObjectList receiverList(const char *signal) const; + QObjectList senderList() const; + void addConnection(int signal, Connection *c); void cleanConnectionLists(); - Connection *senders; //linked list; +#ifdef QT3_SUPPORT + void sendPendingChildInsertedEvents(); + void removePendingChildInsertedEvents(QObject *child); +#endif static Sender *setCurrentSender(QObject *receiver, Sender *sender); @@ -180,13 +156,38 @@ public: Sender *previousSender); static int *setDeleteWatch(QObjectPrivate *d, int *newWatch); static void resetDeleteWatch(QObjectPrivate *d, int *oldWatch, int deleteWatch); - - int *deleteWatch; - QGuard *objectGuards; + static void clearGuards(QObject *); static QObjectPrivate *get(QObject *o) { return o->d_func(); } + +public: + QString objectName; + ExtraData *extraData; // extra data set by the user + QThreadData *threadData; // id of the thread that owns the object + + QObjectConnectionListVector *connectionLists; + + Connection *senders; // linked list of connections connected to this object + Sender *currentSender; // object currently activating the object + mutable quint32 connectedSignals[2]; // 64-bit, so doesn't cause padding on 64-bit platforms + +#ifdef QT3_SUPPORT + QList pendingChildInsertedEvents; +#else + // preserve binary compatibility with code compiled without Qt 3 support + // ### why? + QList unused; +#endif + + QList > eventFilters; + + // these objects are all used to indicate that a QObject was deleted + // plus QPointer, which keeps a separate list + QObjectDeletionNotification *deletionNotification; + QGuard *objectGuards; + int *deleteWatch; }; inline void q_guard_addGuard(QGuard *g) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 765b26f..075f9c3 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1375,10 +1375,9 @@ QWidget::~QWidget() // set all QPointers for this object to zero QObjectPrivate::clearGuards(this); - if(d->declarativeData) { - QDeclarativeData *dd = d->declarativeData; - d->declarativeData = 0; - dd->destroyed(this); + if (d->deletionNotification) { + d->deletionNotification->destroyed(this); + d->deletionNotification = 0; // don't activate again in ~QObject } if (!d->children.isEmpty()) -- cgit v0.12 From a654df7aa466775b0f9a6e4b33319c228f5634b2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 3 Aug 2009 14:56:49 +0200 Subject: Add QWeakPointer::data, which thread-unsafely returns the tracked pointer This function allows one to retrieve the pointer out of a QWeakPointer without promoting it to QSharedPointer first. That means there are no guarantees that the object won't get deleted. Reviewed-by: Bradley T. Hughes --- src/corelib/tools/qsharedpointer.cpp | 76 ++++++++++++++++++++++++++++++++- src/corelib/tools/qsharedpointer_impl.h | 1 + 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 2ca612e..ef4dfac 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -128,7 +128,7 @@ To access the pointer that QWeakPointer is tracking, you must first create a QSharedPointer object and verify if the pointer - is null or not. + is null or not. See QWeakPointer::toStrongRef() for more information. \sa QSharedPointer */ @@ -210,6 +210,8 @@ If \tt T is a derived type of the template parameter of this class, QSharedPointer will perform an automatic cast. Otherwise, you will get a compiler error. + + \sa QWeakPointer::toStrongRef() */ /*! @@ -362,6 +364,8 @@ Returns a weak reference object that shares the pointer referenced by this object. + + \sa QWeakPointer::QWeakPointer(const QSharedPointer &) */ /*! @@ -478,10 +482,78 @@ */ /*! + \fn T *QWeakPointer::data() const + \since 4.6 + + Returns the value of the pointer being tracked by this QWeakPointer, + \b without ensuring that it cannot get deleted. To have that guarantee, + use toStrongRef(), which returns a QSharedPointer object. If this + function can determine that the pointer has already been deleted, it + returns 0. + + It is ok to obtain the value of the pointer and using that value itself, + like for example in debugging statements: + + \code + qDebug("Tracking %p", weakref.data()); + \endcode + + However, dereferencing the pointer is only allowed if you can guarantee + by external means that the pointer does not get deleted. For example, + if you can be certain that no other thread can delete it, nor the + functions that you may call. + + If that is the case, then the following code is valid: + + \code + // this pointer cannot be used in another thread + // so other threads cannot delete it + QWeakPointer weakref = obtainReference(); + + Object *obj = weakref.data(); + if (obj) { + // if the pointer wasn't deleted yet, we know it can't get + // deleted by our own code here nor the functions we call + otherFunction(obj); + } + \endcode + + Use this function with care. + + \sa isNull(), toStrongRef() +*/ + +/*! \fn QSharedPointer QWeakPointer::toStrongRef() const Promotes this weak reference to a strong one and returns a - QSharedPointer object holding that reference. + QSharedPointer object holding that reference. When promoting to + QSharedPointer, this function verifies if the object has been deleted + already or not. If it hasn't, this function increases the reference + count to the shared object, thus ensuring that it will not get + deleted. + + Since this function can fail to obtain a valid strong reference to the + shared object, you should always verify if the conversion succeeded, + by calling QSharedPointer::isNull() on the returned object. + + For example, the following code promotes a QWeakPointer that was held + to a strong reference and, if it succeeded, it prints the value of the + integer that was held: + + \code + QWeakPointer weakref; + + // ... + + QSharedPointer strong = weakref.toStrongRef(); + if (strong) + qDebug() << "The value is:" << *strong; + else + qDebug() << "The value has already been deleted"; + \endcode + + \sa QSharedPointer::QSharedPointer(const QWeakPointer &) */ /*! diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 9fa8df4..e8e3812 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -492,6 +492,7 @@ public: inline bool isNull() const { return d == 0 || d->strongref == 0 || value == 0; } inline operator RestrictedBool() const { return isNull() ? 0 : &QWeakPointer::value; } inline bool operator !() const { return isNull(); } + inline T *data() const { return d == 0 || d->strongref == 0 ? 0 : value; } inline QWeakPointer() : d(0), value(0) { } inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; } -- cgit v0.12 From 6e9d84fcadc07b8f11d9e0eb046c25152eba1235 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 4 Aug 2009 16:33:09 +0200 Subject: Added the license header to the example. --- .../gestures/imageviewer/tapandholdgesture.cpp | 41 ++++++++++++++++++++++ examples/gestures/imageviewer/tapandholdgesture.h | 41 ++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/examples/gestures/imageviewer/tapandholdgesture.cpp b/examples/gestures/imageviewer/tapandholdgesture.cpp index c6f6779..ff5284e 100644 --- a/examples/gestures/imageviewer/tapandholdgesture.cpp +++ b/examples/gestures/imageviewer/tapandholdgesture.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "tapandholdgesture.h" #include diff --git a/examples/gestures/imageviewer/tapandholdgesture.h b/examples/gestures/imageviewer/tapandholdgesture.h index 711a1af..e0d50b5 100644 --- a/examples/gestures/imageviewer/tapandholdgesture.h +++ b/examples/gestures/imageviewer/tapandholdgesture.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef TAPANDHOLDGESTURE_H #define TAPANDHOLDGESTURE_H -- cgit v0.12 From 31edb4d5a63b9b3c28cce1c4ca6eb99f62a09759 Mon Sep 17 00:00:00 2001 From: Matthew Cattell Date: Tue, 4 Aug 2009 16:45:46 +0200 Subject: qregext filter changed to support additional parameter/unicode changed the QRegExp filter back to the old form plus an additional piece to allow international characters. the new regular expression now allows a file type filter to contain a bracketed description prior to the filter set itself. 259105 Andy Shaw --- src/gui/dialogs/qfiledialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index 8b4e1b1..1ec94b6 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -2838,7 +2838,8 @@ void QFileDialogPrivate::_q_goToDirectory(const QString &path) } const char *qt_file_dialog_filter_reg_exp = - "^([^()]*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"; +"(\\W|[a-zA-Z0-9 -]*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"; + // Makes a list of filters from a normal filter string "Image Files (*.png *.jpg)" QStringList qt_clean_filter_list(const QString &filter) -- cgit v0.12 From 83ff02450ea74468fec441e632ddc2cfda2b251c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 4 Aug 2009 18:01:33 +0200 Subject: Revert "Remove currentChildBeingDeleted from QObjectPrivate." This reverts commit 128717b171f01c82e5f0fb83f5923d4f7b9cfc10. The change broke Alien because QWidget no longer has the native window handle in its own private. It needs to access the top-level window (or the one with the native handle) in order to perform some operations. The problem is that it needs to do that in the destructor. And we cleared the parent before the destructor was run. Technically speaking, reverting is the correct thing to do, since the parent *still* exists when the child is deleted. --- src/corelib/kernel/qobject.cpp | 29 +++++++++++++++++------------ src/corelib/kernel/qobject_p.h | 1 + 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 1938012..0801418 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -126,7 +126,7 @@ QObjectData::~QObjectData() {} QObjectDeletionNotification::~QObjectDeletionNotification() {} QObjectPrivate::QObjectPrivate(int version) - : threadData(0), connectionLists(0), senders(0), currentSender(0), deletionNotification(0), objectGuards(0) + : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0), deletionNotification(0), objectGuards(0) { if (version != QObjectPrivateVersion) qFatal("Cannot mix incompatible Qt libraries"); @@ -1855,13 +1855,12 @@ void QObjectPrivate::deleteChildren() // don't use qDeleteAll as the destructor of the child might // delete siblings for (int i = 0; i < children.count(); ++i) { - QObject *child = children.at(i); + currentChildBeingDeleted = children.at(i); children[i] = 0; - if (child) - child->d_func()->parent = 0; - delete child; + delete currentChildBeingDeleted; } children.clear(); + currentChildBeingDeleted = 0; wasDeleted = reallyWasDeleted; } @@ -1872,14 +1871,20 @@ void QObjectPrivate::setParent_helper(QObject *o) return; if (parent) { QObjectPrivate *parentD = parent->d_func(); - const int index = parentD->children.indexOf(q); - if (parentD->wasDeleted) { - parentD->children[index] = 0; + if (parentD->wasDeleted && wasDeleted + && parentD->currentChildBeingDeleted == q) { + // don't do anything since QObjectPrivate::deleteChildren() already + // cleared our entry in parentD->children. } else { - parentD->children.removeAt(index); - if (sendChildEvents && parentD->receiveChildEvents) { - QChildEvent e(QEvent::ChildRemoved, q); - QCoreApplication::sendEvent(parent, &e); + const int index = parentD->children.indexOf(q); + if (parentD->wasDeleted) { + parentD->children[index] = 0; + } else { + parentD->children.removeAt(index); + if (sendChildEvents && parentD->receiveChildEvents) { + QChildEvent e(QEvent::ChildRemoved, q); + QCoreApplication::sendEvent(parent, &e); + } } } } diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 52b4658..a7f3a5a 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -182,6 +182,7 @@ public: #endif QList > eventFilters; + QObject *currentChildBeingDeleted; // these objects are all used to indicate that a QObject was deleted // plus QPointer, which keeps a separate list -- cgit v0.12 From a22f422b20299a501c307b21a6095ece87749124 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 4 Aug 2009 18:43:10 +0200 Subject: Restore the old name for QObjectDeletionNotification. If we're going to do changes to simplify some of the Declarative UI enablers, let's do them all at once. That way, the adaptation necessary happens only once, as opposed to every time we do the changes. I tried not to break by leaving a typedef, but obviously the QObjectPrivate member isn't affected by the typedef... Reviewed-by: Trust Me --- src/corelib/kernel/qobject.cpp | 8 ++++---- src/corelib/kernel/qobject_p.h | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 0801418..7e7dcaf 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -123,10 +123,10 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *) } QObjectData::~QObjectData() {} -QObjectDeletionNotification::~QObjectDeletionNotification() {} +QDeclarativeData::~QDeclarativeData() {} QObjectPrivate::QObjectPrivate(int version) - : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0), deletionNotification(0), objectGuards(0) + : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0), declarativeData(0), objectGuards(0) { if (version != QObjectPrivateVersion) qFatal("Cannot mix incompatible Qt libraries"); @@ -769,8 +769,8 @@ QObject::~QObject() } emit destroyed(this); - if (d->deletionNotification) - d->deletionNotification->destroyed(this); + if (d->declarativeData) + d->declarativeData->destroyed(this); { QMutexLocker locker(signalSlotLock(this)); diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index a7f3a5a..e58ee6c 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -84,13 +84,12 @@ extern QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set; enum { QObjectPrivateVersion = QT_VERSION }; -class Q_CORE_EXPORT QObjectDeletionNotification +class Q_CORE_EXPORT QDeclarativeData { public: - virtual ~QObjectDeletionNotification(); + virtual ~QDeclarativeData(); virtual void destroyed(QObject *) = 0; }; -typedef QObjectDeletionNotification QDeclarativeData; // remove me when Declarative UI updates class Q_CORE_EXPORT QObjectPrivate : public QObjectData { @@ -186,7 +185,7 @@ public: // these objects are all used to indicate that a QObject was deleted // plus QPointer, which keeps a separate list - QObjectDeletionNotification *deletionNotification; + QDeclarativeData *declarativeData; QGuard *objectGuards; int *deleteWatch; }; -- cgit v0.12 From 8e01aa83880bf9cc669106f1e219abd3b3fca186 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 4 Aug 2009 20:06:04 +0200 Su