summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Boddie <dboddie@trolltech.com>2009-07-13 11:49:08 (GMT)
committerDavid Boddie <dboddie@trolltech.com>2009-07-13 11:49:08 (GMT)
commit821c7c1486beb6d5e65bd3ac8ba74752fec37fe8 (patch)
tree042ad778ccdfacd2dc1b4751a98e83889e5e10e3
parent85fbffa12bcd38b08030561335305c3226312bc6 (diff)
parentcc24c46c117248ecb98200416e7f25375e6bb476 (diff)
downloadQt-821c7c1486beb6d5e65bd3ac8ba74752fec37fe8.zip
Qt-821c7c1486beb6d5e65bd3ac8ba74752fec37fe8.tar.gz
Qt-821c7c1486beb6d5e65bd3ac8ba74752fec37fe8.tar.bz2
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt
-rwxr-xr-xconfigure4
-rw-r--r--configure.exebin835584 -> 1101312 bytes
-rw-r--r--doc/src/dnd.qdoc13
-rw-r--r--doc/src/qnamespace.qdoc5
-rw-r--r--doc/src/threads.qdoc82
-rw-r--r--src/3rdparty/phonon/ds9/videowidget.cpp2
-rw-r--r--src/corelib/animation/qpropertyanimation.cpp18
-rw-r--r--src/corelib/codecs/qiconvcodec.cpp6
-rw-r--r--src/corelib/global/qglobal.h2
-rw-r--r--src/corelib/io/qbuffer.cpp2
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp25
-rw-r--r--src/corelib/kernel/qcore_unix_p.h7
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp42
-rw-r--r--src/corelib/plugin/qplugin.h19
-rw-r--r--src/corelib/thread/qthread.cpp11
-rw-r--r--src/corelib/tools/qringbuffer_p.h5
-rw-r--r--src/corelib/tools/qstring.h2
-rw-r--r--src/corelib/tools/qstringbuilder.h14
-rw-r--r--src/dbus/qdbusconnection.cpp7
-rw-r--r--src/gui/dialogs/qfiledialog_p.h1
-rw-r--r--src/gui/dialogs/qsidebar.cpp13
-rw-r--r--src/gui/graphicsview/graphicsview.pri51
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp211
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h53
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h61
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp1743
-rw-r--r--src/gui/graphicsview/qgraphicsscene.h40
-rw-r--r--src/gui/graphicsview/qgraphicsscene_bsp.cpp56
-rw-r--r--src/gui/graphicsview/qgraphicsscene_bsp_p.h9
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h127
-rw-r--r--src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp782
-rw-r--r--src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h213
-rw-r--r--src/gui/graphicsview/qgraphicssceneindex.cpp659
-rw-r--r--src/gui/graphicsview/qgraphicssceneindex_p.h182
-rw-r--r--src/gui/graphicsview/qgraphicsscenelinearindex.cpp62
-rw-r--r--src/gui/graphicsview/qgraphicsscenelinearindex_p.h109
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp216
-rw-r--r--src/gui/graphicsview/qgraphicsview_p.h10
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp50
-rw-r--r--src/gui/itemviews/qabstractitemview_p.h11
-rw-r--r--src/gui/itemviews/qitemselectionmodel.cpp35
-rw-r--r--src/gui/itemviews/qlistview.cpp146
-rw-r--r--src/gui/itemviews/qlistview_p.h24
-rw-r--r--src/gui/itemviews/qtableview.cpp8
-rw-r--r--src/gui/itemviews/qtreeview.cpp140
-rw-r--r--src/gui/itemviews/qtreeview.h5
-rw-r--r--src/gui/itemviews/qtreeview_p.h36
-rw-r--r--src/gui/kernel/qapplication.cpp9
-rw-r--r--src/gui/kernel/qapplication_mac.mm12
-rw-r--r--src/gui/kernel/qapplication_p.h10
-rw-r--r--src/gui/kernel/qapplication_win.cpp49
-rw-r--r--src/gui/kernel/qcocoapanel_mac.mm6
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm116
-rw-r--r--src/gui/kernel/qcocoaview_mac_p.h4
-rw-r--r--src/gui/kernel/qcocoawindow_mac.mm6
-rw-r--r--src/gui/kernel/qmultitouch_mac.mm6
-rw-r--r--src/gui/kernel/qmultitouch_mac_p.h4
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm34
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac_p.h3
-rw-r--r--src/gui/kernel/qt_mac.cpp6
-rw-r--r--src/gui/kernel/qwidget.cpp12
-rw-r--r--src/gui/kernel/qwidget_mac.mm10
-rw-r--r--src/gui/math3d/qgenericmatrix.h4
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp7
-rw-r--r--src/gui/math3d/qquaternion.cpp4
-rw-r--r--src/gui/math3d/qvector2d.cpp4
-rw-r--r--src/gui/math3d/qvector3d.cpp4
-rw-r--r--src/gui/math3d/qvector4d.cpp4
-rw-r--r--src/gui/text/qsyntaxhighlighter.cpp40
-rw-r--r--src/gui/text/qsyntaxhighlighter.h1
-rw-r--r--src/gui/widgets/qabstractscrollarea_p.h2
-rw-r--r--src/gui/widgets/qabstractspinbox.cpp2
-rw-r--r--src/gui/widgets/qdockarealayout.cpp2
-rw-r--r--src/gui/widgets/qeffects.cpp3
-rw-r--r--src/gui/widgets/qgroupbox.cpp6
-rw-r--r--src/gui/widgets/qmainwindow.cpp13
-rw-r--r--src/gui/widgets/qmainwindowlayout.cpp81
-rw-r--r--src/gui/widgets/qmainwindowlayout_mac.mm31
-rw-r--r--src/gui/widgets/qmainwindowlayout_p.h2
-rw-r--r--src/gui/widgets/qprogressbar.cpp2
-rw-r--r--src/gui/widgets/qspinbox.cpp7
-rw-r--r--src/gui/widgets/qtabbar.cpp66
-rw-r--r--src/gui/widgets/qtabbar.h2
-rw-r--r--src/gui/widgets/qtabbar_p.h68
-rw-r--r--src/gui/widgets/qtoolbar.cpp29
-rw-r--r--src/gui/widgets/qwidgetanimator.cpp1
-rw-r--r--src/gui/widgets/qwidgetanimator_p.h1
-rw-r--r--src/network/access/qhttpnetworkreply.cpp6
-rw-r--r--src/network/access/qhttpnetworkreply_p.h1
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp4
-rw-r--r--src/network/kernel/qnetworkproxy.cpp2
-rw-r--r--src/network/socket/qlocalsocket_win.cpp10
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp177
-rw-r--r--src/plugins/kbddrivers/sl5000/main.cpp3
-rw-r--r--src/plugins/kbddrivers/vr41xx/main.cpp3
-rw-r--r--src/plugins/kbddrivers/yopy/main.cpp3
-rw-r--r--src/sql/drivers/oci/qsql_oci.cpp2
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.cpp16
-rw-r--r--src/sql/drivers/psql/qsql_psql.cpp49
-rw-r--r--src/sql/models/qsqltablemodel.cpp3
-rw-r--r--src/svg/qsvghandler.cpp105
-rw-r--r--src/svg/qsvgstyle.cpp14
-rw-r--r--src/svg/qsvgstyle_p.h28
-rw-r--r--tests/auto/auto.pro1
-rwxr-xr-xtests/auto/linguist/lconvert/data/makeplurals.pl42
-rwxr-xr-xtests/auto/linguist/lconvert/data/makeplurals.sh43
-rw-r--r--tests/auto/linguist/lconvert/tst_lconvert.cpp11
-rw-r--r--tests/auto/linguist/lrelease/tst_lrelease.cpp16
-rw-r--r--tests/auto/linguist/lupdate/testlupdate.cpp5
-rw-r--r--tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp35
-rw-r--r--tests/auto/math3d/qquaternion/tst_qquaternion.cpp4
-rw-r--r--tests/auto/math3d/qvectornd/tst_qvectornd.cpp4
-rw-r--r--tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp20
-rw-r--r--tests/auto/qcombobox/tst_qcombobox.cpp6
-rw-r--r--tests/auto/qcssparser/qcssparser.pro1
-rw-r--r--tests/auto/qfiledialog/tst_qfiledialog.cpp39
-rw-r--r--tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp2
-rw-r--r--tests/auto/qflags/tst_qflags.cpp24
-rw-r--r--tests/auto/qfontdialog/tst_qfontdialog.cpp8
-rw-r--r--tests/auto/qgl/qgl.pro3
-rw-r--r--tests/auto/qgl/tst_qgl.cpp23
-rw-r--r--tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp149
-rw-r--r--tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp1
-rw-r--r--tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp41
-rw-r--r--tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp38
-rw-r--r--tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro3
-rw-r--r--tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp271
-rw-r--r--tests/auto/qgraphicsview/tst_qgraphicsview.cpp136
-rw-r--r--tests/auto/qhttpnetworkconnection/qhttpnetworkconnection.pro2
-rw-r--r--tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro2
-rw-r--r--tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp10
-rw-r--r--tests/auto/qkeysequence/tst_qkeysequence.cpp2
-rw-r--r--tests/auto/qlocalsocket/tst_qlocalsocket.cpp17
-rw-r--r--tests/auto/qmainwindow/tst_qmainwindow.cpp6
-rw-r--r--tests/auto/qmenubar/tst_qmenubar.cpp3
-rw-r--r--tests/auto/qnativesocketengine/qnativesocketengine.pro2
-rw-r--r--tests/auto/qnetworkreply/qnetworkreply.pro2
-rw-r--r--tests/auto/qnetworkreply/tst_qnetworkreply.cpp125
-rw-r--r--tests/auto/qpathclipper/qpathclipper.pro2
-rw-r--r--tests/auto/qplaintextedit/tst_qplaintextedit.cpp2
-rw-r--r--tests/auto/qregion/tst_qregion.cpp6
-rw-r--r--tests/auto/qsettings/tst_qsettings.cpp22
-rw-r--r--tests/auto/qsharedpointer/qsharedpointer.pro1
-rw-r--r--tests/auto/qsocketnotifier/qsocketnotifier.pro2
-rw-r--r--tests/auto/qsocks5socketengine/qsocks5socketengine.pro1
-rw-r--r--tests/auto/qsqldatabase/tst_databases.h25
-rw-r--r--tests/auto/qsqldatabase/tst_qsqldatabase.cpp18
-rw-r--r--tests/auto/qsqldriver/tst_qsqldriver.cpp4
-rw-r--r--tests/auto/qsqlquery/tst_qsqlquery.cpp42
-rw-r--r--tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp18
-rw-r--r--tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp62
-rw-r--r--tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp4
-rw-r--r--tests/auto/qstatemachine/tst_qstatemachine.cpp2
-rw-r--r--tests/auto/qstringbuilder/tst_qstringbuilder.cpp17
-rw-r--r--tests/auto/qstylesheetstyle/qstylesheetstyle.pro1
-rw-r--r--tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp156
-rw-r--r--tests/auto/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp29
-rw-r--r--tests/auto/qtableview/tst_qtableview.cpp56
-rw-r--r--tests/auto/qtextedit/tst_qtextedit.cpp4
-rw-r--r--tests/auto/qtextpiecetable/qtextpiecetable.pro5
-rw-r--r--tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp32
-rw-r--r--tests/auto/qurl/tst_qurl.cpp4
-rw-r--r--tests/auto/qwidget/tst_qwidget.cpp15
-rw-r--r--tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro1
-rw-r--r--tests/auto/xmlpatternsview/xmlpatternsview.pro1
-rw-r--r--tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro3
-rw-r--r--tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro1
-rw-r--r--tools/assistant/lib/qhelpsearchengine.cpp29
-rw-r--r--tools/assistant/lib/qhelpsearchindexreader_clucene.cpp22
-rw-r--r--tools/assistant/lib/qhelpsearchindexreader_clucene_p.h7
-rw-r--r--tools/configure/configureapp.cpp7
-rw-r--r--tools/designer/src/designer/qdesigner_workbench.cpp11
-rw-r--r--tools/linguist/lupdate/main.cpp5
-rw-r--r--tools/linguist/phrasebooks/french.qph227
-rw-r--r--tools/linguist/phrasebooks/russian.qph52
-rw-r--r--tools/linguist/shared/profileevaluator.cpp16
-rw-r--r--tools/qdoc3/doc.cpp3
-rw-r--r--tools/qtconfig/translations/translations.pro1
-rw-r--r--tools/qtestlib/wince/cetest/activesyncconnection.cpp12
-rw-r--r--tools/qtestlib/wince/cetest/main.cpp1
-rw-r--r--tools/qtestlib/wince/cetest/remoteconnection.cpp4
-rw-r--r--tools/qvfb/translations/translations.pro1
-rw-r--r--translations/assistant_adp_ru.ts289
-rw-r--r--translations/assistant_ru.ts80
-rw-r--r--translations/linguist_ru.ts28
-rw-r--r--translations/qt_help_ru.ts36
-rw-r--r--translations/qt_ru.ts200
-rw-r--r--translations/qtconfig_ru.ts906
-rw-r--r--translations/qvfb_ru.ts328
189 files changed, 7298 insertions, 3018 deletions
diff --git a/configure b/configure
index f9b3030..bd8b0ca 100755
--- a/configure
+++ b/configure
@@ -6256,7 +6256,6 @@ esac
# debug release
# dll staticlib
#
-# internal
# nocrosscompiler
# GNUmake
# largefile
@@ -6736,6 +6735,9 @@ fi
if [ "$PLATFORM_MAC" = "yes" ]; then
QT_CONFIG="$QT_CONFIG $CFG_MAC_ARCHS"
fi
+if [ "$CFG_DEV" = "yes" ]; then
+ QT_CONFIG="$QT_CONFIG private_tests"
+fi
# Make the application arch follow the Qt arch for single arch builds.
# (for multiple-arch builds, set CONFIG manually in the application .pro file)
diff --git a/configure.exe b/configure.exe
index a139116..10b926e 100644
--- a/configure.exe
+++ b/configure.exe
Binary files differ
diff --git a/doc/src/dnd.qdoc b/doc/src/dnd.qdoc
index b5039f6..5ede20c 100644
--- a/doc/src/dnd.qdoc
+++ b/doc/src/dnd.qdoc
@@ -141,15 +141,17 @@
types of data that the widget accepts.
You must reimplement this function if you want to receive either
QDragMoveEvent or QDropEvent in your reimplementations of
- \l{QWidget::dragMoveEvent()}{dragMoveEvent()} and dropEvent().
+ \l{QWidget::dragMoveEvent()}{dragMoveEvent()} and
+ \l{QWidget::dropEvent()}{dropEvent()}.
- The following code shows how dragEnterEvent() can be reimplemented to
+ The following code shows how \l{QWidget::dragEnterEvent()}{dragEnterEvent()}
+ can be reimplemented to
tell the drag and drop system that we can only handle plain text:
\snippet doc/src/snippets/dropevents/window.cpp 3
- The dropEvent() is used to unpack dropped data and handle it in way that
- is suitable for your application.
+ The \l{QWidget::dropEvent()}{dropEvent()} is used to unpack dropped data
+ and handle it in way that is suitable for your application.
In the following code, the text supplied in the event is passed to a
QTextBrowser and a QComboBox is filled with the list of MIME types that
@@ -159,7 +161,8 @@
In this case, we accept the proposed action without checking what it is.
In a real world application, it may be necessary to return from the
- dropEvent() function without accepting the proposed action or handling
+ \l{QWidget::dropEvent()}{dropEvent()} function without accepting the
+ proposed action or handling
the data if the action is not relevant. For example, we may choose to
ignore Qt::LinkAction actions if we do not support
links to external sources in our application.
diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc
index d509912..ded1577 100644
--- a/doc/src/qnamespace.qdoc
+++ b/doc/src/qnamespace.qdoc
@@ -1247,8 +1247,9 @@
/*! \typedef Qt::HANDLE
Platform-specific handle type for system objects. This is
- equivalent to \c{void *} on Windows and Mac OS X, and embedded
- Linux, and to \c{unsigned long} on X11.
+ equivalent to \c{void *} on Mac OS X and embedded Linux,
+ and to \c{unsigned long} on X11. On Windows it is the
+ DWORD returned by the Win32 function getCurrentThreadId().
\warning Using this type is not portable.
*/
diff --git a/doc/src/threads.qdoc b/doc/src/threads.qdoc
index 9f7f857..8469f51 100644
--- a/doc/src/threads.qdoc
+++ b/doc/src/threads.qdoc
@@ -262,48 +262,41 @@
\keyword thread-safe
\section1 Reentrancy and Thread-Safety
- Throughout the Qt documentation, the terms \e reentrant and \e
- thread-safe are used to specify how a function can be used in
- multithreaded applications:
+ Throughout the documentation, the terms \e{reentrant} and
+ \e{thread-safe} are used to mark classes and functions to indicate
+ how they can be used in multithread applications:
\list
- \o A \e reentrant function can be called simultaneously by
- multiple threads provided that each invocation of the function
- references unique data.
- \o A \e thread-safe function can be called simultaneously by
- multiple threads when each invocation references shared data.
- All access to the shared data is serialized.
+ \o A \e thread-safe function can be called simultaneously from
+ multiple threads, even when the invocations use shared data,
+ because all references to the shared data are serialized.
+ \o A \e reentrant function can also be called simultaneously from
+ multiple threads, but only if each invocation uses its own data.
\endlist
- By extension, a class is said to be reentrant if each and every
- one of its functions can be called simultaneously by multiple
- threads on different instances of the class. Similarly, the class
- is said to be thread-safe if the functions can be called by
- different threads on the same instance.
+ Hence, a \e{thread-safe} function is always \e{reentrant}, but a
+ \e{reentrant} function is not always \e{thread-safe}.
- Classes in the documentation will be documented as thread-safe only
- if they are intended to be used by multiple threads.
+ By extension, a class is said to be \e{reentrant} if its member
+ functions can be called safely from multiple threads, as long as
+ each thread uses a \e{different} instance of the class. The class
+ is \e{thread-safe} if its member functions can be called safely
+ from multiple threads, even if all the threads use the \e{same}
+ instance of the class.
- Note that the terminology in this domain isn't entirely
- standardized. POSIX uses a somewhat different definition of
- reentrancy and thread-safety for its C APIs. When dealing with an
- object-oriented C++ class library such as Qt, the definitions
- must be adapted.
-
- Most C++ classes are inherently reentrant, since they typically
- only reference member data. Any thread can call such a member
- function on an instance of the class, as long as no other thread
- is calling a member function on the same instance. For example,
- the \c Counter class below is reentrant:
+ C++ classes are often reentrant, simply because they only access
+ their own member data. Any thread can call a member function on an
+ instance of a reentrant class, as long as no other thread can call
+ a member function on the \e{same} instance of the class at the
+ same time. For example, the \c Counter class below is reentrant:
\snippet doc/src/snippets/threads/threads.cpp 3
\snippet doc/src/snippets/threads/threads.cpp 4
The class isn't thread-safe, because if multiple threads try to
modify the data member \c n, the result is undefined. This is
- because C++'s \c ++ and \c -- operators aren't necessarily
- atomic. Indeed, they usually expand to three machine
- instructions:
+ because the \c ++ and \c -- operators aren't always atomic.
+ Indeed, they usually expand to three machine instructions:
\list 1
\o Load the variable's value in a register.
@@ -332,14 +325,27 @@
declared with the \c mutable qualifier because we need to lock
and unlock the mutex in \c value(), which is a const function.
- Most Qt classes are reentrant and not thread-safe, to avoid the
- overhead of repeatedly locking and unlocking a QMutex. For
- example, QString is reentrant, meaning that you can use it in
- different threads, but you can't access the same QString object
- from different threads simultaneously (unless you protect it with
- a mutex yourself). A few classes and functions are thread-safe;
- these are mainly thread-related classes such as QMutex, or
- fundamental functions such as QCoreApplication::postEvent().
+ Many Qt classes are \e{reentrant}, but they are not made
+ \e{thread-safe}, because making them thread-safe would incur the
+ extra overhead of repeatedly locking and unlocking a QMutex. For
+ example, QString is reentrant but not thread-safe. You can safely
+ access \e{different} instances of QString from multiple threads
+ simultaneously, but you can't safely access the \e{same} instance
+ of QString from multiple threads simultaneously (unless you
+ protect the accesses yourself with a QMutex).
+
+ Some Qt classes and functions are thread-safe. These are mainly
+ the thread-related classes (e.g. QMutex) and fundamental functions
+ (e.g. QCoreApplication::postEvent()).
+
+ \note Qt Classes are only documented as \e{thread-safe} if they
+ are intended to be used by multiple threads.
+
+ \note Terminology in the multithreading domain isn't entirely
+ standardized. POSIX uses definitions of reentrant and thread-safe
+ that are somewhat different for its C APIs. When using other
+ object-oriented C++ class libraries with Qt, be sure the
+ definitions are understood.
\section1 Threads and QObjects
diff --git a/src/3rdparty/phonon/ds9/videowidget.cpp b/src/3rdparty/phonon/ds9/videowidget.cpp
index 0ef653f..34ff8cb 100644
--- a/src/3rdparty/phonon/ds9/videowidget.cpp
+++ b/src/3rdparty/phonon/ds9/videowidget.cpp
@@ -153,7 +153,7 @@ namespace Phonon
}
} else if (!isEmbedded()) {
m_currentRenderer = m_node->switchRendering(m_currentRenderer);
- setAttribute(Qt::WA_PaintOnScreen, true);
+ setAttribute(Qt::WA_PaintOnScreen, false);
}
}
diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp
index 7526a81..5f224aa 100644
--- a/src/corelib/animation/qpropertyanimation.cpp
+++ b/src/corelib/animation/qpropertyanimation.cpp
@@ -100,10 +100,6 @@
QT_BEGIN_NAMESPACE
-typedef QPair<QObject *, QByteArray> QPropertyAnimationPair;
-typedef QHash<QPropertyAnimationPair, QPropertyAnimation*> QPropertyAnimationHash;
-Q_GLOBAL_STATIC(QPropertyAnimationHash, _q_runningAnimations)
-
void QPropertyAnimationPrivate::updateMetaProperty()
{
if (!target || propertyName.isEmpty())
@@ -286,19 +282,21 @@ void QPropertyAnimation::updateState(QAbstractAnimation::State oldState,
QPropertyAnimation *animToStop = 0;
{
- QPropertyAnimationHash * hash = _q_runningAnimations();
- QMutexLocker locker(QMutexPool::globalInstanceGet(hash));
+ QMutexLocker locker(QMutexPool::globalInstanceGet(&staticMetaObject));
+ typedef QPair<QObject *, QByteArray> QPropertyAnimationPair;
+ typedef QHash<QPropertyAnimationPair, QPropertyAnimation*> QPropertyAnimationHash;
+ static QPropertyAnimationHash hash;
QPropertyAnimationPair key(d->target, d->propertyName);
if (newState == Running) {
d->updateMetaProperty();
- animToStop = hash->value(key, 0);
- hash->insert(key, this);
+ animToStop = hash.value(key, 0);
+ hash.insert(key, this);
// update the default start value
if (oldState == Stopped) {
d->setDefaultStartValue(d->target->property(d->propertyName.constData()));
}
- } else if (hash->value(key) == this) {
- hash->remove(key);
+ } else if (hash.value(key) == this) {
+ hash.remove(key);
}
}
diff --git a/src/corelib/codecs/qiconvcodec.cpp b/src/corelib/codecs/qiconvcodec.cpp
index 1bf76ea..188ac8c 100644
--- a/src/corelib/codecs/qiconvcodec.cpp
+++ b/src/corelib/codecs/qiconvcodec.cpp
@@ -225,10 +225,11 @@ QString QIconvCodec::convertToUnicode(const char* chars, int len, ConverterState
char *inBytes = const_cast<char *>(chars);
#endif
+ QByteArray in;
if (remainingCount) {
// we have to prepend the remaining bytes from the previous conversion
inBytesLeft += remainingCount;
- QByteArray in(inBytesLeft, Qt::Uninitialized);
+ in.resize(inBytesLeft);
inBytes = in.data();
memcpy(in.data(), remainingBuffer, remainingCount);
@@ -362,9 +363,10 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt
inBytes = const_cast<char *>(reinterpret_cast<const char *>(uc));
inBytesLeft = len * sizeof(QChar);
+ QByteArray in;
if (convState && convState->remainingChars) {
// we have one surrogate char to be prepended
- QByteArray in(sizeof(QChar) + len, Qt::Uninitialized);
+ in.resize(sizeof(QChar) + len);
inBytes = in.data();
QChar remaining = convState->state_data[0];
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index a139a55..d6c708c 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -2062,7 +2062,7 @@ public:
inline bool operator!() const { return !i; }
- inline bool testFlag(Enum f) const { return (i & f) == f; }
+ inline bool testFlag(Enum f) const { return (i & f) == f && (f != 0 || i == f ); }
};
#define Q_DECLARE_FLAGS(Flags, Enum)\
diff --git a/src/corelib/io/qbuffer.cpp b/src/corelib/io/qbuffer.cpp
index aed5b82..3883d30 100644
--- a/src/corelib/io/qbuffer.cpp
+++ b/src/corelib/io/qbuffer.cpp
@@ -452,7 +452,7 @@ qint64 QBuffer::writeData(const char *data, qint64 len)
*/
void QBuffer::connectNotify(const char *signal)
{
- if (strcmp(signal + 1, "readyRead()") == 0 || strcmp(signal + 1, "bytesWritten(qint64)"))
+ if (strcmp(signal + 1, "readyRead()") == 0 || strcmp(signal + 1, "bytesWritten(qint64)") == 0)
d_func()->signalConnectionCount++;
}
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index a98d005..e2682f5 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -398,20 +398,23 @@ void QAbstractEventDispatcher::closingDown()
*/
/*!
- Sets the event filter \a filter. Returns a pointer to the filter
- function previously defined.
-
- The event filter is a function that receives all messages taken
- from the system event loop before the event is dispatched to the
- respective target. This includes messages that are not sent to Qt
+ Replaces the event filter function for this
+ QAbstractEventDispatcher with \a filter and returns the replaced
+ event filter function. Only the current event filter function is
+ called. If you want to use both filter functions, save the
+ replaced EventFilter in a place where yours can call it.
+
+ The event filter function set here is called for all messages
+ taken from the system event loop before the event is dispatched to
+ the respective target, including the messages not meant for Qt
objects.
- The function can return true to stop the event to be processed by
- Qt, or false to continue with the standard event processing.
+ The event filter function should return true if the message should
+ be filtered, (i.e. stopped). It should return false to allow
+ processing the message to continue.
- Only one filter can be defined, but the filter can use the return
- value to call the previously set event filter. By default, no
- filter is set (i.e. the function returns 0).
+ By default, no event filter function is set (i.e., this function
+ returns a null EventFilter the first time it is called).
*/
QAbstractEventDispatcher::EventFilter QAbstractEventDispatcher::setEventFilter(EventFilter filter)
{
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index 1bf2425..8d43897 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -69,19 +69,19 @@
struct sockaddr;
-QT_BEGIN_NAMESPACE
-
#if defined(Q_OS_LINUX) && defined(O_CLOEXEC) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204
// Linux supports thread-safe FD_CLOEXEC
# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1
+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);
}
+QT_END_NAMESPACE
+using namespace QT_PREPEND_NAMESPACE(QtLibcSupplement);
-using namespace QtLibcSupplement;
#else
# define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 0
#endif
@@ -91,6 +91,7 @@ using namespace QtLibcSupplement;
var = cmd; \
} while (var == -1 && errno == EINTR)
+QT_BEGIN_NAMESPACE
// don't call QT_OPEN or ::open
// call qt_safe_open
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 054be70..706dc54 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -2183,21 +2183,37 @@ void QCoreApplication::removeLibraryPath(const QString &path)
/*!
\fn EventFilter QCoreApplication::setEventFilter(EventFilter filter)
- Sets the event filter \a filter. Returns a pointer to the filter
- function previously defined.
-
- The event filter is a function that is called for every message
- received in all threads. This does \e not include messages to
+ Replaces the event filter function for the QCoreApplication with
+ \a filter and returns the pointer to the replaced event filter
+ function. Only the current event filter function is called. If you
+ want to use both filter functions, save the replaced EventFilter
+ in a place where yours can call it.
+
+ The event filter function set here is called for all messages
+ received by all threads meant for all Qt objects. It is \e not
+ called for messages that are not meant for Qt objects.
+
+ The event filter function should return true if the message should
+ be filtered, (i.e. stopped). It should return false to allow
+ processing the message to continue.
+
+ By default, no event filter function is set (i.e., this function
+ returns a null EventFilter the first time it is called).
+
+ \note The filter function set here receives native messages,
+ i.e. MSG or XEvent structs, that are going to Qt objects. It is
+ called by QCoreApplication::filterEvent(). If the filter function
+ returns false to indicate the message should be processed further,
+ the native message can then be translated into a QEvent and
+ handled by the standard Qt \l{QEvent} {event} filering, e.g.
+ QObject::installEventFilter().
+
+ \note The filter function set here is different form the filter
+ function set via QAbstractEventDispatcher::setEventFilter(), which
+ gets all messages received by its thread, even messages meant for
objects that are not handled by Qt.
- The function can return true to stop the event to be processed by
- Qt, or false to continue with the standard event processing.
-
- Only one filter can be defined, but the filter can use the return
- value to call the previously set event filter. By default, no
- filter is set (i.e., the function returns 0).
-
- \sa installEventFilter()
+ \sa QObject::installEventFilter(), QAbstractEventDispatcher::setEventFilter()
*/
QCoreApplication::EventFilter
QCoreApplication::setEventFilter(QCoreApplication::EventFilter filter)
diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h
index ff2b412..233b4f9 100644
--- a/src/corelib/plugin/qplugin.h
+++ b/src/corelib/plugin/qplugin.h
@@ -63,21 +63,6 @@ typedef QObject *(*QtPluginInstanceFunction)();
void Q_CORE_EXPORT qRegisterStaticPluginInstanceFunction(QtPluginInstanceFunction function);
-struct qt_plugin_instance_deleter
-{
- qt_plugin_instance_deleter(QPointer<QObject> &instance)
- : instance_(instance)
- {
- }
-
- ~qt_plugin_instance_deleter()
- {
- delete instance_;
- }
-
- QPointer<QObject> &instance_;
-};
-
#define Q_IMPORT_PLUGIN(PLUGIN) \
extern QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance_##PLUGIN(); \
class Static##PLUGIN##PluginInstance{ \
@@ -91,10 +76,8 @@ struct qt_plugin_instance_deleter
#define Q_PLUGIN_INSTANCE(IMPLEMENTATION) \
{ \
static QT_PREPEND_NAMESPACE(QPointer)<QT_PREPEND_NAMESPACE(QObject)> _instance; \
- if (!_instance) { \
- static QT_PREPEND_NAMESPACE(qt_plugin_instance_deleter) deleter(_instance); \
+ if (!_instance) \
_instance = new IMPLEMENTATION; \
- } \
return _instance; \
}
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 24522f2..2e31c6d 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -261,9 +261,14 @@ void QAdoptedThread::run()
Returns the thread handle of the currently executing thread.
\warning The handle returned by this function is used for internal
- purposes and should not be used in any application code. On
- Windows, the returned value is a pseudo-handle for the current
- thread that cannot be used for numerical comparison.
+ purposes and should not be used in any application code.
+
+ \warning On Windows, the returned value is a pseudo-handle for the
+ current thread. It can't be used for numerical comparison. i.e.,
+ this function returns the DWORD (Windows-Thread ID) returned by
+ the Win32 function getCurrentThreadId(), not the HANDLE
+ (Windows-Thread HANDLE) returned by the Win32 function
+ getCurrentThread().
*/
/*!
diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h
index f3daca7..008c068 100644
--- a/src/corelib/tools/qringbuffer_p.h
+++ b/src/corelib/tools/qringbuffer_p.h
@@ -303,6 +303,9 @@ public:
// read an unspecified amount (will read the first buffer)
inline QByteArray read() {
+ if (bufferSize == 0)
+ return QByteArray();
+
// multiple buffers, just take the first one
if (head == 0 && tailBuffer != 0) {
QByteArray qba = buffers.takeFirst();
@@ -325,7 +328,7 @@ public:
// We can avoid by initializing the QRingBuffer with basicBlockSize of 0
// and only using this read() function.
QByteArray qba(readPointer(), nextDataBlockSize());
- buffers.takeFirst();
+ buffers.removeFirst();
head = 0;
if (tailBuffer == 0) {
buffers << QByteArray();
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 6bb0d8e..235c603 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -1235,6 +1235,8 @@ inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QStringRef
QT_END_NAMESPACE
+QT_END_HEADER
+
#ifdef QT_USE_FAST_CONCATENATION
#include <QtCore/qstringbuilder.h>
#endif
diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h
index 852c072..3b43253 100644
--- a/src/corelib/tools/qstringbuilder.h
+++ b/src/corelib/tools/qstringbuilder.h
@@ -69,7 +69,7 @@ private:
};
-template <typename T> class QConcatenable {};
+template <typename T> struct QConcatenable {};
template <typename A, typename B>
class QStringBuilder
@@ -202,6 +202,18 @@ template <> struct QConcatenable<const char *>
*out++ = QLatin1Char(*a++);
}
};
+
+template <> struct QConcatenable<QByteArray>
+{
+ typedef QByteArray type;
+ static int size(const QByteArray &ba) { return qstrnlen(ba.constData(), ba.size()); }
+ static inline void appendTo(const QByteArray &ba, QChar *&out)
+ {
+ const char *data = ba.constData();
+ while (*data)
+ *out++ = QLatin1Char(*data++);
+ }
+};
#endif
template <typename A, typename B>
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index 6777aa5..14cadd9 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -973,8 +973,15 @@ QDBusConnection QDBusConnection::systemBus()
}
/*!
+ \nonreentrant
+
Returns the connection that sent the signal, if called in a slot activated
by QDBus; otherwise it returns 0.
+
+ \note Please avoid this function. This function is not thread-safe, so if
+ there's any other thread delivering a D-Bus call, this function may return
+ the wrong connection. In new code, please use QDBusContext::connection()
+ (see that class for a description on how to use it).
*/
QDBusConnection QDBusConnection::sender()
{
diff --git a/src/gui/dialogs/qfiledialog_p.h b/src/gui/dialogs/qfiledialog_p.h
index d798f9d..4c599cc 100644
--- a/src/gui/dialogs/qfiledialog_p.h
+++ b/src/gui/dialogs/qfiledialog_p.h
@@ -73,7 +73,6 @@
#include <qabstractproxymodel.h>
#include <qcompleter.h>
#include <qpointer.h>
-#include <qtimeline.h>
#include <qdebug.h>
#include "qsidebar_p.h"
diff --git a/src/gui/dialogs/qsidebar.cpp b/src/gui/dialogs/qsidebar.cpp
index 1915e21..e4821ad 100644
--- a/src/gui/dialogs/qsidebar.cpp
+++ b/src/gui/dialogs/qsidebar.cpp
@@ -247,11 +247,16 @@ void QUrlModel::addUrls(const QList<QUrl> &list, int row, bool move)
QUrl url = list.at(i);
if (!url.isValid() || url.scheme() != QLatin1String("file"))
continue;
+ //this makes sure the url is clean
+ const QString cleanUrl = QDir::cleanPath(url.toLocalFile());
+ url = QUrl::fromLocalFile(cleanUrl);
+
for (int j = 0; move && j < rowCount(); ++j) {
+ QString local = index(j, 0).data(UrlRole).toUrl().toLocalFile();
#if defined(Q_OS_WIN)
- if (QDir::cleanPath(index(j, 0).data(UrlRole).toUrl().toLocalFile()).toLower() == QDir::cleanPath(url.toLocalFile()).toLower()) {
+ if (index(j, 0).data(UrlRole).toUrl().toLocalFile().toLower() == cleanUrl.toLower()) {
#else
- if (QDir::cleanPath(index(j, 0).data(UrlRole).toUrl().toLocalFile()) == QDir::cleanPath(url.toLocalFile())) {
+ if (index(j, 0).data(UrlRole).toUrl().toLocalFile() == cleanUrl) {
#endif
removeRow(j);
if (j <= row)
@@ -260,12 +265,12 @@ void QUrlModel::addUrls(const QList<QUrl> &list, int row, bool move)
}
}
row = qMax(row, 0);
- QModelIndex idx = fileSystemModel->index(url.toLocalFile());
+ QModelIndex idx = fileSystemModel->index(cleanUrl);
if (!fileSystemModel->isDir(idx))
continue;
insertRows(row, 1);
setUrl(index(row, 0), url, idx);
- watching.append(QPair<QModelIndex, QString>(idx, url.toLocalFile()));
+ watching.append(qMakePair(idx, cleanUrl));
}
}
diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri
index 4cee6d6..0c0747e 100644
--- a/src/gui/graphicsview/graphicsview.pri
+++ b/src/gui/graphicsview/graphicsview.pri
@@ -1,37 +1,42 @@
# Qt graphicsview module
-HEADERS += graphicsview/qgraphicsitem.h \
+HEADERS += graphicsview/qgraphicsgridlayout.h \
+ graphicsview/qgraphicsitem.h \
graphicsview/qgraphicsitem_p.h \
graphicsview/qgraphicsitemanimation.h \
- graphicsview/qgraphicsscene.h \
- graphicsview/qgraphicsscene_p.h \
- graphicsview/qgraphicsscene_bsp_p.h \
- graphicsview/qgraphicssceneevent.h \
- graphicsview/qgraphicsview_p.h \
- graphicsview/qgraphicsview.h
-SOURCES += graphicsview/qgraphicsitem.cpp \
- graphicsview/qgraphicsitemanimation.cpp \
- graphicsview/qgraphicsscene.cpp \
- graphicsview/qgraphicsscene_bsp.cpp \
- graphicsview/qgraphicssceneevent.cpp \
- graphicsview/qgraphicsview.cpp
-
-# Widgets on the canvas
-HEADERS += graphicsview/qgraphicslayout.h \
+ graphicsview/qgraphicslayout.h \
graphicsview/qgraphicslayout_p.h \
graphicsview/qgraphicslayoutitem.h \
graphicsview/qgraphicslayoutitem_p.h \
graphicsview/qgraphicslinearlayout.h \
+ graphicsview/qgraphicsproxywidget.h \
+ graphicsview/qgraphicsscene.h \
+ graphicsview/qgraphicsscene_bsp_p.h \
+ graphicsview/qgraphicsscene_p.h \
+ graphicsview/qgraphicsscenebsptreeindex_p.h \
+ graphicsview/qgraphicssceneevent.h \
+ graphicsview/qgraphicssceneindex_p.h \
+ graphicsview/qgraphicsscenelinearindex_p.h \
+ graphicsview/qgraphicsview.h \
+ graphicsview/qgraphicsview_p.h \
graphicsview/qgraphicswidget.h \
graphicsview/qgraphicswidget_p.h \
- graphicsview/qgridlayoutengine_p.h \
- graphicsview/qgraphicsproxywidget.h \
- graphicsview/qgraphicsgridlayout.h
-SOURCES += graphicsview/qgraphicslayout.cpp \
+ graphicsview/qgridlayoutengine_p.h
+
+SOURCES += graphicsview/qgraphicsgridlayout.cpp \
+ graphicsview/qgraphicsitem.cpp \
+ graphicsview/qgraphicsitemanimation.cpp \
+ graphicsview/qgraphicslayout.cpp \
graphicsview/qgraphicslayout_p.cpp \
graphicsview/qgraphicslayoutitem.cpp \
graphicsview/qgraphicslinearlayout.cpp \
+ graphicsview/qgraphicsproxywidget.cpp \
+ graphicsview/qgraphicsscene.cpp \
+ graphicsview/qgraphicsscene_bsp.cpp \
+ graphicsview/qgraphicsscenebsptreeindex.cpp \
+ graphicsview/qgraphicssceneevent.cpp \
+ graphicsview/qgraphicssceneindex.cpp \
+ graphicsview/qgraphicsscenelinearindex.cpp \
+ graphicsview/qgraphicsview.cpp \
graphicsview/qgraphicswidget.cpp \
graphicsview/qgraphicswidget_p.cpp \
- graphicsview/qgridlayoutengine.cpp \
- graphicsview/qgraphicsproxywidget.cpp \
- graphicsview/qgraphicsgridlayout.cpp
+ graphicsview/qgridlayoutengine.cpp
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index a5ee7e6..03014d8 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -558,6 +558,7 @@
#include "qgraphicsview.h"
#include "qgraphicswidget.h"
#include "qgraphicsproxywidget.h"
+#include "qgraphicsscenebsptreeindex_p.h"
#include <QtCore/qbitarray.h>
#include <QtCore/qdebug.h>
#include <QtCore/qpoint.h>
@@ -588,17 +589,6 @@
QT_BEGIN_NAMESPACE
-// QRectF::intersects() returns false always if either the source or target
-// rectangle's width or height are 0. This works around that problem.
-static inline void _q_adjustRect(QRectF *rect)
-{
- Q_ASSERT(rect);
- if (!rect->width())
- rect->adjust(-0.00001, 0, 0.00001, 0);
- if (!rect->height())
- rect->adjust(0, -0.00001, 0, 0.00001);
-}
-
static inline void _q_adjustRect(QRect *rect)
{
Q_ASSERT(rect);
@@ -832,6 +822,42 @@ void QGraphicsItemPrivate::combineTransformFromParent(QTransform *x, const QTran
}
}
+void QGraphicsItemPrivate::updateSceneTransformFromParent()
+{
+ if (parent) {
+ Q_ASSERT(!parent->d_ptr->dirtySceneTransform);
+ if (parent->d_ptr->sceneTransformTranslateOnly) {
+ sceneTransform = QTransform::fromTranslate(parent->d_ptr->sceneTransform.dx() + pos.x(),
+ parent->d_ptr->sceneTransform.dy() + pos.y());
+ } else {
+ sceneTransform = parent->d_ptr->sceneTransform;
+ sceneTransform.translate(pos.x(), pos.y());
+ }
+ if (transformData) {
+ sceneTransform = transformData->computedFullTransform(&sceneTransform);
+ sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
+ } else {
+ sceneTransformTranslateOnly = parent->d_ptr->sceneTransformTranslateOnly;
+ }
+ } else if (!transformData) {
+ sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
+ sceneTransformTranslateOnly = 1;
+ } else if (transformData->onlyTransform) {
+ sceneTransform = transformData->transform;
+ if (!pos.isNull())
+ sceneTransform *= QTransform::fromTranslate(pos.x(), pos.y());
+ sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
+ } else if (pos.isNull()) {
+ sceneTransform = transformData->computedFullTransform();
+ sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
+ } else {
+ sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
+ sceneTransform = transformData->computedFullTransform(&sceneTransform);
+ sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
+ }
+ dirtySceneTransform = 0;
+}
+
/*!
\internal
@@ -871,6 +897,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
if (newParent == parent)
return;
+ if (scene) {
+ // Deliver the change to the index
+ scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant);
+ }
+
if (QGraphicsWidget *w = isWidget ? static_cast<QGraphicsWidget *>(q) : q->parentWidget()) {
// Update the child focus chain; when reparenting a widget that has a
// focus child, ensure that that focus child clears its focus child
@@ -958,12 +989,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
}
}
- if (scene) {
- // Invalidate any sort caching; arrival of a new item means we need to
- // resort.
- scene->d_func()->invalidateSortCache();
- }
-
// Resolve depth.
resolveDepth(parent ? parent->d_ptr->depth : -1);
dirtySceneTransform = 1;
@@ -1442,6 +1467,8 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags)
flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
if (quint32(d_ptr->flags) == quint32(flags))
return;
+ if (d_ptr->scene)
+ d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags));
// Flags that alter the geometry of the item (or its children).
const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations);
@@ -1800,6 +1827,8 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
if (q_ptr->isSelected())
q_ptr->setSelected(false);
} else {
+ geometryChanged = 1;
+ paintedViewBoundingRectsNeedRepaint = 1;
if (isWidget && scene) {
QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
if (widget->windowType() == Qt::Popup)
@@ -3160,7 +3189,8 @@ void QGraphicsItem::setTransformOrigin(const QPointF &origin)
*/
QMatrix QGraphicsItem::sceneMatrix() const
{
- return sceneTransform().toAffine();
+ d_ptr->ensureSceneTransform();
+ return d_ptr->sceneTransform.toAffine();
}
@@ -3183,16 +3213,7 @@ QMatrix QGraphicsItem::sceneMatrix() const
*/
QTransform QGraphicsItem::sceneTransform() const
{
- if (d_ptr->dirtySceneTransform) {
- // This item and all its descendants have dirty scene transforms.
- // We're about to validate this item's scene transform, so we have to
- // invalidate all the children; otherwise there's no way for the descendants
- // to detect that the ancestor has changed.
- d_ptr->invalidateChildrenSceneTransform();
- }
-
- QGraphicsItem *that = const_cast<QGraphicsItem *>(this);
- d_ptr->ensureSceneTransformRecursive(&that);
+ d_ptr->ensureSceneTransform();
return d_ptr->sceneTransform;
}
@@ -3222,8 +3243,10 @@ QTransform QGraphicsItem::sceneTransform() const
QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) const
{
// Ensure we return the standard transform if we're not untransformable.
- if (!d_ptr->itemIsUntransformable())
- return sceneTransform() * viewportTransform;
+ if (!d_ptr->itemIsUntransformable()) {
+ d_ptr->ensureSceneTransform();
+ return d_ptr->sceneTransform * viewportTransform;
+ }
// Find the topmost item that ignores view transformations.
const QGraphicsItem *untransformedAncestor = this;
@@ -3242,7 +3265,8 @@ QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) c
}
// First translate the base untransformable item.
- QPointF mappedPoint = (untransformedAncestor->sceneTransform() * viewportTransform).map(QPointF(0, 0));
+ untransformedAncestor->d_ptr->ensureSceneTransform();
+ QPointF mappedPoint = (untransformedAncestor->d_ptr->sceneTransform * viewportTransform).map(QPointF(0, 0));
// COMBINE
QTransform matrix = QTransform::fromTranslate(mappedPoint.x(), mappedPoint.y());
@@ -3335,8 +3359,11 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co
// Find the closest common ancestor. If the two items don't share an
// ancestor, then the only way is to combine their scene transforms.
const QGraphicsItem *commonAncestor = commonAncestorItem(other);
- if (!commonAncestor)
- return sceneTransform() * other->sceneTransform().inverted(ok);
+ if (!commonAncestor) {
+ d_ptr->ensureSceneTransform();
+ other->d_ptr->ensureSceneTransform();
+ return d_ptr->sceneTransform * other->d_ptr->sceneTransform.inverted(ok);
+ }
// If the two items are cousins (in sibling branches), map both to the
// common ancestor, and combine the two transforms.
@@ -3627,18 +3654,20 @@ void QGraphicsItem::setZValue(qreal z)
qreal newZ = qreal(newZVariant.toDouble());
if (newZ == d_ptr->z)
return;
+
+ if (d_ptr->scene) {
+ // Z Value has changed, we have to notify the index.
+ d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, newZVariant);
+ }
+
d_ptr->z = newZ;
if (d_ptr->parent)
d_ptr->parent->d_ptr->needSortChildren = 1;
else if (d_ptr->scene)
d_ptr->scene->d_func()->needSortTopLevelItems = 1;
- if (d_ptr->scene) {
+ if (d_ptr->scene)
d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
- // Invalidate any sort caching; arrival of a new item means we need to
- // resort.
- d_ptr->scene->d_func()->invalidateSortCache();
- }
itemChange(ItemZValueHasChanged, newZVariant);
@@ -3729,7 +3758,13 @@ QRectF QGraphicsItem::sceneBoundingRect() const
QRectF br = boundingRect();
br.translate(offset);
- return !parentItem ? br : parentItem->sceneTransform().mapRect(br);
+ if (!parentItem)
+ return br;
+ if (parentItem->d_ptr->hasTranslateOnlySceneTransform()) {
+ br.translate(parentItem->d_ptr->sceneTransform.dx(), parentItem->d_ptr->sceneTransform.dy());
+ return br;
+ }
+ return parentItem->d_ptr->sceneTransform.mapRect(br);
}
/*!
@@ -4104,7 +4139,7 @@ bool QGraphicsItem::isObscuredBy(const QGraphicsItem *item) const
{
if (!item)
return false;
- return QGraphicsScenePrivate::closestItemFirst_withoutCache(item, this)
+ return QGraphicsSceneBspTreeIndexPrivate::closestItemFirst_withoutCache(item, this)
&& qt_QGraphicsItem_isObscured(this, item, boundingRect());
}
@@ -4297,12 +4332,11 @@ bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, bool ignore
{
// No scene, or if the scene is updating everything, means we have nothing
// to do. The only exception is if the scene tracks the growing scene rect.
- return (!visible && !ignoreVisibleBit)
+ return !scene
+ || (!visible && !ignoreVisibleBit && !this->ignoreVisible)
|| (!ignoreDirtyBit && fullUpdatePending)
- || !scene
- || (scene->d_func()->updateAll && scene->d_func()->hasSceneRect)
|| (!ignoreClipping && (childrenClippedToShape() && isClippedAway()))
- || (!ignoreOpacity && childrenCombineOpacity() && isFullyTransparent());
+ || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent());
}
/*!
@@ -4323,6 +4357,7 @@ void QGraphicsItemPrivate::resolveDepth(int parentDepth)
void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
{
needSortChildren = 1;
+ child->d_ptr->siblingIndex = children.size();
children.append(child);
}
@@ -4332,6 +4367,10 @@ void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
void QGraphicsItemPrivate::removeChild(QGraphicsItem *child)
{
children.removeOne(child);
+ // NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
+ // the child is not guaranteed to be at the index after the list is sorted.
+ // (see ensureSortedChildren()).
+ child->d_ptr->siblingIndex = -1;
}
/*!
@@ -4492,9 +4531,22 @@ void QGraphicsItemPrivate::ensureSceneTransformRecursive(QGraphicsItem **topMost
}
// COMBINE my transform with the parent's scene transform.
- sceneTransform = parent ? parent->d_ptr->sceneTransform : QTransform();
- combineTransformFromParent(&sceneTransform);
- dirtySceneTransform = 0;
+ updateSceneTransformFromParent();
+ Q_ASSERT(!dirtySceneTransform);
+}
+
+void QGraphicsItemPrivate::ensureSceneTransform()
+{
+ if (dirtySceneTransform) {
+ // This item and all its descendants have dirty scene transforms.
+ // We're about to validate this item's scene transform, so we have to
+ // invalidate all the children; otherwise there's no way for the descendants
+ // to detect that the ancestor has changed.
+ invalidateChildrenSceneTransform();
+ }
+
+ QGraphicsItem *that = q_func();
+ ensureSceneTransformRecursive(&that);
}
/*!
@@ -4835,7 +4887,9 @@ QPointF QGraphicsItem::mapToParent(const QPointF &point) const
*/
QPointF QGraphicsItem::mapToScene(const QPointF &point) const
{
- return sceneTransform().map(point);
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return QPointF(point.x() + d_ptr->sceneTransform.dx(), point.y() + d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.map(point);
}
/*!
@@ -4902,7 +4956,9 @@ QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const
*/
QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const
{
- return sceneTransform().map(rect);
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.map(rect);
}
/*!
@@ -4975,7 +5031,9 @@ QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const
*/
QRectF QGraphicsItem::mapRectToScene(const QRectF &rect) const
{
- return sceneTransform().mapRect(rect);
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.mapRect(rect);
}
/*!
@@ -5049,7 +5107,9 @@ QRectF QGraphicsItem::mapRectFromParent(const QRectF &rect) const
*/
QRectF QGraphicsItem::mapRectFromScene(const QRectF &rect) const
{
- return sceneTransform().inverted().mapRect(rect);
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.inverted().mapRect(rect);
}
/*!
@@ -5101,7 +5161,9 @@ QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
*/
QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const
{
- return sceneTransform().map(polygon);
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return polygon.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.map(polygon);
}
/*!
@@ -5146,7 +5208,9 @@ QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const
*/
QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const
{
- return sceneTransform().map(path);
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return path.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.map(path);
}
/*!
@@ -5207,7 +5271,9 @@ QPointF QGraphicsItem::mapFromParent(const QPointF &point) const
*/
QPointF QGraphicsItem::mapFromScene(const QPointF &point) const
{
- return sceneTransform().inverted().map(point);
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return QPointF(point.x() - d_ptr->sceneTransform.dx(), point.y() - d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.inverted().map(point);
}
/*!
@@ -5275,7 +5341,9 @@ QPolygonF QGraphicsItem::mapFromParent(const QRectF &rect) const
*/
QPolygonF QGraphicsItem::mapFromScene(const QRectF &rect) const
{
- return sceneTransform().inverted().map(rect);
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.inverted().map(rect);
}
/*!
@@ -5325,7 +5393,9 @@ QPolygonF QGraphicsItem::mapFromParent(const QPolygonF &polygon) const
*/
QPolygonF QGraphicsItem::mapFromScene(const QPolygonF &polygon) const
{
- return sceneTransform().inverted().map(polygon);
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return polygon.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.inverted().map(polygon);
}
/*!
@@ -5368,7 +5438,9 @@ QPainterPath QGraphicsItem::mapFromParent(const QPainterPath &path) const
*/
QPainterPath QGraphicsItem::mapFromScene(const QPainterPath &path) const
{
- return sceneTransform().inverted().map(path);
+ if (d_ptr->hasTranslateOnlySceneTransform())
+ return path.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
+ return d_ptr->sceneTransform.inverted().map(path);
}
/*!
@@ -6333,7 +6405,7 @@ void QGraphicsItem::addToIndex()
return;
}
if (d_ptr->scene)
- d_ptr->scene->d_func()->addToIndex(this);
+ d_ptr->scene->d_func()->index->addItem(this);
}
/*!
@@ -6350,7 +6422,7 @@ void QGraphicsItem::removeFromIndex()
return;
}
if (d_ptr->scene)
- d_ptr->scene->d_func()->removeFromIndex(this);
+ d_ptr->scene->d_func()->index->removeItem(this);
}
/*!
@@ -6369,10 +6441,12 @@ void QGraphicsItem::removeFromIndex()
void QGraphicsItem::prepareGeometryChange()
{
if (d_ptr->scene) {
+ d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true;
d_ptr->geometryChanged = 1;
d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
+ scenePrivate->index->prepareBoundingRectChange(this);
scenePrivate->markDirty(this, QRectF(),
/*invalidateChildren=*/true,
/*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper);
@@ -6383,10 +6457,13 @@ void QGraphicsItem::prepareGeometryChange()
// _q_processDirtyItems is called before _q_emitUpdated.
if ((scenePrivate->connectedSignals & scenePrivate->changedSignalMask)
|| scenePrivate->views.isEmpty()) {
- d_ptr->scene->update(sceneTransform().mapRect(boundingRect()));
+ if (d_ptr->hasTranslateOnlySceneTransform()) {
+ d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(),
+ d_ptr->sceneTransform.dy()));
+ } else {
+ d_ptr->scene->update(d_ptr->sceneTransform.mapRect(boundingRect()));
+ }
}
-
- scenePrivate->removeFromIndex(this);
}
QGraphicsItem *parent = this;
@@ -9706,17 +9783,11 @@ QDebug operator<<(QDebug debug, QGraphicsItem *item)
return debug;
}
- QStringList flags;
- if (item->isVisible()) flags << QLatin1String("isVisible");
- if (item->isEnabled()) flags << QLatin1String("isEnabled");
- if (item->isSelected()) flags << QLatin1String("isSelected");
- if (item->hasFocus()) flags << QLatin1String("HasFocus");
-
debug << "QGraphicsItem(this =" << ((void*)item)
<< ", parent =" << ((void*)item->parentItem())
<< ", pos =" << item->pos()
- << ", z =" << item->zValue() << ", flags = {"
- << flags.join(QLatin1String("|")) << " })";
+ << ", z =" << item->zValue() << ", flags = "
+ << item->flags() << ")";
return debug;
}
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index d26110a..72c4830 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -142,7 +142,7 @@ public:
QGraphicsItem(QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
@@ -209,8 +209,8 @@ public:
Qt::MouseButtons acceptedMouseButtons() const;
void setAcceptedMouseButtons(Qt::MouseButtons buttons);
- bool acceptsHoverEvents() const; // obsolete
- void setAcceptsHoverEvents(bool enabled); // obsolete
+ bool acceptsHoverEvents() const; // ### obsolete
+ void setAcceptsHoverEvents(bool enabled); // ### obsolete
bool acceptHoverEvents() const;
void setAcceptHoverEvents(bool enabled);
bool acceptTouchEvents() const;
@@ -437,11 +437,16 @@ private:
friend class QGraphicsScene;
friend class QGraphicsScenePrivate;
friend class QGraphicsSceneFindItemBspTreeVisitor;
+ friend class QGraphicsSceneBspTree;
friend class QGraphicsView;
friend class QGraphicsViewPrivate;
friend class QGraphicsWidget;
friend class QGraphicsWidgetPrivate;
friend class QGraphicsProxyWidgetPrivate;
+ friend class QGraphicsSceneIndex;
+ friend class QGraphicsSceneIndexPrivate;
+ friend class QGraphicsSceneBspTreeIndex;
+ friend class QGraphicsSceneBspTreeIndexPrivate;
friend class ::tst_QGraphicsItem;
friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *);
friend bool qt_closestItemFirst(const QGraphicsItem *, const QGraphicsItem *);
@@ -533,7 +538,7 @@ class Q_GUI_EXPORT QAbstractGraphicsShapeItem : public QGraphicsItem
public:
QAbstractGraphicsShapeItem(QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
@@ -563,13 +568,13 @@ class Q_GUI_EXPORT QGraphicsPathItem : public QAbstractGraphicsShapeItem
public:
QGraphicsPathItem(QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
QGraphicsPathItem(const QPainterPath &path, QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
@@ -606,19 +611,19 @@ class Q_GUI_EXPORT QGraphicsRectItem : public QAbstractGraphicsShapeItem
public:
QGraphicsRectItem(QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
@@ -659,19 +664,19 @@ class Q_GUI_EXPORT QGraphicsEllipseItem : public QAbstractGraphicsShapeItem
public:
QGraphicsEllipseItem(QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
@@ -718,14 +723,14 @@ class Q_GUI_EXPORT QGraphicsPolygonItem : public QAbstractGraphicsShapeItem
public:
QGraphicsPolygonItem(QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
QGraphicsPolygonItem(const QPolygonF &polygon,
QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
@@ -765,19 +770,19 @@ class Q_GUI_EXPORT QGraphicsLineItem : public QGraphicsItem
public:
QGraphicsLineItem(QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
@@ -825,13 +830,13 @@ public:
QGraphicsPixmapItem(QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
QGraphicsPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
@@ -887,13 +892,13 @@ class Q_GUI_EXPORT QGraphicsTextItem : public QGraphicsObject
public:
QGraphicsTextItem(QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
QGraphicsTextItem(const QString &text, QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
@@ -988,13 +993,13 @@ class Q_GUI_EXPORT QGraphicsSimpleTextItem : public QAbstractGraphicsShapeItem
public:
QGraphicsSimpleTextItem(QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
@@ -1034,7 +1039,7 @@ class Q_GUI_EXPORT QGraphicsItemGroup : public QGraphicsItem
public:
QGraphicsItemGroup(QGraphicsItem *parent = 0
#ifndef Q_QDOC
- // obsolete argument
+ // ### obsolete argument
, QGraphicsScene *scene = 0
#endif
);
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 46ec6fe..9bdd273 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -119,6 +119,7 @@ public:
parent(0),
transformData(0),
index(-1),
+ siblingIndex(-1),
depth(0),
acceptedMouseButtons(0x1f),
visible(1),
@@ -149,13 +150,14 @@ public:
dirtyChildrenBoundingRect(1),
paintedViewBoundingRectsNeedRepaint(0),
dirtySceneTransform(1),
- geometryChanged(0),
+ geometryChanged(1),
inDestructor(0),
isObject(0),
ignoreVisible(0),
ignoreOpacity(0),
acceptTouchEvents(0),
acceptedTouchBeginEvent(0),
+ sceneTransformTranslateOnly(0),
globalStackingOrder(-1),
q_ptr(0)
{
@@ -164,6 +166,15 @@ public:
inline virtual ~QGraphicsItemPrivate()
{ }
+ static const QGraphicsItemPrivate *get(const QGraphicsItem *item)
+ {
+ return item->d_ptr;
+ }
+ static QGraphicsItemPrivate *get(QGraphicsItem *item)
+ {
+ return item->d_ptr;
+ }
+
void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
AncestorFlag flag = NoFlag, bool enabled = false, bool root = true);
void setIsMemberOfGroup(bool enabled);
@@ -177,6 +188,7 @@ public:
void combineTransformToParent(QTransform *x, const QTransform *viewTransform = 0) const;
void combineTransformFromParent(QTransform *x, const QTransform *viewTransform = 0) const;
+ void updateSceneTransformFromParent();
// ### Qt 5: Remove. Workaround for reimplementation added after Qt 4.4.
virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const;
@@ -286,6 +298,13 @@ public:
void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF());
void updateCachedClipPathFromSetPosHelper(const QPointF &newPos);
void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem);
+ void ensureSceneTransform();
+
+ inline bool hasTranslateOnlySceneTransform()
+ {
+ ensureSceneTransform();
+ return sceneTransformTranslateOnly;
+ }
inline void invalidateChildrenSceneTransform()
{
@@ -370,6 +389,7 @@ public:
}
inline QTransform transformToParent() const;
+ inline void ensureSortedChildren();
QPainterPath cachedClipPath;
QRectF childrenBoundingRect;
@@ -385,6 +405,7 @@ public:
TransformData *transformData;
QTransform sceneTransform;
int index;
+ int siblingIndex;
int depth;
// Packed 32 bytes
@@ -426,7 +447,8 @@ public:
quint32 ignoreOpacity : 1;
quint32 acceptTouchEvents : 1;
quint32 acceptedTouchBeginEvent : 1;
- quint32 unused : 9; // feel free to use
+ quint32 sceneTransformTranslateOnly : 1;
+ quint32 unused : 8; // feel free to use
// Optional stacking order
int globalStackingOrder;
@@ -457,6 +479,10 @@ struct QGraphicsItemPrivate::TransformData {
if (onlyTransform) {
if (!postmultiplyTransform)
return transform;
+ if (postmultiplyTransform->isIdentity())
+ return transform;
+ if (transform.isIdentity())
+ return *postmultiplyTransform;
QTransform x(transform);
x *= *postmultiplyTransform;
return x;
@@ -477,6 +503,29 @@ struct QGraphicsItemPrivate::TransformData {
}
};
+/*!
+ \internal
+*/
+inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
+{
+ // Return true if sibling item1 is on top of item2.
+ const QGraphicsItemPrivate *d1 = item1->d_ptr;
+ const QGraphicsItemPrivate *d2 = item2->d_ptr;
+ bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent;
+ bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent;
+ if (f1 != f2)
+ return f2;
+ if (d1->z != d2->z)
+ return d1->z > d2->z;
+ return d1->siblingIndex > d2->siblingIndex;
+}
+
+/*!
+ \internal
+*/
+static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
+{ return qt_closestLeaf(item2, item1); }
+
/*
return the full transform of the item to the parent. This include the position and all the transform data
*/
@@ -487,6 +536,14 @@ inline QTransform QGraphicsItemPrivate::transformToParent() const
return matrix;
}
+inline void QGraphicsItemPrivate::ensureSortedChildren()
+{
+ if (needSortChildren) {
+ qSort(children.begin(), children.end(), qt_notclosestLeaf);
+ needSortChildren = 0;
+ }
+}
+
QT_END_NAMESPACE
#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 0c3abd4..c8e178a 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -39,7 +39,6 @@
**
****************************************************************************/
-
/*!
\class QGraphicsScene
\brief The QGraphicsScene class provides a surface for managing a large
@@ -218,6 +217,9 @@
#include "qgraphicsview_p.h"
#include "qgraphicswidget.h"
#include "qgraphicswidget_p.h"
+#include "qgraphicssceneindex_p.h"
+#include "qgraphicsscenebsptreeindex_p.h"
+#include "qgraphicsscenelinearindex_p.h"
#include <QtCore/qdebug.h>
#include <QtCore/qlist.h>
@@ -251,67 +253,6 @@
QT_BEGIN_NAMESPACE
-static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2);
-
-static inline bool QRectF_intersects(const QRectF &s, const QRectF &r)
-{
- qreal xp = s.left();
- qreal yp = s.top();
- qreal w = s.width();
- qreal h = s.height();
- qreal l1 = xp;
- qreal r1 = xp;
- if (w < 0)
- l1 += w;
- else
- r1 += w;
-
- qreal l2 = r.left();
- qreal r2 = r.left();
- if (w < 0)
- l2 += r.width();
- else
- r2 += r.width();
-
- if (l1 >= r2 || l2 >= r1)
- return false;
-
- qreal t1 = yp;
- qreal b1 = yp;
- if (h < 0)
- t1 += h;
- else
- b1 += h;
-
- qreal t2 = r.top();
- qreal b2 = r.top();
- if (r.height() < 0)
- t2 += r.height();
- else
- b2 += r.height();
-
- return !(t1 >= b2 || t2 >= b1);
-}
-
-// QRectF::intersects() returns false always if either the source or target
-// rectangle's width or height are 0. This works around that problem.
-static inline void _q_adjustRect(QRectF *rect)
-{
- Q_ASSERT(rect);
- if (!rect->width())
- rect->adjust(-0.00001, 0, 0.00001, 0);
- if (!rect->height())
- rect->adjust(0, -0.00001, 0, 0.00001);
-}
-
-static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
-{
- Q_ASSERT(item);
- QRectF boundingRect(item->boundingRect());
- _q_adjustRect(&boundingRect);
- return boundingRect;
-}
-
static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent)
{
hover->setWidget(mouseEvent->widget());
@@ -331,18 +272,15 @@ static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraph
QGraphicsScenePrivate::QGraphicsScenePrivate()
: changedSignalMask(0),
indexMethod(QGraphicsScene::BspTreeIndex),
- bspTreeDepth(0),
+ index(0),
lastItemCount(0),
hasSceneRect(false),
+ dirtyGrowingItemsBoundingRect(true),
updateAll(false),
calledEmitUpdated(false),
processDirtyItemsEmitted(false),
selectionChanging(0),
needSortTopLevelItems(true),
- regenerateIndex(true),
- purgePending(false),
- indexTimerId(0),
- restartIndexTimer(false),
stickyFocus(false),
hasFocus(false),
focusItem(0),
@@ -359,7 +297,6 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
allItemsUseDefaultCursor(true),
painterStateProtection(true),
sortCacheEnabled(false),
- updatingSortCache(false),
style(0),
allItemsIgnoreTouchEvents(true)
{
@@ -372,6 +309,8 @@ void QGraphicsScenePrivate::init()
{
Q_Q(QGraphicsScene);
+ index = new QGraphicsSceneBspTreeIndex(q);
+
// Keep this index so we can check for connected slots later on.
changedSignalMask = (1 << q->metaObject()->indexOfSignal("changed(QList<QRectF>)"));
qApp->d_func()->scene_list.append(q);
@@ -381,223 +320,25 @@ void QGraphicsScenePrivate::init()
/*!
\internal
*/
-QList<QGraphicsItem *> QGraphicsScenePrivate::estimateItemsInRect(const QRectF &rect) const
-{
- const_cast<QGraphicsScenePrivate *>(this)->purgeRemovedItems();
- const_cast<QGraphicsScenePrivate *>(this)->_q_updateSortCache();
-
- if (indexMethod == QGraphicsScene::BspTreeIndex) {
- // ### Only do this once in a while.
- QGraphicsScenePrivate *that = const_cast<QGraphicsScenePrivate *>(this);
-
- // Get items from BSP tree
- QList<QGraphicsItem *> items = that->bspTree.items(rect);
-
- // Fill in with any unindexed items
- for (int i = 0; i < unindexedItems.size(); ++i) {
- if (QGraphicsItem *item = unindexedItems.at(i)) {
- if (!item->d_ptr->itemDiscovered && item->d_ptr->visible && !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) {
- QRectF boundingRect = item->sceneBoundingRect();
- if (QRectF_intersects(boundingRect, rect)) {
- item->d_ptr->itemDiscovered = 1;
- items << item;
- }
- }
- }
- }
-
- // Reset the discovered state of all discovered items
- for (int i = 0; i < items.size(); ++i)
- items.at(i)->d_func()->itemDiscovered = 0;
- return items;
- }
-
- QList<QGraphicsItem *> itemsInRect;
- for (int i = 0; i < unindexedItems.size(); ++i) {
- if (QGraphicsItem *item = unindexedItems.at(i)) {
- if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
- continue;
- if (item->d_ptr->visible && !item->d_ptr->isFullyTransparent())
- itemsInRect << item;
- }
- }
- for (int i = 0; i < indexedItems.size(); ++i) {
- if (QGraphicsItem *item = indexedItems.at(i)) {
- if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
- continue;
- if (item->d_ptr->visible && !item->d_ptr->isFullyTransparent())
- itemsInRect << item;
- }
- }
-
- return itemsInRect;
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::addToIndex(QGraphicsItem *item)
-{
- if (indexMethod == QGraphicsScene::BspTreeIndex) {
- if (item->d_func()->index != -1) {
- bspTree.insertItem(item, item->sceneBoundingRect());
- foreach (QGraphicsItem *child, item->children())
- child->addToIndex();
- } else {
- // The BSP tree is regenerated if the number of items grows to a
- // certain threshold, or if the bounding rect of the graph doubles in
- // size.
- startIndexTimer();
- }
- }
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::removeFromIndex(QGraphicsItem *item)
-{
- if (indexMethod == QGraphicsScene::BspTreeIndex) {
- int index = item->d_func()->index;
- if (index != -1) {
- bspTree.removeItem(item, item->sceneBoundingRect());
- freeItemIndexes << index;
- indexedItems[index] = 0;
- item->d_func()->index = -1;
- unindexedItems << item;
-
- foreach (QGraphicsItem *child, item->children())
- child->removeFromIndex();
- }
-
- startIndexTimer();
- }
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::resetIndex()
-{
- purgeRemovedItems();
- if (indexMethod == QGraphicsScene::BspTreeIndex) {
- for (int i = 0; i < indexedItems.size(); ++i) {
- if (QGraphicsItem *item = indexedItems.at(i)) {
- item->d_ptr->index = -1;
- unindexedItems << item;
- }
- }
- indexedItems.clear();
- freeItemIndexes.clear();
- regenerateIndex = true;
- startIndexTimer();
- }
-}
-
-static inline int intmaxlog(int n)
+QGraphicsScenePrivate *QGraphicsScenePrivate::get(QGraphicsScene *q)
{
- return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0);
+ return q->d_func();
}
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::_q_updateIndex()
+void QGraphicsScenePrivate::_q_emitUpdated()
{
- if (!indexTimerId)
- return;
-
Q_Q(QGraphicsScene);
- q->killTimer(indexTimerId);
- indexTimerId = 0;
-
- purgeRemovedItems();
-
- // Add unindexedItems to indexedItems
- QRectF unindexedItemsBoundingRect;
- for (int i = 0; i < unindexedItems.size(); ++i) {
- if (QGraphicsItem *item = unindexedItems.at(i)) {
- unindexedItemsBoundingRect |= item->sceneBoundingRect();
- if (!freeItemIndexes.isEmpty()) {
- int freeIndex = freeItemIndexes.takeFirst();
- item->d_func()->index = freeIndex;
- indexedItems[freeIndex] = item;
- } else {
- item->d_func()->index = indexedItems.size();
- indexedItems << item;
- }
- }
- }
-
- // Update growing scene rect.
- QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
- growingItemsBoundingRect |= unindexedItemsBoundingRect;
-
- // Determine whether we should regenerate the BSP tree.
- if (indexMethod == QGraphicsScene::BspTreeIndex) {
- int depth = bspTreeDepth;
- if (depth == 0) {
- int oldDepth = intmaxlog(lastItemCount);
- depth = intmaxlog(indexedItems.size());
- static const int slack = 100;
- if (bspTree.leafCount() == 0 || (oldDepth != depth && qAbs(lastItemCount - indexedItems.size()) > slack)) {
- // ### Crude algorithm.
- regenerateIndex = true;
- }
- }
-
- // Regenerate the tree.
- if (regenerateIndex) {
- regenerateIndex = false;
- bspTree.initialize(q->sceneRect(), depth);
- unindexedItems = indexedItems;
- lastItemCount = indexedItems.size();
- q->update();
-
- // Take this opportunity to reset our largest-item counter for
- // untransformable items. When the items are inserted into the BSP
- // tree, we'll get an accurate calculation.
- largestUntransformableItem = QRectF();
- }
- }
+ calledEmitUpdated = false;
- // Insert all unindexed items into the tree.
- for (int i = 0; i < unindexedItems.size(); ++i) {
- if (QGraphicsItem *item = unindexedItems.at(i)) {
- QRectF rect = item->sceneBoundingRect();
- if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
- continue;
- if (indexMethod == QGraphicsScene::BspTreeIndex)
- bspTree.insertItem(item, rect);
-
- // If the item ignores view transformations, update our
- // largest-item-counter to ensure that the view can accurately
- // discover untransformable items when drawing.
- if (item->d_ptr->itemIsUntransformable()) {
- QGraphicsItem *topmostUntransformable = item;
- while (topmostUntransformable && (topmostUntransformable->d_ptr->ancestorFlags
- & QGraphicsItemPrivate::AncestorIgnoresTransformations)) {
- topmostUntransformable = topmostUntransformable->parentItem();
- }
- // ### Verify that this is the correct largest untransformable rectangle.
- largestUntransformableItem |= item->mapToItem(topmostUntransformable, item->boundingRect()).boundingRect();
- }
+ if (dirtyGrowingItemsBoundingRect) {
+ if (!hasSceneRect) {
+ const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
+ growingItemsBoundingRect |= q->itemsBoundingRect();
+ if (oldGrowingItemsBoundingRect != growingItemsBoundingRect)
+ emit q->sceneRectChanged(growingItemsBoundingRect);
}
+ dirtyGrowingItemsBoundingRect = false;
}
- unindexedItems.clear();
-
- // Notify scene rect changes.
- if (!hasSceneRect && growingItemsBoundingRect != oldGrowingItemsBoundingRect)
- emit q->sceneRectChanged(growingItemsBoundingRect);
-}
-
-/*!
- \internal
-*/
-void QGraphicsScenePrivate::_q_emitUpdated()
-{
- Q_Q(QGraphicsScene);
- calledEmitUpdated = false;
// Ensure all views are connected if anything is connected. This disables
// the optimization that items send updates directly to the views, but it
@@ -633,6 +374,7 @@ void QGraphicsScenePrivate::_q_emitUpdated()
void QGraphicsScenePrivate::registerTopLevelItem(QGraphicsItem *item)
{
needSortTopLevelItems = true;
+ item->d_ptr->siblingIndex = topLevelItems.size();
topLevelItems.append(item);
}
@@ -642,19 +384,10 @@ void QGraphicsScenePrivate::registerTopLevelItem(QGraphicsItem *item)
void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item)
{
topLevelItems.removeOne(item);
-}
-
-/*!
- \internal
-
- Updates all items in the pending update list. At this point, the list is
- unlikely to contain partially constructed items.
-*/
-void QGraphicsScenePrivate::_q_updateLater()
-{
- foreach (QGraphicsItem *item, pendingUpdateItems)
- item->update();
- pendingUpdateItems.clear();
+ // NB! Do not use topLevelItems.removeAt(item->d_ptr->siblingIndex) because
+ // the item is not guaranteed to be at the index after the list is sorted
+ // (see ensureSortedTopLevelItems()).
+ item->d_ptr->siblingIndex = -1;
}
/*!
@@ -680,9 +413,23 @@ void QGraphicsScenePrivate::_q_processDirtyItems()
{
processDirtyItemsEmitted = false;
+ if (updateAll) {
+ Q_ASSERT(calledEmitUpdated);
+ // No need for further processing (except resetting the dirty states).
+ // The growingItemsBoundingRect is updated in _q_emitUpdated.
+ for (int i = 0; i < topLevelItems.size(); ++i)
+ resetDirtyItem(topLevelItems.at(i), /*recursive=*/true);
+ return;
+ }
+
const bool wasPendingSceneUpdate = calledEmitUpdated;
const QRectF oldGrowingItemsBoundingRect = growingItemsBoundingRect;
- processDirtyItemsRecursive(0);
+
+ // Process items recursively.
+ for (int i = 0; i < topLevelItems.size(); ++i)
+ processDirtyItemsRecursive(topLevelItems.at(i));
+
+ dirtyGrowingItemsBoundingRect = false;
if (!hasSceneRect && oldGrowingItemsBoundingRect != growingItemsBoundingRect)
emit q_func()->sceneRectChanged(growingItemsBoundingRect);
@@ -727,22 +474,16 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
// Clear focus on the item to remove any reference in the focusWidget chain.
item->clearFocus();
+
markDirty(item, QRectF(), false, false, false, false, /*removingItemFromScene=*/true);
- if (!item->d_ptr->inDestructor) {
+ if (item->d_ptr->inDestructor) {
+ // The item is actually in its destructor, we call the special method in the index.
+ index->deleteItem(item);
+ } else {
// Can potentially call item->boundingRect() (virtual function), that's why
// we only can call this function if the item is not in its destructor.
- removeFromIndex(item);
- } else if (item->d_ptr->index != -1) {
- // Important: The index is useless until purgeRemovedItems() is called.
- indexedItems[item->d_ptr->index] = (QGraphicsItem *)0;
- if (!purgePending)
- purgePending = true;
- removedItems << item;
- } else {
- // Recently added items are purged immediately. unindexedItems() never
- // contains stale items.
- unindexedItems.removeAll(item);
+ index->removeItem(item);
}
if (!item->d_ptr->inDestructor && item == tabFocusFirst) {
@@ -763,17 +504,6 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
unregisterTopLevelItem(item);
}
- if (!item->d_ptr->inDestructor) {
- // Remove from our item lists.
- int index = item->d_func()->index;
- if (index != -1) {
- freeItemIndexes << index;
- indexedItems[index] = 0;
- } else {
- unindexedItems.removeAll(item);
- }
- }
-
// Reset the mouse grabber and focus item data.
if (item == focusItem)
focusItem = 0;
@@ -793,7 +523,6 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
hoverItems.removeAll(item);
cachedItemsUnderMouse.removeAll(item);
unpolishedItems.removeAll(item);
- pendingUpdateItems.removeAll(item);
resetDirtyItem(item);
//We remove all references of item from the sceneEventFilter arrays
@@ -831,45 +560,6 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
/*!
\internal
-
- Removes stale pointers from all data structures.
-*/
-void QGraphicsScenePrivate::purgeRemovedItems()
-{
- if (!purgePending && removedItems.isEmpty())
- return;
-
- // Remove stale items from the BSP tree.
- if (indexMethod != QGraphicsScene::NoIndex)
- bspTree.removeItems(removedItems);
-
- // Purge this list.
- removedItems.clear();
- freeItemIndexes.clear();
- for (int i = 0; i < indexedItems.size(); ++i) {
- if (!indexedItems.at(i))
- freeItemIndexes << i;
- }
- purgePending = false;
-}
-
-/*!
- \internal
-
- Starts or restarts the timer used for reindexing unindexed items.
-*/
-void QGraphicsScenePrivate::startIndexTimer(int interval)
-{
- Q_Q(QGraphicsScene);
- if (indexTimerId) {
- restartIndexTimer = true;
- } else {
- indexTimerId = q->startTimer(interval);
- }
-}
-
-/*!
- \internal
*/
void QGraphicsScenePrivate::addPopup(QGraphicsWidget *widget)
{
@@ -1104,41 +794,20 @@ QList<QGraphicsItem *> QGraphicsScenePrivate::itemsAtPosition(const QPoint &scre
{
Q_Q(const QGraphicsScene);
QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0;
- QList<QGraphicsItem *> items;
- if (view)
- items = view->items(view->viewport()->mapFromGlobal(screenPos));
- else
- items = q->items(scenePos);
- return items;
-}
+ if (!view)
+ return q->items(scenePos, Qt::IntersectsItemShape, Qt::AscendingOrder, QTransform());
-/*!
- \internal
+ const QRectF pointRect(QPointF(widget->mapFromGlobal(screenPos)), QSizeF(1, 1));
+ if (!view->isTransformed())
+ return q->items(pointRect, Qt::IntersectsItemShape, Qt::AscendingOrder);
- Checks if item collides with the path and mode, but also checks that if it
- doesn't collide, maybe its frame rect will.
-*/
-bool QGraphicsScenePrivate::itemCollidesWithPath(QGraphicsItem *item,
- const QPainterPath &path,
- Qt::ItemSelectionMode mode)
-{
- if (item->collidesWithPath(path, mode))
- return true;
- if (item->isWidget()) {
- // Check if this is a window, and if its frame rect collides.
- QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
- if (widget->isWindow()) {
- QRectF frameRect = widget->windowFrameRect();
- QPainterPath framePath;
- framePath.addRect(frameRect);
- bool intersects = path.intersects(frameRect);
- if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
- return intersects || path.contains(frameRect.topLeft())
- || framePath.contains(path.elementAt(0));
- return !intersects && path.contains(frameRect.topLeft());
- }
+ const QTransform viewTransform = view->viewportTransform();
+ if (viewTransform.type() <= QTransform::TxScale) {
+ return q->items(viewTransform.inverted().mapRect(pointRect), Qt::IntersectsItemShape,
+ Qt::AscendingOrder, viewTransform);
}
- return false;
+ return q->items(viewTransform.inverted().map(pointRect), Qt::IntersectsItemShape,
+ Qt::AscendingOrder, viewTransform);
}
/*!
@@ -1150,7 +819,7 @@ void QGraphicsScenePrivate::storeMouseButtonsForMouseGrabber(QGraphicsSceneMouse
if (event->buttons() & i) {
mouseGrabberButtonDownPos.insert(Qt::MouseButton(i),
mouseGrabberItems.last()->d_ptr->genericMapFromScene(event->scenePos(),
- event->widget()));
+ event->widget()));
mouseGrabberButtonDownScenePos.insert(Qt::MouseButton(i), event->scenePos());
mouseGrabberButtonDownScreenPos.insert(Qt::MouseButton(i), event->screenPos());
}
@@ -1428,779 +1097,6 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item)
return 0;
}
-QList<QGraphicsItem *> QGraphicsScenePrivate::topLevelItemsInStackingOrder(const QTransform *const viewTransform,
- QRegion *exposedRegion)
-{
- if (indexMethod == QGraphicsScene::NoIndex || !exposedRegion) {
- if (needSortTopLevelItems) {
- needSortTopLevelItems = false;
- qStableSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf);
- }
- return topLevelItems;
- }
-
- const QRectF exposedRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1);
- QRectF sceneRect;
- QTransform invertedViewTransform(Qt::Uninitialized);
- if (!viewTransform) {
- sceneRect = exposedRect;
- } else {
- invertedViewTransform = viewTransform->inverted();
- sceneRect = invertedViewTransform.mapRect(exposedRect);
- }
- if (!largestUntransformableItem.isEmpty()) {
- // ### Nuke this when we move the indexing code into a separate
- // class. All the largestUntransformableItem code should then go
- // away, and the estimate function should return untransformable
- // items as well.
- QRectF untr = largestUntransformableItem;
- QRectF ltri = !viewTransform ? untr : invertedViewTransform.mapRect(untr);
- ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height());
- sceneRect.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height());
- }
-
- QList<QGraphicsItem *> tmp = estimateItemsInRect(sceneRect);
- for (int i = 0; i < tmp.size(); ++i)
- tmp.at(i)->topLevelItem()->d_ptr->itemDiscovered = 1;
-
- // Sort if the toplevel list is unsorted.
- if (needSortTopLevelItems) {
- needSortTopLevelItems = false;
- qStableSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf);
- }
-
- QList<QGraphicsItem *> tli;
- for (int i = 0; i < topLevelItems.size(); ++i) {
- // ### Investigate smarter ways. Looping through all top level
- // items is not optimal. If the BSP tree is to have maximum
- // effect, it should be possible to sort the subset of items
- // quickly. We must use this approach for now, as it's the only
- // current way to keep the stable sorting order (insertion order).
- QGraphicsItem *item = topLevelItems.at(i);
- if (item->d_ptr->itemDiscovered) {
- item->d_ptr->itemDiscovered = 0;
- tli << item;
- }
- }
- return tli;
-}
-
-void QGraphicsScenePrivate::recursive_items_helper(QGraphicsItem *item, QRectF rect,
- QList<QGraphicsItem *> *items,
- const QTransform &parentTransform,
- const QTransform &viewTransform,
- Qt::ItemSelectionMode mode, Qt::SortOrder order,
- qreal parentOpacity) const
-{
- // Calculate opacity.
- qreal opacity;
- if (item) {
- if (!item->d_ptr->visible)
- return;
- QGraphicsItem *p = item->d_ptr->parent;
- bool itemIgnoresParentOpacity = item->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity;
- bool parentDoesntPropagateOpacity = (p && (p->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren));
- if (!itemIgnoresParentOpacity && !parentDoesntPropagateOpacity) {
- opacity = parentOpacity * item->opacity();
- } else {
- opacity = item->d_ptr->opacity;
- }
- if (opacity == 0.0 && !(item->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren))
- return;
- } else {
- opacity = parentOpacity;
- }
-
- // Calculate the full transform for this item.
- QTransform transform = parentTransform;
- bool keep = false;
- if (item) {
- item->d_ptr->combineTransformFromParent(&transform, &viewTransform);
-
- // ### This does not take the clip into account.
- QRectF brect = item->boundingRect();
- _q_adjustRect(&brect);
-
- keep = true;
- if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
- keep = rect.contains(transform.mapRect(brect)) && rect != brect;
- else
- keep = rect.intersects(transform.mapRect(brect));
-
- if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
- QPainterPath rectPath;
- rectPath.addRect(rect);
- keep = itemCollidesWithPath(item, transform.inverted().map(rectPath), mode);
- }
- }
-
- bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape));
- bool dontProcessItem = !item || !keep;
- bool dontProcessChildren = item && dontProcessItem && childClip;
-
- // Find and sort children.
- QList<QGraphicsItem *> &children = item ? item->d_ptr->children : const_cast<QGraphicsScenePrivate *>(this)->topLevelItems;
- if (!dontProcessChildren) {
- if (item && item->d_ptr->needSortChildren) {
- item->d_ptr->needSortChildren = 0;
- qStableSort(children.begin(), children.end(), qt_notclosestLeaf);
- } else if (!item && needSortTopLevelItems) {
- const_cast<QGraphicsScenePrivate *>(this)->needSortTopLevelItems = false;
- qStableSort(children.begin(), children.end(), qt_notclosestLeaf);
- }
- }
-
- childClip &= !dontProcessChildren & !children.isEmpty();
-
- // Clip.
- if (childClip)
- rect &= transform.map(item->shape()).controlPointRect();
-
- // Process children behind
- int i = 0;
- if (!dontProcessChildren) {
- for (i = 0; i < children.size(); ++i) {
- QGraphicsItem *child = children.at(i);
- if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent))
- break;
- recursive_items_helper(child, rect, items, transform, viewTransform,
- mode, order, opacity);
- }
- }
-
- // Process item
- if (!dontProcessItem)
- items->append(item);
-
- // Process children in front
- if (!dontProcessChildren) {
- for (; i < children.size(); ++i)
- recursive_items_helper(children.at(i), rect, items, transform, viewTransform,
- mode, order, opacity);
- }
-
- if (!item && order == Qt::AscendingOrder) {
- int n = items->size();
- for (int i = 0; i < n / 2; ++i) {
- QGraphicsItem *tmp = (*items)[n - i - 1];
- (*items)[n - i - 1] = (*items)[i];
- (*items)[i] = tmp;
- }
- }
-}
-
-QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPointF &pos) const
-{
- QList<QGraphicsItem *> items;
-
- // The index returns a rough estimate of what items are inside the rect.
- // Refine it by iterating through all returned items.
- QRectF adjustedRect = QRectF(pos, QSize(1,1));
- foreach (QGraphicsItem *item, estimateItemsInRect(adjustedRect)) {
- // Find the item's scene transform in a clever way.
- QTransform x = item->sceneTransform();
- bool keep = false;
-
- // ### _q_adjustedRect is only needed because QRectF::intersects,
- // QRectF::contains and QTransform::map() and friends don't work with
- // flat rectangles.
- const QRectF br(adjustedItemBoundingRect(item));
- // Rect intersects/contains item's shape
- if (QRectF_intersects(adjustedRect, x.mapRect(br))) {
- bool ok;
- QTransform xinv = x.inverted(&ok);
- if (ok) {
- if (item->contains(xinv.map(pos))) {
- items << item;
- keep = true;
- }
- }
- }
-
- if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) {
- // Recurse into children that clip children.
- bool ok;
- QTransform xinv = x.inverted(&ok);
- if (ok)
- childItems_helper(&items, item, xinv.map(pos));
- }
- }
-
- sortItems(&items, Qt::AscendingOrder, sortCacheEnabled);
- return items;
-}
-
-QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QRectF &rect,
- Qt::ItemSelectionMode mode,
- Qt::SortOrder order) const
-{
- QList<QGraphicsItem *> items;
-
- QPainterPath path;
-
- // The index returns a rough estimate of what items are inside the rect.
- // Refine it by iterating through all returned items.
- QRectF adjustedRect(rect);
- _q_adjustRect(&adjustedRect);
- foreach (QGraphicsItem *item, estimateItemsInRect(adjustedRect)) {
- // Find the item's scene transform in a clever way.
- QTransform x = item->sceneTransform();
- bool keep = false;
-
- // ### _q_adjustedRect is only needed because QRectF::intersects,
- // QRectF::contains and QTransform::map() and friends don't work with
- // flat rectangles.
- const QRectF br(adjustedItemBoundingRect(item));
- if (mode >= Qt::ContainsItemBoundingRect) {
- // Rect intersects/contains item's bounding rect
- QRectF mbr = x.mapRect(br);
- if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr))
- || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(mbr))) {
- items << item;
- keep = true;
- }
- } else {
- // Rect intersects/contains item's shape
- if (QRectF_intersects(adjustedRect, x.mapRect(br))) {
- bool ok;
- QTransform xinv = x.inverted(&ok);
- if (ok) {
- if (path.isEmpty())
- path.addRect(rect);
- if (itemCollidesWithPath(item, xinv.map(path), mode)) {
- items << item;
- keep = true;
- }
- }
- }
- }
-
- if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) {
- // Recurse into children that clip children.
- bool ok;
- QTransform xinv = x.inverted(&ok);
- if (ok) {
- if (x.type() <= QTransform::TxScale) {
- // Rect
- childItems_helper(&items, item, xinv.mapRect(rect), mode);
- } else {
- // Polygon
- childItems_helper(&items, item, xinv.map(rect), mode);
- }
- }
- }
- }
-
- if (order != Qt::SortOrder(-1))
- sortItems(&items, order, sortCacheEnabled);
- return items;
-}
-
-QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPolygonF &polygon,
- Qt::ItemSelectionMode mode,
- Qt::SortOrder order) const
-{
- QList<QGraphicsItem *> items;
-
- QRectF polyRect(polygon.boundingRect());
- _q_adjustRect(&polyRect);
- QPainterPath path;
-
- // The index returns a rough estimate of what items are inside the rect.
- // Refine it by iterating through all returned items.
- foreach (QGraphicsItem *item, estimateItemsInRect(polyRect)) {
- // Find the item's scene transform in a clever way.
- QTransform x = item->sceneTransform();
- bool keep = false;
-
- // ### _q_adjustedRect is only needed because QRectF::intersects,
- // QRectF::contains and QTransform::map() and friends don't work with
- // flat rectangles.
- const QRectF br(adjustedItemBoundingRect(item));
- if (mode >= Qt::ContainsItemBoundingRect) {
- // Polygon contains/intersects item's bounding rect
- if (path == QPainterPath())
- path.addPolygon(polygon);
- if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br)))
- || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) {
- items << item;
- keep = true;
- }
- } else {
- // Polygon contains/intersects item's shape
- if (QRectF_intersects(polyRect, x.mapRect(br))) {
- bool ok;
- QTransform xinv = x.inverted(&ok);
- if (ok) {
- if (path == QPainterPath())
- path.addPolygon(polygon);
- if (itemCollidesWithPath(item, xinv.map(path), mode)) {
- items << item;
- keep = true;
- }
- }
- }
- }
-
- if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) {
- // Recurse into children that clip children.
- bool ok;
- QTransform xinv = x.inverted(&ok);
- if (ok)
- childItems_helper(&items, item, xinv.map(polygon), mode);
- }
- }
-
- if (order != Qt::SortOrder(-1))
- sortItems(&items, order, sortCacheEnabled);
- return items;
-}
-
-QList<QGraphicsItem *> QGraphicsScenePrivate::items_helper(const QPainterPath &path,
- Qt::ItemSelectionMode mode,
- Qt::SortOrder order) const
-{
- QList<QGraphicsItem *> items;
- QRectF pathRect(path.controlPointRect());
- _q_adjustRect(&pathRect);
-
- // The index returns a rough estimate of what items are inside the rect.
- // Refine it by iterating through all returned items.
- foreach (QGraphicsItem *item, estimateItemsInRect(pathRect)) {
- // Find the item's scene transform in a clever way.
- QTransform x = item->sceneTransform();
- bool keep = false;
-
- // ### _q_adjustedRect is only needed because QRectF::intersects,
- // QRectF::contains and QTransform::map() and friends don't work with
- // flat rectangles.
- const QRectF br(adjustedItemBoundingRect(item));
- if (mode >= Qt::ContainsItemBoundingRect) {
- // Path contains/intersects item's bounding rect
- if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br)))
- || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) {
- items << item;
- keep = true;
- }
- } else {
- // Path contains/intersects item's shape
- if (QRectF_intersects(pathRect, x.mapRect(br))) {
- bool ok;
- QTransform xinv = x.inverted(&ok);
- if (ok) {
- if (itemCollidesWithPath(item, xinv.map(path), mode)) {
- items << item;
- keep = true;
- }
- }
- }
- }
-
- if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) {
- bool ok;
- QTransform xinv = x.inverted(&ok);
- if (ok)
- childItems_helper(&items, item, xinv.map(path), mode);
- }
- }
-
- if (order != Qt::SortOrder(-1))
- sortItems(&items, order, sortCacheEnabled);
- return items;
-}
-
-void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
- const QGraphicsItem *parent,
- const QPointF &pos) const
-{
- bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
- if (parentClip && parent->d_ptr->isClippedAway())
- return;
- // ### is this needed?
- if (parentClip && !parent->boundingRect().contains(pos))
- return;
-
- QList<QGraphicsItem *> &children = parent->d_ptr->children;
- for (int i = 0; i < children.size(); ++i) {
- QGraphicsItem *item = children.at(i);
- if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible())
- continue;
-
- // Skip invisible items and all their children.
- if (item->d_ptr->isInvisible())
- continue;
-
- bool keep = false;
- if (!item->d_ptr->isClippedAway()) {
- if (item->contains(item->mapFromParent(pos))) {
- items->append(item);
- keep = true;
- }
- }
-
- if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty())
- // Recurse into children.
- childItems_helper(items, item, item->mapFromParent(pos));
- }
-}
-
-
-void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
- const QGraphicsItem *parent,
- const QRectF &rect,
- Qt::ItemSelectionMode mode) const
-{
- bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
- if (parentClip && parent->d_ptr->isClippedAway())
- return;
- QRectF adjustedRect(rect);
- _q_adjustRect(&adjustedRect);
- QRectF r = !parentClip ? adjustedRect : adjustedRect.intersected(adjustedItemBoundingRect(parent));
- if (r.isEmpty())
- return;
-
- QPainterPath path;
- QList<QGraphicsItem *> &children = parent->d_ptr->children;
- for (int i = 0; i < children.size(); ++i) {
- QGraphicsItem *item = children.at(i);
- if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible())
- continue;
-
- // Skip invisible items and all their children.
- if (item->d_ptr->isInvisible())
- continue;
-
- bool keep = false;
- if (!item->d_ptr->isClippedAway()) {
- // ### _q_adjustedRect is only needed because QRectF::intersects,
- // QRectF::contains and QTransform::map() and friends don't work with
- // flat rectangles.
- const QRectF br(adjustedItemBoundingRect(item));
- QRectF mbr = item->mapRectToParent(br);
- if (mode >= Qt::ContainsItemBoundingRect) {
- // Rect intersects/contains item's bounding rect
- if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr))
- || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(br))) {
- items->append(item);
- keep = true;
- }
- } else {
- // Rect intersects/contains item's shape
- if (QRectF_intersects(rect, mbr)) {
- if (path == QPainterPath())
- path.addRect(rect);
- if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
- items->append(item);
- keep = true;
- }
- }
- }
- }
-
- if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) {
- // Recurse into children.
- if (!item->d_ptr->transformData || item->d_ptr->transformData->computedFullTransform().type() <= QTransform::TxScale) {
- // Rect
- childItems_helper(items, item, item->mapRectFromParent(rect), mode);
- } else {
- // Polygon
- childItems_helper(items, item, item->mapFromParent(rect), mode);
- }
- }
- }
-}
-
-
-void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
- const QGraphicsItem *parent,
- const QPolygonF &polygon,
- Qt::ItemSelectionMode mode) const
-{
- bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
- if (parentClip && parent->d_ptr->isClippedAway())
- return;
- QRectF polyRect(polygon.boundingRect());
- _q_adjustRect(&polyRect);
- QRectF r = !parentClip ? polyRect : polyRect.intersected(adjustedItemBoundingRect(parent));
- if (r.isEmpty())
- return;
-
- QPainterPath path;
- QList<QGraphicsItem *> &children = parent->d_ptr->children;
- for (int i = 0; i < children.size(); ++i) {
- QGraphicsItem *item = children.at(i);
- if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible())
- continue;
-
- // Skip invisible items.
- if (item->d_ptr->isInvisible())
- continue;
-
- bool keep = false;
- if (!item->d_ptr->isClippedAway()) {
- // ### _q_adjustedRect is only needed because QRectF::intersects,
- // QRectF::contains and QTransform::map() and friends don't work with
- // flat rectangles.
- const QRectF br(adjustedItemBoundingRect(item));
- if (mode >= Qt::ContainsItemBoundingRect) {
- // Polygon contains/intersects item's bounding rect
- if (path == QPainterPath())
- path.addPolygon(polygon);
- if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br)))
- || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) {
- items->append(item);
- keep = true;
- }
- } else {
- // Polygon contains/intersects item's shape
- if (QRectF_intersects(polyRect, item->mapRectToParent(br))) {
- if (path == QPainterPath())
- path.addPolygon(polygon);
- if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
- items->append(item);
- keep = true;
- }
- }
- }
- }
-
- if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) {
- // Recurse into children that clip children.
- childItems_helper(items, item, item->mapFromParent(polygon), mode);
- }
- }
-}
-
-void QGraphicsScenePrivate::childItems_helper(QList<QGraphicsItem *> *items,
- const QGraphicsItem *parent,
- const QPainterPath &path,
- Qt::ItemSelectionMode mode) const
-{
- bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape);
- if (parentClip && parent->d_ptr->isClippedAway())
- return;
- QRectF pathRect(path.boundingRect());
- _q_adjustRect(&pathRect);
- QRectF r = !parentClip ? pathRect : pathRect.intersected(adjustedItemBoundingRect(parent));
- if (r.isEmpty())
- return;
-
- QList<QGraphicsItem *> &children = parent->d_ptr->children;
- for (int i = 0; i < children.size(); ++i) {
- QGraphicsItem *item = children.at(i);
- if (item->d_ptr->transformData && !item->d_ptr->transformData->computedFullTransform().isInvertible())
- continue;
-
- // Skip invisible items.
- if (item->d_ptr->isInvisible())
- continue;
-
- bool keep = false;
- if (!item->d_ptr->isClippedAway()) {
- // ### _q_adjustedRect is only needed because QRectF::intersects,
- // QRectF::contains and QTransform::map() and friends don't work with
- // flat rectangles.
- const QRectF br(adjustedItemBoundingRect(item));
- if (mode >= Qt::ContainsItemBoundingRect) {
- // Polygon contains/intersects item's bounding rect
- if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br)))
- || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) {
- items->append(item);
- keep = true;
- }
- } else {
- // Path contains/intersects item's shape
- if (QRectF_intersects(pathRect, item->mapRectToParent(br))) {
- if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) {
- items->append(item);
- keep = true;
- }
- }
- }
- }
-
- if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) {
- // Recurse into children that clip children.
- childItems_helper(items, item, item->mapFromParent(path), mode);
- }
- }
-}
-
-void QGraphicsScenePrivate::invalidateSortCache()
-{
- Q_Q(QGraphicsScene);
- if (!sortCacheEnabled || updatingSortCache)
- return;
-
- updatingSortCache = true;
- QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection);
-}
-
-/*!
- \internal
-
- Should not be exported, but we can't change that now.
- ### Qt 5: Remove symbol / make static
-*/
-inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
-{
- // Return true if sibling item1 is on top of item2.
- const QGraphicsItemPrivate *d1 = item1->d_ptr;
- const QGraphicsItemPrivate *d2 = item2->d_ptr;
- bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent;
- bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent;
- if (f1 != f2) return f2;
- qreal z1 = d1->z;
- qreal z2 = d2->z;
- return z1 > z2;
-}
-
-static inline bool qt_notclosestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2)
-{
- return qt_closestLeaf(item2, item1);
-}
-
-/*!
- \internal
-
- Should not be exported, but we can't change that now.
-*/
-inline bool qt_closestItemFirst(const QGraphicsItem *item1, const QGraphicsItem *item2)
-{
- return QGraphicsScenePrivate::closestItemFirst_withoutCache(item1, item2);
-}
-
-/*!
- Returns true if \a item1 is on top of \a item2.
-
- \internal
-*/
-bool QGraphicsScenePrivate::closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2)
-{
- // Siblings? Just check their z-values.
- const QGraphicsItemPrivate *d1 = item1->d_ptr;
- const QGraphicsItemPrivate *d2 = item2->d_ptr;
- if (d1->parent == d2->parent)
- return qt_closestLeaf(item1, item2);
-
- // Find common ancestor, and each item's ancestor closest to the common
- // ancestor.
- int item1Depth = d1->depth;
- int item2Depth = d2->depth;
- const QGraphicsItem *p = item1;
- const QGraphicsItem *t1 = item1;
- while (item1Depth > item2Depth && (p = p->d_ptr->parent)) {
- if (p == item2) {
- // item2 is one of item1's ancestors; item1 is on top
- return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
- }
- t1 = p;
- --item1Depth;
- }
- p = item2;
- const QGraphicsItem *t2 = item2;
- while (item2Depth > item1Depth && (p = p->d_ptr->parent)) {
- if (p == item1) {
- // item1 is one of item2's ancestors; item1 is not on top
- return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
- }
- t2 = p;
- --item2Depth;
- }
-
- // item1Ancestor is now at the same level as item2Ancestor, but not the same.
- const QGraphicsItem *a1 = t1;
- const QGraphicsItem *a2 = t2;
- while (a1) {
- const QGraphicsItem *p1 = a1;
- const QGraphicsItem *p2 = a2;
- a1 = a1->parentItem();
- a2 = a2->parentItem();
- if (a1 && a1 == a2)
- return qt_closestLeaf(p1, p2);
- }
-
- // No common ancestor? Then just compare the items' toplevels directly.
- return qt_closestLeaf(t1->topLevelItem(), t2->topLevelItem());
-}
-
-/*!
- Returns true if \a item2 is on top of \a item1.
-
- \internal
-*/
-bool QGraphicsScenePrivate::closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2)
-{
- return closestItemFirst_withoutCache(item2, item1);
-}
-
-void QGraphicsScenePrivate::climbTree(QGraphicsItem *item, int *stackingOrder)
-{
- if (!item->d_ptr->children.isEmpty()) {
- QList<QGraphicsItem *> childList = item->d_ptr->children;
- qSort(childList.begin(), childList.end(), qt_closestLeaf);
- for (int i = 0; i < childList.size(); ++i) {
- QGraphicsItem *item = childList.at(i);
- if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent))
- climbTree(childList.at(i), stackingOrder);
- }
- item->d_ptr->globalStackingOrder = (*stackingOrder)++;
- for (int i = 0; i < childList.size(); ++i) {
- QGraphicsItem *item = childList.at(i);
- if (item->flags() & QGraphicsItem::ItemStacksBehindParent)
- climbTree(childList.at(i), stackingOrder);
- }
- } else {
- item->d_ptr->globalStackingOrder = (*stackingOrder)++;
- }
-}
-
-void QGraphicsScenePrivate::_q_updateSortCache()
-{
- _q_updateIndex();
-
- if (!sortCacheEnabled || !updatingSortCache)
- return;
-
- updatingSortCache = false;
- int stackingOrder = 0;
-
- QList<QGraphicsItem *> topLevels;
-
- for (int i = 0; i < indexedItems.size(); ++i) {
- QGraphicsItem *item = indexedItems.at(i);
- if (item && item->parentItem() == 0)
- topLevels << item;
- }
- for (int i = 0; i < unindexedItems.size(); ++i) {
- QGraphicsItem *item = unindexedItems.at(i);
- if (item->parentItem() == 0)
- topLevels << item;
- }
-
- qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf);
- for (int i = 0; i < topLevels.size(); ++i)
- climbTree(topLevels.at(i), &stackingOrder);
-}
-
-void QGraphicsScenePrivate::sortItems(QList<QGraphicsItem *> *itemList, Qt::SortOrder order,
- bool sortCacheEnabled)
-{
- if (sortCacheEnabled) {
- if (order == Qt::AscendingOrder) {
- qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache);
- } else if (order == Qt::DescendingOrder) {
- qSort(itemList->begin(), itemList->end(), closestItemLast_withCache);
- }
- } else {
- if (order == Qt::AscendingOrder) {
- qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache);
- } else if (order == Qt::DescendingOrder) {
- qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache);
- }
- }
-}
-
/*!
\internal
@@ -2333,8 +1229,8 @@ QGraphicsScene::QGraphicsScene(QObject *parent)
QGraphicsScene::QGraphicsScene(const QRectF &sceneRect, QObject *parent)
: QObject(*new QGraphicsScenePrivate, parent)
{
- setSceneRect(sceneRect);
d_func()->init();
+ setSceneRect(sceneRect);
}
/*!
@@ -2348,8 +1244,8 @@ QGraphicsScene::QGraphicsScene(const QRectF &sceneRect, QObject *parent)
QGraphicsScene::QGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObject *parent)
: QObject(*new QGraphicsScenePrivate, parent)
{
- setSceneRect(x, y, width, height);
d_func()->init();
+ setSceneRect(x, y, width, height);
}
/*!
@@ -2386,8 +1282,19 @@ QGraphicsScene::~QGraphicsScene()
QRectF QGraphicsScene::sceneRect() const
{
Q_D(const QGraphicsScene);
- const_cast<QGraphicsScenePrivate *>(d)->_q_updateIndex();
- return d->hasSceneRect ? d->sceneRect : d->growingItemsBoundingRect;
+ if (d->hasSceneRect)
+ return d->sceneRect;
+
+ if (d->dirtyGrowingItemsBoundingRect) {
+ // Lazily update the growing items bounding rect
+ QGraphicsScenePrivate *thatd = const_cast<QGraphicsScenePrivate *>(d);
+ QRectF oldGrowingBoundingRect = thatd->growingItemsBoundingRect;
+ thatd->growingItemsBoundingRect |= itemsBoundingRect();
+ thatd->dirtyGrowingItemsBoundingRect = false;
+ if (oldGrowingBoundingRect != thatd->growingItemsBoundingRect)
+ emit const_cast<QGraphicsScene *>(this)->sceneRectChanged(thatd->growingItemsBoundingRect);
+ }
+ return d->growingItemsBoundingRect;
}
void QGraphicsScene::setSceneRect(const QRectF &rect)
{
@@ -2395,8 +1302,7 @@ void QGraphicsScene::setSceneRect(const QRectF &rect)
if (rect != d->sceneRect) {
d->hasSceneRect = !rect.isNull();
d->sceneRect = rect;
- d->resetIndex();
- emit sceneRectChanged(rect);
+ emit sceneRectChanged(d->hasSceneRect ? rect : d->growingItemsBoundingRect);
}
}
@@ -2437,6 +1343,8 @@ void QGraphicsScene::setSceneRect(const QRectF &rect)
void QGraphicsScene::render(QPainter *painter, const QRectF &target, const QRectF &source,
Qt::AspectRatioMode aspectRatioMode)
{
+ // ### Switch to using the recursive rendering algorithm instead.
+
// Default source rect = scene rect
QRectF sourceRect = source;
if (sourceRect.isNull())
@@ -2531,8 +1439,19 @@ QGraphicsScene::ItemIndexMethod QGraphicsScene::itemIndexMethod() const
void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method)
{
Q_D(QGraphicsScene);
- d->resetIndex();
+ if (d->indexMethod == method)
+ return;
+
d->indexMethod = method;
+
+ QList<QGraphicsItem *> oldItems = d->index->items(Qt::AscendingOrder);
+ delete d->index;
+ if (method == BspTreeIndex)
+ d->index = new QGraphicsSceneBspTreeIndex(this);
+ else
+ d->index = new QGraphicsSceneLinearIndex(this);
+ for (int i = oldItems.size() - 1; i >= 0; --i)
+ d->index->addItem(oldItems.at(i));
}
/*!
@@ -2570,35 +1489,32 @@ void QGraphicsScene::setItemIndexMethod(ItemIndexMethod method)
int QGraphicsScene::bspTreeDepth() const
{
Q_D(const QGraphicsScene);
- return d->bspTreeDepth;
+ QGraphicsSceneBspTreeIndex *bspTree = qobject_cast<QGraphicsSceneBspTreeIndex *>(d->index);
+ return bspTree ? bspTree->bspTreeDepth() : 0;
}
void QGraphicsScene::setBspTreeDepth(int depth)
{
Q_D(QGraphicsScene);
- if (d->bspTreeDepth == depth)
- return;
-
if (depth < 0) {
qWarning("QGraphicsScene::setBspTreeDepth: invalid depth %d ignored; must be >= 0", depth);
return;
}
- d->bspTreeDepth = depth;
- d->resetIndex();
+ QGraphicsSceneBspTreeIndex *bspTree = qobject_cast<QGraphicsSceneBspTreeIndex *>(d->index);
+ if (!bspTree) {
+ qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP");
+ return;
+ }
+ bspTree->setBspTreeDepth(depth);
}
/*!
\property QGraphicsScene::sortCacheEnabled
\brief whether sort caching is enabled
\since 4.5
+ \obsolete
- When enabled, this property adds a cache that speeds up sorting and
- transformations for scenes with deep hierarchies (i.e., items with many
- levels of descendents), at the cost of using more memory (approx. 100 more
- bytes of memory per item).
-
- Items that are not part of a deep hierarchy suffer no penalty from this
- cache.
+ Since Qt 4.6, this property has no effect.
*/
bool QGraphicsScene::isSortCacheEnabled() const
{
@@ -2608,10 +1524,9 @@ bool QGraphicsScene::isSortCacheEnabled() const
void QGraphicsScene::setSortCacheEnabled(bool enabled)
{
Q_D(QGraphicsScene);
- if (enabled == d->sortCacheEnabled)
+ if (d->sortCacheEnabled == enabled)
return;
- if ((d->sortCacheEnabled = enabled))
- d->invalidateSortCache();
+ d->sortCacheEnabled = enabled;
}
/*!
@@ -2623,6 +1538,7 @@ void QGraphicsScene::setSortCacheEnabled(bool enabled)
*/
QRectF QGraphicsScene::itemsBoundingRect() const
{
+ // Does not take untransformable items into account.
QRectF boundingRect;
foreach (QGraphicsItem *item, items())
boundingRect |= item->sceneBoundingRect();
@@ -2637,29 +1553,24 @@ QRectF QGraphicsScene::itemsBoundingRect() const
QList<QGraphicsItem *> QGraphicsScene::items() const
{
Q_D(const QGraphicsScene);
- const_cast<QGraphicsScenePrivate *>(d)->purgeRemovedItems();
+ return d->index->items(Qt::AscendingOrder);
+}
- // If freeItemIndexes is empty, we know there are no holes in indexedItems and
- // unindexedItems.
- if (d->freeItemIndexes.isEmpty()) {
- if (d->unindexedItems.isEmpty())
- return d->indexedItems;
- return d->indexedItems + d->unindexedItems;
- }
+/*!
+ Returns an ordered list of all items on the scene. \a order decides the
+ sorting.
- // Rebuild the list of items to avoid holes. ### We could also just
- // compress the item lists at this point.
- QList<QGraphicsItem *> itemList;
- foreach (QGraphicsItem *item, d->indexedItems + d->unindexedItems) {
- if (item)
- itemList << item;
- }
- return itemList;
+ \sa addItem(), removeItem()
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(Qt::SortOrder order) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(order);
}
/*!
Returns all visible items at position \a pos in the scene. The items are
- listed in descending Z order (i.e., the first item in the list is the
+ listed in descending stacking order (i.e., the first item in the list is the
top-most item, and the last item is the bottom-most item).
\sa itemAt()
@@ -2667,7 +1578,7 @@ QList<QGraphicsItem *> QGraphicsScene::items() const
QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos) const
{
Q_D(const QGraphicsScene);
- return d->items_helper(pos);
+ return d->index->items(pos, Qt::IntersectsItemShape, Qt::AscendingOrder);
}
/*!
@@ -2686,9 +1597,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos) const
QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode) const
{
Q_D(const QGraphicsScene);
- QList<QGraphicsItem *> itemList;
- d->recursive_items_helper(0, rect, &itemList, QTransform(), QTransform(), mode, Qt::AscendingOrder);
- return itemList;
+ return d->index->items(rect, mode, Qt::AscendingOrder);
}
/*!
@@ -2712,7 +1621,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelecti
QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode) const
{
Q_D(const QGraphicsScene);
- return d->items_helper(polygon, mode, Qt::AscendingOrder);
+ return d->index->items(polygon, mode, Qt::AscendingOrder);
}
/*!
@@ -2729,7 +1638,85 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemS
QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode) const
{
Q_D(const QGraphicsScene);
- return d->items_helper(path, mode, Qt::AscendingOrder);
+ return d->index->items(path, mode, Qt::AscendingOrder);
+}
+
+/*!
+ Returns all visible items that, depending on \a mode, are at the specified \a pos
+ and return a list sorted using \a order.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with \a pos are returned.
+
+ \a deviceTransform is the transformation apply to the view.
+
+ \sa itemAt()
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(const QPointF &pos, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(pos, mode, order, deviceTransform);
+}
+
+/*!
+ \overload
+
+ Returns all visible items that, depending on \a mode, are either inside or
+ intersect with the specified \a rect and return a list sorted using \a order.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a rect are returned.
+
+ \a deviceTransform is the transformation apply to the view.
+
+ \sa itemAt()
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rect, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(rect, mode, order, deviceTransform);
+}
+
+/*!
+ \overload
+
+ Returns all visible items that, depending on \a mode, are either inside or
+ intersect with the specified \a polygon and return a list sorted using \a order.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a polygon are returned.
+
+ \a deviceTransform is the transformation apply to the view.
+
+ \sa itemAt()
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(polygon, mode, order, deviceTransform);
+}
+
+/*!
+ \overload
+
+ Returns all visible items that, depending on \a mode, are either inside or
+ intersect with the specified \a path and return a list sorted using \a order.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a path are returned.
+
+ \a deviceTransform is the transformation apply to the view.
+
+ \sa itemAt()
+*/
+QList<QGraphicsItem *> QGraphicsScene::items(const QPainterPath &path, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform) const
+{
+ Q_D(const QGraphicsScene);
+ return d->index->items(path, mode, order, deviceTransform);
}
/*!
@@ -2752,12 +1739,12 @@ QList<QGraphicsItem *> QGraphicsScene::collidingItems(const QGraphicsItem *item,
return QList<QGraphicsItem *>();
}
+ // Does not support ItemIgnoresTransformations.
QList<QGraphicsItem *> tmp;
- foreach (QGraphicsItem *itemInVicinity, d->estimateItemsInRect(item->sceneBoundingRect())) {
+ foreach (QGraphicsItem *itemInVicinity, d->index->estimateItems(item->sceneBoundingRect(), Qt::AscendingOrder)) {
if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode))
tmp << itemInVicinity;
}
- d->sortItems(&tmp, Qt::AscendingOrder, d->sortCacheEnabled);
return tmp;
}
@@ -2777,6 +1764,13 @@ QGraphicsItem *QGraphicsScene::itemAt(const QPointF &pos) const
return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first();
}
+QGraphicsItem *QGraphicsScene::itemAt(const QPointF &pos, const QTransform &deviceTransform) const
+{
+ QList<QGraphicsItem *> itemsAtPoint = items(pos, Qt::IntersectsItemShape,
+ Qt::AscendingOrder, deviceTransform);
+ return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first();
+}
+
/*!
\fn QGraphicsScene::itemAt(qreal x, qreal y) const
\overload
@@ -2852,6 +1846,21 @@ void QGraphicsScene::setSelectionArea(const QPainterPath &path)
*/
void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode)
{
+ setSelectionArea(path, mode, QTransform());
+}
+
+/*!
+ \overload
+ \since 4.3
+
+ Sets the selection area to \a path using \a mode to determine if items are
+ included in the selection area.
+
+ \sa clearSelection(), selectionArea()
+*/
+void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode,
+ const QTransform &deviceTransform)
+{
Q_D(QGraphicsScene);
// Note: with boolean path operations, we can improve performance here
@@ -2867,7 +1876,7 @@ void QGraphicsScene::setSelectionArea(const QPainterPath &path, Qt::ItemSelectio
bool changed = false;
// Set all items in path to selected.
- foreach (QGraphicsItem *item, items(path, mode)) {
+ foreach (QGraphicsItem *item, items(path, mode, Qt::AscendingOrder, deviceTransform)) {
if (item->flags() & QGraphicsItem::ItemIsSelectable) {
if (!item->isSelected())
changed = true;
@@ -2924,26 +1933,13 @@ void QGraphicsScene::clearSelection()
void QGraphicsScene::clear()
{
Q_D(QGraphicsScene);
- // Recursive descent delete
- for (int i = 0; i < d->indexedItems.size(); ++i) {
- if (QGraphicsItem *item = d->indexedItems.at(i)) {
- if (!item->parentItem())
- delete item;
- }
- }
- QList<QGraphicsItem *> unindexedParents;
- for (int i = 0; i < d->unindexedItems.size(); ++i) {
- QGraphicsItem *item = d->unindexedItems.at(i);
- if (!item->parentItem())
- unindexedParents << item;
- }
- d->unindexedItems.clear();
- qDeleteAll(unindexedParents);
- d->indexedItems.clear();
- d->freeItemIndexes.clear();
+ // NB! We have to clear the index before deleting items; otherwise the
+ // index might try to access dangling item pointers.
+ d->index->clear();
+ const QList<QGraphicsItem *> items = d->topLevelItems;
+ qDeleteAll(items);
+ Q_ASSERT(d->topLevelItems.isEmpty());
d->lastItemCount = 0;
- d->bspTree.clear();
- d->largestUntransformableItem = QRectF();
d->allItemsIgnoreHoverEvents = true;
d->allItemsUseDefaultCursor = true;
d->allItemsIgnoreTouchEvents = true;
@@ -3065,14 +2061,6 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
return;
}
- // Prevent reusing a recently deleted pointer: purge all removed items
- // from our lists.
- d->purgeRemovedItems();
-
- // Invalidate any sort caching; arrival of a new item means we need to
- // resort.
- d->invalidateSortCache();
-
// Detach this item from its parent if the parent's scene is different
// from this scene.
if (QGraphicsItem *itemParent = item->parentItem()) {
@@ -3083,29 +2071,18 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
// Add the item to this scene
item->d_func()->scene = targetScene;
- // Indexing requires sceneBoundingRect(), but because \a item might
- // not be completely constructed at this point, we need to store it in
- // a temporary list and schedule an indexing for later.
- d->unindexedItems << item;
- item->d_func()->index = -1;
- d->startIndexTimer(0);
+ // Add the item in the index
+ d->index->addItem(item);
// Add to list of toplevels if this item is a toplevel.
if (!item->d_ptr->parent)
d->registerTopLevelItem(item);
- // Update the scene's sort cache settings.
- item->d_ptr->globalStackingOrder = -1;
- d->invalidateSortCache();
-
// Add to list of items that require an update. We cannot assume that the
// item is fully constructed, so calling item->update() can lead to a pure
// virtual function call to boundingRect().
- if (!d->updateAll) {
- if (d->pendingUpdateItems.isEmpty())
- QMetaObject::invokeMethod(this, "_q_updateLater", Qt::QueuedConnection);
- d->pendingUpdateItems << item;
- }
+ d->markDirty(item);
+ d->dirtyGrowingItemsBoundingRect = true;
// Disable selectionChanged() for individual items
++d->selectionChanging;
@@ -4039,16 +3016,6 @@ bool QGraphicsScene::event(QEvent *event)
case QEvent::TouchEnd:
d->touchEventHandler(static_cast<QTouchEvent *>(event));
break;
- case QEvent::Timer:
- if (d->indexTimerId && static_cast<QTimerEvent *>(event)->timerId() == d->indexTimerId) {
- if (d->restartIndexTimer) {
- d->restartIndexTimer = false;
- } else {
- // this call will kill the timer
- d->_q_updateIndex();
- }
- }
- // Fallthrough intended - support timers in subclasses.
default:
return QObject::event(event);
}
@@ -5137,6 +4104,20 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
}
}
+void QGraphicsScenePrivate::drawItems(QPainter *painter, const QTransform *const viewTransform,
+ QRegion *exposedRegion, QWidget *widget)
+{
+ QRectF exposedSceneRect;
+ if (exposedRegion && indexMethod != QGraphicsScene::NoIndex) {
+ exposedSceneRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1);
+ if (viewTransform)
+ exposedSceneRect = viewTransform->inverted().mapRect(exposedSceneRect);
+ }
+ const QList<QGraphicsItem *> tli = index->estimateTopLevelItems(exposedSceneRect, Qt::DescendingOrder);
+ for (int i = 0; i < tli.size(); ++i)
+ drawSubtreeRecursive(tli.at(i), painter, viewTransform, exposedRegion, widget);
+}
+
void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter,
const QTransform *const viewTransform,
QRegion *exposedRegion, QWidget *widget,
@@ -5159,6 +4140,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
QTransform transform(Qt::Uninitialized);
QTransform *transformPtr = 0;
+ bool translateOnlyTransform = false;
#define ENSURE_TRANSFORM_PTR \
if (!transformPtr) { \
Q_ASSERT(!itemIsUntransformable); \
@@ -5168,6 +4150,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
transformPtr = &transform; \
} else { \
transformPtr = &item->d_ptr->sceneTransform; \
+ translateOnlyTransform = item->d_ptr->sceneTransformTranslateOnly; \
} \
}
@@ -5179,10 +4162,8 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
transform = item->deviceTransform(viewTransform ? *viewTransform : QTransform());
transformPtr = &transform;
} else if (item->d_ptr->dirtySceneTransform) {
- item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform
- : QTransform();
- item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform);
- item->d_ptr->dirtySceneTransform = 0;
+ item->d_ptr->updateSceneTransformFromParent();
+ Q_ASSERT(!item->d_ptr->dirtySceneTransform);
wasDirtyParentSceneTransform = true;
}
@@ -5191,7 +4172,8 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
if (drawItem) {
const QRectF brect = adjustedItemBoundingRect(item);
ENSURE_TRANSFORM_PTR
- QRect viewBoundingRect = transformPtr->mapRect(brect).toRect();
+ QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toRect()
+ : transformPtr->mapRect(brect).toRect();
item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect);
viewBoundingRect.adjust(-1, -1, 1, 1);
drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect) : !viewBoundingRect.isEmpty();
@@ -5208,10 +4190,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
int i = 0;
if (itemHasChildren) {
- if (item->d_ptr->needSortChildren) {
- item->d_ptr->needSortChildren = 0;
- qStableSort(item->d_ptr->children.begin(), item->d_ptr->children.end(), qt_notclosestLeaf);
- }
+ item->d_ptr->ensureSortedChildren();
if (itemClipsChildrenToShape) {
painter->save();
@@ -5237,7 +4216,8 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
if (drawItem) {
Q_ASSERT(!itemIsFullyTransparent);
Q_ASSERT(itemHasContents);
- item->d_ptr->initStyleOption(&styleOptionTmp, transform, exposedRegion
+ ENSURE_TRANSFORM_PTR
+ item->d_ptr->initStyleOption(&styleOptionTmp, *transformPtr, exposedRegion
? *exposedRegion : QRegion(), exposedRegion == 0);
const bool itemClipsToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsToShape;
@@ -5245,10 +4225,9 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
if (savePainter)
painter->save();
- if (!itemHasChildren || !itemClipsChildrenToShape) {
- ENSURE_TRANSFORM_PTR
+ if (!itemHasChildren || !itemClipsChildrenToShape)
painter->setWorldTransform(*transformPtr);
- }
+
if (itemClipsToShape)
painter->setClipPath(item->shape(), Qt::IntersectClip);
painter->setOpacity(opacity);
@@ -5291,6 +4270,16 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b
/*ignoreVisibleBit=*/force,
/*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren,
/*ignoreOpacity=*/ignoreOpacity)) {
+ if (item->d_ptr->dirty) {
+ // The item is already marked as dirty and will be processed later. However,
+ // we have to make sure ignoreVisible and ignoreOpacity are set properly;
+ // otherwise things like: item->update(); item->hide() (force is now true)
+ // won't work as expected.
+ if (force)
+ item->d_ptr->ignoreVisible = 1;
+ if (ignoreOpacity)
+ item->d_ptr->ignoreOpacity = 1;
+ }
return;
}
@@ -5350,65 +4339,121 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b
}
static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate *item,
- const QRectF &rect, const QTransform &xform)
+ const QRectF &rect, bool itemIsUntransformable)
{
Q_ASSERT(view);
Q_ASSERT(item);
- if (item->hasBoundingRegionGranularity)
+
+ QGraphicsItem *itemq = static_cast<QGraphicsItem *>(item->q_ptr);
+ QGraphicsView *viewq = static_cast<QGraphicsView *>(view->q_ptr);
+
+ if (itemIsUntransformable) {
+ const QTransform xform = itemq->deviceTransform(viewq->viewportTransform());
+ if (!item->hasBoundingRegionGranularity)
+ return view->updateRect(xform.mapRect(rect).toRect());
return view->updateRegion(xform.map(QRegion(rect.toRect())));
- return view->updateRect(xform.mapRect(rect).toRect());
+ }
+
+ if (item->sceneTransformTranslateOnly && view->identityMatrix) {
+ const qreal dx = item->sceneTransform.dx();
+ const qreal dy = item->sceneTransform.dy();
+ if (!item->hasBoundingRegionGranularity) {
+ QRectF r(rect);
+ r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll());
+ return view->updateRect(r.toRect());
+ }
+ QRegion r(rect.toRect());
+ r.translate(qRound(dx) - view->horizontalScroll(), qRound(dy) - view->verticalScroll());
+ return view->updateRegion(r);
+ }
+
+ if (!viewq->isTransformed()) {
+ if (!item->hasBoundingRegionGranularity)
+ return view->updateRect(item->sceneTransform.mapRect(rect).toRect());
+ return view->updateRegion(item->sceneTransform.map(QRegion(rect.toRect())));
+ }
+
+ QTransform xform = item->sceneTransform;
+ xform *= viewq->viewportTransform();
+ if (!item->hasBoundingRegionGranularity)
+ return view->updateRect(xform.mapRect(rect).toRect());
+ return view->updateRegion(xform.map(QRegion(rect.toRect())));
}
void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren,
qreal parentOpacity)
{
Q_Q(QGraphicsScene);
+ Q_ASSERT(item);
+ Q_ASSERT(!updateAll);
- bool wasDirtyParentViewBoundingRects = false;
- bool wasDirtyParentSceneTransform = false;
- qreal opacity = parentOpacity;
+ if (!item->d_ptr->dirty && !item->d_ptr->dirtyChildren) {
+ resetDirtyItem(item);
+ return;
+ }
- if (item) {
- wasDirtyParentViewBoundingRects = item->d_ptr->paintedViewBoundingRectsNeedRepaint;
- opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
- const bool itemIsHidden = !item->d_ptr->ignoreVisible && !item->d_ptr->visible;
- const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity && opacity == 0.0;
-
- if (item->d_ptr->dirtySceneTransform && !itemIsHidden && !item->d_ptr->itemIsUntransformable()
- && !(itemIsFullyTransparent && item->d_ptr->childrenCombineOpacity())) {
- // Calculate the full scene transform for this item.
- item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform
- : QTransform();
- item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform);
- item->d_ptr->dirtySceneTransform = 0;
- wasDirtyParentSceneTransform = true;
- }
+ const bool itemIsHidden = !item->d_ptr->ignoreVisible && !item->d_ptr->visible;
+ if (itemIsHidden) {
+ resetDirtyItem(item, /*recursive=*/true);
+ return;
+ }
+
+ const bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents);
+ const bool itemHasChildren = !item->d_ptr->children.isEmpty();
+ if (!itemHasContents && !itemHasChildren) {
+ resetDirtyItem(item);
+ return; // Item has neither contents nor children!(?)
+ }
+
+ const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
+ const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity && opacity < 0.0001;
+ if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) {
+ resetDirtyItem(item, /*recursive=*/itemHasChildren);
+ return;
+ }
- if (itemIsHidden || itemIsFullyTransparent || (item->d_ptr->flags & QGraphicsItem::ItemHasNoContents)) {
- // Make sure we don't process invisible items or items with no content.
- item->d_ptr->dirty = 0;
+ bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform;
+ const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
+ if (wasDirtyParentSceneTransform && !itemIsUntransformable) {
+ item->d_ptr->updateSceneTransformFromParent();
+ Q_ASSERT(!item->d_ptr->dirtySceneTransform);
+ }
+
+ const bool wasDirtyParentViewBoundingRects = item->d_ptr->paintedViewBoundingRectsNeedRepaint;
+ if (itemIsFullyTransparent || !itemHasContents || dirtyAncestorContainsChildren) {
+ // Make sure we don't process invisible items or items with no content.
+ item->d_ptr->dirty = 0;
+ item->d_ptr->fullUpdatePending = 0;
+ // Might have a dirty view bounding rect otherwise.
+ if (itemIsFullyTransparent || !itemHasContents)
item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0;
+ }
+
+ if (!hasSceneRect && item->d_ptr->geometryChanged && item->d_ptr->visible) {
+ // Update growingItemsBoundingRect.
+ if (item->d_ptr->sceneTransformTranslateOnly) {
+ growingItemsBoundingRect |= item->boundingRect().translated(item->d_ptr->sceneTransform.dx(),
+ item->d_ptr->sceneTransform.dy());
+ } else {
+ growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(item->boundingRect());
}
}
// Process item.
- if (item && (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint)) {
+ if (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
const bool useCompatUpdate = views.isEmpty() || (connectedSignals & changedSignalMask);
- const bool untransformableItem = item->d_ptr->itemIsUntransformable();
const QRectF itemBoundingRect = adjustedItemBoundingRect(item);
- if (item->d_ptr->geometryChanged) {
- // Update growingItemsBoundingRect.
- if (!hasSceneRect)
- growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(itemBoundingRect);
- item->d_ptr->geometryChanged = 0;
- }
-
- if (useCompatUpdate && !untransformableItem && qFuzzyIsNull(item->boundingRegionGranularity())) {
+ if (useCompatUpdate && !itemIsUntransformable && qFuzzyIsNull(item->boundingRegionGranularity())) {
// This block of code is kept for compatibility. Since 4.5, by default
// QGraphicsView does not connect the signal and we use the below
// method of delivering updates.
- q->update(item->d_ptr->sceneTransform.mapRect(itemBoundingRect));
+ if (item->d_ptr->sceneTransformTranslateOnly) {
+ q->update(itemBoundingRect.translated(item->d_ptr->sceneTransform.dx(),
+ item->d_ptr->sceneTransform.dy()));
+ } else {
+ q->update(item->d_ptr->sceneTransform.mapRect(itemBoundingRect));
+ }
} else {
QRectF dirtyRect;
bool uninitializedDirtyRect = true;
@@ -5416,30 +4461,31 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
for (int j = 0; j < views.size(); ++j) {
QGraphicsView *view = views.at(j);
QGraphicsViewPrivate *viewPrivate = view->d_func();
- if (viewPrivate->fullUpdatePending)
- continue;
- switch (viewPrivate->viewportUpdateMode) {
- case QGraphicsView::NoViewportUpdate:
- continue;
- case QGraphicsView::FullViewportUpdate:
- view->viewport()->update();
- viewPrivate->fullUpdatePending = 1;
+ QRect &paintedViewBoundingRect = item->d_ptr->paintedViewBoundingRects[viewPrivate->viewport];
+ if (viewPrivate->fullUpdatePending
+ || viewPrivate->viewportUpdateMode == QGraphicsView::NoViewportUpdate) {
+ // Okay, if we have a full update pending or no viewport update, this item's
+ // paintedViewBoundingRect will be updated correctly in the next paintEvent if
+ // it is inside the viewport, but for now we can pretend that it is outside.
+ paintedViewBoundingRect = QRect(-1, -1, -1, -1);
continue;
- default:
- break;
}
- QRect &paintedViewBoundingRect = item->d_ptr->paintedViewBoundingRects[viewPrivate->viewport];
- if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
- wasDirtyParentViewBoundingRects = true;
+ if (item->d_ptr->paintedViewBoundingRectsNeedRepaint && !paintedViewBoundingRect.isEmpty()) {
paintedViewBoundingRect.translate(viewPrivate->dirtyScrollOffset);
if (!viewPrivate->updateRect(paintedViewBoundingRect))
- paintedViewBoundingRect = QRect();
+ paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport.
}
if (!item->d_ptr->dirty)
continue;
+ if (!item->d_ptr->paintedViewBoundingRectsNeedRepaint
+ && paintedViewBoundingRect.x() == -1 && paintedViewBoundingRect.y() == -1
+ && paintedViewBoundingRect.width() == -1 && paintedViewBoundingRect.height() == -1) {
+ continue; // Outside viewport.
+ }
+
if (uninitializedDirtyRect) {
dirtyRect = itemBoundingRect;
if (!item->d_ptr->fullUpdatePending) {
@@ -5452,35 +4498,25 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
if (dirtyRect.isEmpty())
continue; // Discard updates outside the bounding rect.
- bool valid = false;
- if (untransformableItem) {
- valid = updateHelper(viewPrivate, item->d_ptr, dirtyRect,
- item->deviceTransform(view->viewportTransform()));
- } else if (!view->isTransformed()) {
- valid = updateHelper(viewPrivate, item->d_ptr, dirtyRect, item->d_ptr->sceneTransform);
- } else {
- QTransform deviceTransform = item->d_ptr->sceneTransform;
- deviceTransform *= view->viewportTransform();
- valid = updateHelper(viewPrivate, item->d_ptr, dirtyRect, deviceTransform);
+ if (!updateHelper(viewPrivate, item->d_ptr, dirtyRect, itemIsUntransformable)
+ && item->d_ptr->paintedViewBoundingRectsNeedRepaint) {
+ paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport.
}
- if (!valid)
- paintedViewBoundingRect = QRect();
}
}
}
- // Process root items / children.
- if (!item || item->d_ptr->dirtyChildren) {
- QList<QGraphicsItem *> *children = item ? &item->d_ptr->children : &topLevelItems;
- const bool allChildrenDirty = item && item->d_ptr->allChildrenDirty;
+ // Process children.
+ if (itemHasChildren && item->d_ptr->dirtyChildren) {
if (!dirtyAncestorContainsChildren) {
- dirtyAncestorContainsChildren = item && item->d_ptr->fullUpdatePending
+ dirtyAncestorContainsChildren = item->d_ptr->fullUpdatePending
&& (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
}
- const bool parentIgnoresVisible = item && item->d_ptr->ignoreVisible;
- const bool parentIgnoresOpacity = item && item->d_ptr->ignoreOpacity;
- for (int i = 0; i < children->size(); ++i) {
- QGraphicsItem *child = children->at(i);
+ const bool allChildrenDirty = item->d_ptr->allChildrenDirty;
+ const bool parentIgnoresVisible = item->d_ptr->ignoreVisible;
+ const bool parentIgnoresOpacity = item->d_ptr->ignoreOpacity;
+ for (int i = 0; i < item->d_ptr->children.size(); ++i) {
+ QGraphicsItem *child = item->d_ptr->children.at(i);
if (wasDirtyParentSceneTransform)
child->d_ptr->dirtySceneTransform = 1;
if (wasDirtyParentViewBoundingRects)
@@ -5489,36 +4525,19 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
child->d_ptr->ignoreVisible = 1;
if (parentIgnoresOpacity)
child->d_ptr->ignoreOpacity = 1;
-
if (allChildrenDirty) {
child->d_ptr->dirty = 1;
child->d_ptr->fullUpdatePending = 1;
child->d_ptr->dirtyChildren = 1;
child->d_ptr->allChildrenDirty = 1;
- } else if (!child->d_ptr->dirty && !child->d_ptr->dirtyChildren) {
- resetDirtyItem(child);
- continue;
- }
-
- if (dirtyAncestorContainsChildren || updateAll) {
- // No need to process this child's dirty rect, hence reset the dirty state.
- // However, we have to continue the recursion because it might have a dirty
- // view bounding rect that needs repaint. We also have to reset the dirty
- // state of its descendants.
- child->d_ptr->dirty = 0;
- child->d_ptr->fullUpdatePending = 0;
- if (updateAll)
- child->d_ptr->paintedViewBoundingRectsNeedRepaint = 0;
}
-
processDirtyItemsRecursive(child, dirtyAncestorContainsChildren, opacity);
}
} else if (wasDirtyParentSceneTransform) {
item->d_ptr->invalidateChildrenSceneTransform();
}
- if (item)
- resetDirtyItem(item);
+ resetDirtyItem(item);
}
/*!
diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h
index 6aaeb91..d790f90 100644
--- a/src/gui/graphicsview/qgraphicsscene.h
+++ b/src/gui/graphicsview/qgraphicsscene.h
@@ -83,6 +83,7 @@ class QGraphicsSimpleTextItem;
class QGraphicsTextItem;
class QGraphicsView;
class QGraphicsWidget;
+class QGraphicsSceneIndex;
class QHelpEvent;
class QInputMethodEvent;
class QKeyEvent;
@@ -152,22 +153,38 @@ public:
QRectF itemsBoundingRect() const;
QList<QGraphicsItem *> items() const;
- QList<QGraphicsItem *> items(const QPointF &pos) const;
- QList<QGraphicsItem *> items(const QRectF &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
- QList<QGraphicsItem *> items(const QPolygonF &polygon, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
- QList<QGraphicsItem *> items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
+ QList<QGraphicsItem *> items(Qt::SortOrder order) const; // ### Qt 5: unify
+
+ QList<QGraphicsItem *> items(const QPointF &pos, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
+ QList<QGraphicsItem *> items(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
+ QList<QGraphicsItem *> items(const QPolygonF &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
+ QList<QGraphicsItem *> items(const QPainterPath &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
+
+ QList<QGraphicsItem *> items(const QPointF &pos) const; // ### obsolete
+ QList<QGraphicsItem *> items(const QRectF &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete
+ QList<QGraphicsItem *> items(const QPolygonF &polygon, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete
+ QList<QGraphicsItem *> items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; // ### obsolete
+
QList<QGraphicsItem *> collidingItems(const QGraphicsItem *item, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const;
- QGraphicsItem *itemAt(const QPointF &pos) const;
+
+ QGraphicsItem *itemAt(const QPointF &pos) const; // ### obsolete
+ QGraphicsItem *itemAt(const QPointF &pos, const QTransform &deviceTransform) const;
inline QList<QGraphicsItem *> items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const
- { return items(QRectF(x, y, w, h), mode); }
- inline QGraphicsItem *itemAt(qreal x, qreal y) const
+ { return items(QRectF(x, y, w, h), mode); } // ### obsolete
+ inline QList<QGraphicsItem *> items(qreal x, qreal y, qreal w, qreal h, Qt::ItemSelectionMode mode, Qt::SortOrder order,
+ const QTransform &deviceTransform = QTransform()) const
+ { return items(QRectF(x, y, w, h), mode, order, deviceTransform); }
+ inline QGraphicsItem *itemAt(qreal x, qreal y) const // ### obsolete
{ return itemAt(QPointF(x, y)); }
+ inline QGraphicsItem *itemAt(qreal x, qreal y, const QTransform &deviceTransform) const
+ { return itemAt(QPointF(x, y), deviceTransform); }
QList<QGraphicsItem *> selectedItems() const;
QPainterPath selectionArea() const;
void setSelectionArea(const QPainterPath &path);
- void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode);
+ void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode);
+ void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode, const QTransform &deviceTransform);
QGraphicsItemGroup *createItemGroup(const QList<QGraphicsItem *> &items);
void destroyItemGroup(QGraphicsItemGroup *group);
@@ -275,11 +292,8 @@ Q_SIGNALS:
private:
Q_DECLARE_PRIVATE(QGraphicsScene)
Q_DISABLE_COPY(QGraphicsScene)
- Q_PRIVATE_SLOT(d_func(), void _q_updateIndex())
Q_PRIVATE_SLOT(d_func(), void _q_emitUpdated())
- Q_PRIVATE_SLOT(d_func(), void _q_updateLater())
Q_PRIVATE_SLOT(d_func(), void _q_polishItems())
- Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache())
Q_PRIVATE_SLOT(d_func(), void _q_processDirtyItems())
friend class QGraphicsItem;
friend class QGraphicsItemPrivate;
@@ -287,6 +301,10 @@ private:
friend class QGraphicsViewPrivate;
friend class QGraphicsWidget;
friend class QGraphicsWidgetPrivate;
+ friend class QGraphicsSceneIndex;
+ friend class QGraphicsSceneIndexPrivate;
+ friend class QGraphicsSceneBspTreeIndex;
+ friend class QGraphicsSceneBspTreeIndexPrivate;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsScene::SceneLayers)
diff --git a/src/gui/graphicsview/qgraphicsscene_bsp.cpp b/src/gui/graphicsview/qgraphicsscene_bsp.cpp
index 3f3e58b..fb4b9a4 100644
--- a/src/gui/graphicsview/qgraphicsscene_bsp.cpp
+++ b/src/gui/graphicsview/qgraphicsscene_bsp.cpp
@@ -70,12 +70,15 @@ class QGraphicsSceneFindItemBspTreeVisitor : public QGraphicsSceneBspTreeVisitor
{
public:
QList<QGraphicsItem *> *foundItems;
+ bool onlyTopLevelItems;
void visit(QList<QGraphicsItem *> *items)
{
for (int i = 0; i < items->size(); ++i) {
QGraphicsItem *item = items->at(i);
- if (!item->d_func()->itemDiscovered && item->isVisible()) {
+ if (onlyTopLevelItems && item->d_ptr->parent)
+ item = item->topLevelItem();
+ if (!item->d_func()->itemDiscovered && item->d_ptr->visible) {
item->d_func()->itemDiscovered = 1;
foundItems->prepend(item);
}
@@ -143,19 +146,15 @@ void QGraphicsSceneBspTree::removeItems(const QSet<QGraphicsItem *> &items)
}
}
-QList<QGraphicsItem *> QGraphicsSceneBspTree::items(const QRectF &rect)
+QList<QGraphicsItem *> QGraphicsSceneBspTree::items(const QRectF &rect, bool onlyTopLevelItems) const
{
QList<QGraphicsItem *> tmp;
findVisitor->foundItems = &tmp;
+ findVisitor->onlyTopLevelItems = onlyTopLevelItems;
climbTree(findVisitor, rect);
- return tmp;
-}
-
-QList<QGraphicsItem *> QGraphicsSceneBspTree::items(const QPointF &pos)
-{
- QList<QGraphicsItem *> tmp;
- findVisitor->foundItems = &tmp;
- climbTree(findVisitor, pos);
+ // Reset discovery bits.
+ for (int i = 0; i < tmp.size(); ++i)
+ tmp.at(i)->d_ptr->itemDiscovered = 0;
return tmp;
}
@@ -235,47 +234,17 @@ void QGraphicsSceneBspTree::initialize(const QRectF &rect, int depth, int index)
}
}
-void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index)
-{
- if (nodes.isEmpty())
- return;
-
- const Node &node = nodes.at(index);
- int childIndex = firstChildIndex(index);
-
- switch (node.type) {
- case Node::Leaf: {
- visitor->visit(&leaves[node.leafIndex]);
- break;
- }
- case Node::Vertical:
- if (pos.x() < node.offset) {
- climbTree(visitor, pos, childIndex);
- } else {
- climbTree(visitor, pos, childIndex + 1);
- }
- break;
- case Node::Horizontal:
- if (pos.y() < node.offset) {
- climbTree(visitor, pos, childIndex);
- } else {
- climbTree(visitor, pos, childIndex + 1);
- }
- break;
- }
-}
-
-void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index)
+void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index) const
{
if (nodes.isEmpty())
return;
const Node &node = nodes.at(index);
- int childIndex = firstChildIndex(index);
+ const int childIndex = firstChildIndex(index);
switch (node.type) {
case Node::Leaf: {
- visitor->visit(&leaves[node.leafIndex]);
+ visitor->visit(const_cast<QList<QGraphicsItem*>*>(&leaves[node.leafIndex]));
break;
}
case Node::Vertical:
@@ -288,7 +257,6 @@ void QGraphicsSceneBspTree::climbTree(QGraphicsSceneBspTreeVisitor *visitor, con
}
break;
case Node::Horizontal:
- int childIndex = firstChildIndex(index);
if (rect.top() < node.offset) {
climbTree(visitor, rect, childIndex);
if (rect.bottom() >= node.offset)
diff --git a/src/gui/graphicsview/qgraphicsscene_bsp_p.h b/src/gui/graphicsview/qgraphicsscene_bsp_p.h
index 73a937f..4cac64a 100644
--- a/src/gui/graphicsview/qgraphicsscene_bsp_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_bsp_p.h
@@ -92,8 +92,7 @@ public:
void removeItem(QGraphicsItem *item, const QRectF &rect);
void removeItems(const QSet<QGraphicsItem *> &items);
- QList<QGraphicsItem *> items(const QRectF &rect);
- QList<QGraphicsItem *> items(const QPointF &pos);
+ QList<QGraphicsItem *> items(const QRectF &rect, bool onlyTopLevelItems = false) const;
int leafCount() const;
inline int firstChildIndex(int index) const
@@ -106,11 +105,7 @@ public:
private:
void initialize(const QRectF &rect, int depth, int index);
- void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QPointF &pos, int index = 0);
- void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index = 0);
-
- void findItems(QList<QGraphicsItem *> *foundItems, const QRectF &rect, int index);
- void findItems(QList<QGraphicsItem *> *foundItems, const QPointF &pos, int index);
+ void climbTree(QGraphicsSceneBspTreeVisitor *visitor, const QRectF &rect, int index = 0) const;
QRectF rectForIndex(int index) const;
QVector<Node> nodes;
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index dc720a7..ffd62d5 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -59,7 +59,6 @@
#include "qgraphicssceneevent.h"
#include "qgraphicsview.h"
-#include "qgraphicsscene_bsp_p.h"
#include "qgraphicsitem_p.h"
#include <private/qobject_p.h>
@@ -72,10 +71,9 @@
#include <QtGui/qstyle.h>
#include <QtGui/qstyleoption.h>
-static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000;
-
QT_BEGIN_NAMESPACE
+class QGraphicsSceneIndex;
class QGraphicsView;
class QGraphicsWidget;
@@ -86,24 +84,19 @@ public:
QGraphicsScenePrivate();
void init();
+ static QGraphicsScenePrivate *get(QGraphicsScene *q);
+
quint32 changedSignalMask;
QGraphicsScene::ItemIndexMethod indexMethod;
- int bspTreeDepth;
-
- QList<QGraphicsItem *> estimateItemsInRect(const QRectF &rect) const;
- void addToIndex(QGraphicsItem *item);
- void removeFromIndex(QGraphicsItem *item);
- void resetIndex();
+ QGraphicsSceneIndex *index;
- QGraphicsSceneBspTree bspTree;
- void _q_updateIndex();
int lastItemCount;
QRectF sceneRect;
bool hasSceneRect;
+ bool dirtyGrowingItemsBoundingRect;
QRectF growingItemsBoundingRect;
- QRectF largestUntransformableItem;
void _q_emitUpdated();
QList<QRectF> updatedRects;
@@ -114,9 +107,6 @@ public:
QPainterPath selectionArea;
int selectionChanging;
QSet<QGraphicsItem *> selectedItems;
- QList<QGraphicsItem *> unindexedItems;
- QList<QGraphicsItem *> indexedItems;
- QList<QGraphicsItem *> pendingUpdateItems;
QList<QGraphicsItem *> unpolishedItems;
QList<QGraphicsItem *> topLevelItems;
bool needSortTopLevelItems;
@@ -128,21 +118,11 @@ public:
void _q_processDirtyItems();
- QList<int> freeItemIndexes;
- bool regenerateIndex;
-
- bool purgePending;
void removeItemHelper(QGraphicsItem *item);
- QSet<QGraphicsItem *> removedItems;
- void purgeRemovedItems();
QBrush backgroundBrush;
QBrush foregroundBrush;
- int indexTimerId;
- bool restartIndexTimer;
- void startIndexTimer(int interval = QGRAPHICSSCENE_INDEXTIMER_TIMEOUT);
-
bool stickyFocus;
bool hasFocus;
QGraphicsItem *focusItem;
@@ -181,7 +161,6 @@ public:
QList<QGraphicsItem *> itemsAtPosition(const QPoint &screenPos,
const QPointF &scenePos,
QWidget *widget) const;
- static bool itemCollidesWithPath(QGraphicsItem *item, const QPainterPath &path, Qt::ItemSelectionMode mode);
void storeMouseButtonsForMouseGrabber(QGraphicsSceneMouseEvent *event);
QList<QGraphicsView *> views;
@@ -210,69 +189,14 @@ public:
void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent);
QGraphicsWidget *windowForItem(const QGraphicsItem *item) const;
- QList<QGraphicsItem *> topLevelItemsInStackingOrder(const QTransform *const, QRegion *);
- void recursive_items_helper(QGraphicsItem *item, QRectF rect, QList<QGraphicsItem *> *items,
- const QTransform &parentTransform, const QTransform &viewTransform,
- Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const;
-
- QList<QGraphicsItem *> items_helper(const QPointF &pos) const;
- QList<QGraphicsItem *> items_helper(const QRectF &rect,
- Qt::ItemSelectionMode mode,
- Qt::SortOrder order) const;
- QList<QGraphicsItem *> items_helper(const QPolygonF &rect,
- Qt::ItemSelectionMode mode,
- Qt::SortOrder order) const;
- QList<QGraphicsItem *> items_helper(const QPainterPath &rect,
- Qt::ItemSelectionMode mode,
- Qt::SortOrder order) const;
- void childItems_helper(QList<QGraphicsItem *> *items,
- const QGraphicsItem *parent,
- const QPointF &pos) const;
- void childItems_helper(QList<QGraphicsItem *> *items,
- const QGraphicsItem *parent,
- const QRectF &rect,
- Qt::ItemSelectionMode mode) const;
- void childItems_helper(QList<QGraphicsItem *> *items,
- const QGraphicsItem *parent,
- const QPolygonF &polygon,
- Qt::ItemSelectionMode mode) const;
- void childItems_helper(QList<QGraphicsItem *> *items,
- const QGraphicsItem *parent,
- const QPainterPath &path,
- Qt::ItemSelectionMode mode) const;
-
- bool sortCacheEnabled;
- bool updatingSortCache;
- void invalidateSortCache();
- static void climbTree(QGraphicsItem *item, int *stackingOrder);
- void _q_updateSortCache();
-
- static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2);
- static bool closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2);
-
- static inline bool closestItemFirst_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2)
- {
- return item1->d_ptr->globalStackingOrder < item2->d_ptr->globalStackingOrder;
- }
- static inline bool closestItemLast_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2)
- {
- return item1->d_ptr->globalStackingOrder >= item2->d_ptr->globalStackingOrder;
- }
-
- static void sortItems(QList<QGraphicsItem *> *itemList, Qt::SortOrder order, bool cached);
+ bool sortCacheEnabled; // for compatibility
void drawItemHelper(QGraphicsItem *item, QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget,
bool painterStateProtection);
- inline void drawItems(QPainter *painter, const QTransform *const viewTransform,
- QRegion *exposedRegion, QWidget *widget)
- {
- const QList<QGraphicsItem *> tli = topLevelItemsInStackingOrder(viewTransform, exposedRegion);
- for (int i = 0; i < tli.size(); ++i)
- drawSubtreeRecursive(tli.at(i), painter, viewTransform, exposedRegion, widget);
- return;
- }
+ void drawItems(QPainter *painter, const QTransform *const viewTransform,
+ QRegion *exposedRegion, QWidget *widget);
void drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform *const,
QRegion *exposedRegion, QWidget *widget, qreal parentOpacity = qreal(1.0));
@@ -282,18 +206,32 @@ public:
void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false,
qreal parentOpacity = qreal(1.0));
- inline void resetDirtyItem(QGraphicsItem *item)
+ inline void resetDirtyItem(QGraphicsItem *item, bool recursive = false)
{
Q_ASSERT(item);
item->d_ptr->dirty = 0;
item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0;
item->d_ptr->geometryChanged = 0;
+ if (!item->d_ptr->dirtyChildren)
+ recursive = false;
item->d_ptr->dirtyChildren = 0;
item->d_ptr->needsRepaint = QRectF();
item->d_ptr->allChildrenDirty = 0;
item->d_ptr->fullUpdatePending = 0;
item->d_ptr->ignoreVisible = 0;
item->d_ptr->ignoreOpacity = 0;
+ if (recursive) {
+ for (int i = 0; i < item->d_ptr->children.size(); ++i)
+ resetDirtyItem(item->d_ptr->children.at(i), recursive);
+ }
+ }
+
+ inline void ensureSortedTopLevelItems()
+ {
+ if (needSortTopLevelItems) {
+ qSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf);
+ needSortTopLevelItems = false;
+ }
}
QStyle *style;
@@ -320,6 +258,25 @@ public:
void updateInputMethodSensitivityInViews();
};
+// QRectF::intersects() returns false always if either the source or target
+// rectangle's width or height are 0. This works around that problem.
+static inline void _q_adjustRect(QRectF *rect)
+{
+ Q_ASSERT(rect);
+ if (!rect->width())
+ rect->adjust(-0.00001, 0, 0.00001, 0);
+ if (!rect->height())
+ rect->adjust(0, -0.00001, 0, 0.00001);
+}
+
+static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
+{
+ Q_ASSERT(item);
+ QRectF boundingRect(item->boundingRect());
+ _q_adjustRect(&boundingRect);
+ return boundingRect;
+}
+
QT_END_NAMESPACE
#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
new file mode 100644
index 0000000..a54ade9
--- /dev/null
+++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp
@@ -0,0 +1,782 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the 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 qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QGraphicsSceneBspTreeIndex
+ \brief The QGraphicsSceneBspTreeIndex class provides an implementation of
+ a BSP indexing algorithm for discovering items in QGraphicsScene.
+ \since 4.6
+ \ingroup multimedia
+ \ingroup graphicsview-api
+ \mainclass
+ \internal
+
+ QGraphicsSceneBspTreeIndex index use a BSP(Binary Space Partitioning)
+ implementation to discover items quickly. This implementation is
+ very efficient for static scene. It has a depth that you can set.
+ The depth directly affects performance and memory usage; the latter
+ growing exponentially with the depth of the tree. With an optimal tree
+ depth, the index can instantly determine the locality of items, even
+ for scenes with thousands or millions of items. This also greatly improves
+ rendering performance.
+
+ By default, the value is 0, in which case Qt will guess a reasonable
+ default depth based on the size, location and number of items in the
+ scene. If these parameters change frequently, however, you may experience
+ slowdowns as the index retunes the depth internally. You can avoid
+ potential slowdowns by fixating the tree depth through setting this
+ property.
+
+ The depth of the tree and the size of the scene rectangle decide the
+ granularity of the scene's partitioning. The size of each scene segment is
+ determined by the following algorithm:
+
+ The BSP tree has an optimal size when each segment contains between 0 and
+ 10 items.
+
+ \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex
+*/
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+#include <private/qgraphicsscene_p.h>
+#include <private/qgraphicsscenebsptreeindex_p.h>
+#include <private/qgraphicssceneindex_p.h>
+
+#include <QtCore/qmath.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+static inline int intmaxlog(int n)
+{
+ return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0);
+}
+
+/*!
+ Constructs a private scene bsp index.
+*/
+QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene)
+ : QGraphicsSceneIndexPrivate(scene),
+ bspTreeDepth(0),
+ indexTimerId(0),
+ restartIndexTimer(false),
+ regenerateIndex(true),
+ lastItemCount(0),
+ purgePending(false),
+ sortCacheEnabled(false),
+ updatingSortCache(false)
+{
+}
+
+
+/*!
+ This method will update the BSP index by removing the items from the temporary
+ unindexed list and add them in the indexedItems list. This will also
+ update the growingItemsBoundingRect if needed. This will update the BSP
+ implementation as well.
+
+ \internal
+*/
+void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex()
+{
+ Q_Q(QGraphicsSceneBspTreeIndex);
+ if (!indexTimerId)
+ return;
+
+ q->killTimer(indexTimerId);
+ indexTimerId = 0;
+
+ purgeRemovedItems();
+
+ // Add unindexedItems to indexedItems
+ for (int i = 0; i < unindexedItems.size(); ++i) {
+ if (QGraphicsItem *item = unindexedItems.at(i)) {
+ Q_ASSERT(!item->d_ptr->itemDiscovered);
+ if (!freeItemIndexes.isEmpty()) {
+ int freeIndex = freeItemIndexes.takeFirst();
+ item->d_func()->index = freeIndex;
+ indexedItems[freeIndex] = item;
+ } else {
+ item->d_func()->index = indexedItems.size();
+ indexedItems << item;
+ }
+ }
+ }
+
+ // Determine whether we should regenerate the BSP tree.
+ if (bspTreeDepth == 0) {
+ int oldDepth = intmaxlog(lastItemCount);
+ bspTreeDepth = intmaxlog(indexedItems.size());
+ static const int slack = 100;
+ if (bsp.leafCount() == 0 || (oldDepth != bspTreeDepth && qAbs(lastItemCount - indexedItems.size()) > slack)) {
+ // ### Crude algorithm.
+ regenerateIndex = true;
+ }
+ }
+
+ // Regenerate the tree.
+ if (regenerateIndex) {
+ regenerateIndex = false;
+ bsp.initialize(sceneRect, bspTreeDepth);
+ unindexedItems = indexedItems;
+ lastItemCount = indexedItems.size();
+ }
+
+ // Insert all unindexed items into the tree.
+ for (int i = 0; i < unindexedItems.size(); ++i) {
+ if (QGraphicsItem *item = unindexedItems.at(i)) {
+ if (item->d_ptr->itemIsUntransformable()) {
+ untransformableItems << item;
+ continue;
+ }
+ if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
+ continue;
+
+ bsp.insertItem(item, item->sceneBoundingRect());
+ }
+ }
+ unindexedItems.clear();
+}
+
+
+/*!
+ \internal
+
+ Removes stale pointers from all data structures.
+*/
+void QGraphicsSceneBspTreeIndexPrivate::purgeRemovedItems()
+{
+ if (!purgePending && removedItems.isEmpty())
+ return;
+
+ // Remove stale items from the BSP tree.
+ bsp.removeItems(removedItems);
+ // Purge this list.
+ removedItems.clear();
+ freeItemIndexes.clear();
+ for (int i = 0; i < indexedItems.size(); ++i) {
+ if (!indexedItems.at(i))
+ freeItemIndexes << i;
+ }
+ purgePending = false;
+}
+
+/*!
+ \internal
+
+ Starts or restarts the timer used for reindexing unindexed items.
+*/
+void QGraphicsSceneBspTreeIndexPrivate::startIndexTimer(int interval)
+{
+ Q_Q(QGraphicsSceneBspTreeIndex);
+ if (indexTimerId) {
+ restartIndexTimer = true;
+ } else {
+ indexTimerId = q->startTimer(interval);
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneBspTreeIndexPrivate::resetIndex()
+{
+ purgeRemovedItems();
+ for (int i = 0; i < indexedItems.size(); ++i) {
+ if (QGraphicsItem *item = indexedItems.at(i)) {
+ item->d_ptr->index = -1;
+ Q_ASSERT(!item->d_ptr->itemDiscovered);
+ unindexedItems << item;
+ }
+ }
+ indexedItems.clear();
+ freeItemIndexes.clear();
+ untransformableItems.clear();
+ regenerateIndex = true;
+ startIndexTimer();
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stackingOrder)
+{
+ if (!item->d_ptr->children.isEmpty()) {
+ QList<QGraphicsItem *> childList = item->d_ptr->children;
+ qSort(childList.begin(), childList.end(), qt_closestLeaf);
+ for (int i = 0; i < childList.size(); ++i) {
+ QGraphicsItem *item = childList.at(i);
+ if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent))
+ climbTree(childList.at(i), stackingOrder);
+ }
+ item->d_ptr->globalStackingOrder = (*stackingOrder)++;
+ for (int i = 0; i < childList.size(); ++i) {
+ QGraphicsItem *item = childList.at(i);
+ if (item->flags() & QGraphicsItem::ItemStacksBehindParent)
+ climbTree(childList.at(i), stackingOrder);
+ }
+ } else {
+ item->d_ptr->globalStackingOrder = (*stackingOrder)++;
+ }
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache()
+{
+ Q_Q(QGraphicsSceneBspTreeIndex);
+ _q_updateIndex();
+
+ if (!sortCacheEnabled || !updatingSortCache)
+ return;
+
+ updatingSortCache = false;
+ int stackingOrder = 0;
+
+ QList<QGraphicsItem *> topLevels;
+ const QList<QGraphicsItem *> items = q->items();
+ for (int i = 0; i < items.size(); ++i) {
+ QGraphicsItem *item = items.at(i);
+ if (item && !item->d_ptr->parent)
+ topLevels << item;
+ }
+
+ qSort(topLevels.begin(), topLevels.end(), qt_closestLeaf);
+ for (int i = 0; i < topLevels.size(); ++i)
+ climbTree(topLevels.at(i), &stackingOrder);
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneBspTreeIndexPrivate::invalidateSortCache()
+{
+ Q_Q(QGraphicsSceneBspTreeIndex);
+ if (!sortCacheEnabled || updatingSortCache)
+ return;
+
+ updatingSortCache = true;
+ QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection);
+}
+
+void QGraphicsSceneBspTreeIndexPrivate::addItem(QGraphicsItem *item, bool recursive)
+{
+ if (!item)
+ return;
+
+ // Prevent reusing a recently deleted pointer: purge all removed item from our lists.
+ purgeRemovedItems();
+
+ // Invalidate any sort caching; arrival of a new item means we need to resort.
+ // Update the scene's sort cache settings.
+ item->d_ptr->globalStackingOrder = -1;
+ invalidateSortCache();
+
+ // Indexing requires sceneBoundingRect(), but because \a item might
+ // not be completely constructed at this point, we need to store it in
+ // a temporary list and schedule an indexing for later.
+ if (item->d_ptr->index == -1) {
+ Q_ASSERT(!unindexedItems.contains(item));
+ unindexedItems << item;
+ startIndexTimer(0);
+ } else {
+ Q_ASSERT(indexedItems.contains(item));
+ qWarning("QGraphicsSceneBspTreeIndex::addItem: item has already been added to this BSP");
+ }
+
+ if (recursive) {
+ for (int i = 0; i < item->d_ptr->children.size(); ++i)
+ addItem(item->d_ptr->children.at(i), recursive);
+ }
+}
+
+void QGraphicsSceneBspTreeIndexPrivate::removeItem(QGraphicsItem *item, bool recursive,
+ bool moveToUnindexedItems)
+{
+ if (!item)
+ return;
+
+ if (item->d_ptr->index != -1) {
+ Q_ASSERT(item->d_ptr->index < indexedItems.size());
+ Q_ASSERT(indexedItems.at(item->d_ptr->index) == item);
+ Q_ASSERT(!item->d_ptr->itemDiscovered);
+ freeItemIndexes << item->d_ptr->index;
+ indexedItems[item->d_ptr->index] = 0;
+ item->d_ptr->index = -1;
+
+ if (item->d_ptr->itemIsUntransformable()) {
+ untransformableItems.removeOne(item);
+ } else if (item->d_ptr->inDestructor) {
+ // Avoid virtual function calls from the destructor.
+ purgePending = true;
+ removedItems << item;
+ } else if (!(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) {
+ bsp.removeItem(item, item->sceneBoundingRect());
+ }
+ } else {
+ unindexedItems.removeOne(item);
+ }
+ invalidateSortCache(); // ### Only do this when removing from BSP?
+
+ Q_ASSERT(item->d_ptr->index == -1);
+ Q_ASSERT(!indexedItems.contains(item));
+ Q_ASSERT(!unindexedItems.contains(item));
+ Q_ASSERT(!untransformableItems.contains(item));
+
+ if (moveToUnindexedItems)
+ addItem(item);
+
+ if (recursive) {
+ for (int i = 0; i < item->d_ptr->children.size(); ++i)
+ removeItem(item->d_ptr->children.at(i), recursive, moveToUnindexedItems);
+ }
+}
+
+QList<QGraphicsItem *> QGraphicsSceneBspTreeIndexPrivate::estimateItems(const QRectF &rect, Qt::SortOrder order,
+ bool onlyTopLevelItems)
+{
+ Q_Q(QGraphicsSceneBspTreeIndex);
+ if (onlyTopLevelItems && rect.isNull())
+ return q->QGraphicsSceneIndex::estimateTopLevelItems(rect, order);
+
+ purgeRemovedItems();
+ _q_updateSortCache();
+ Q_ASSERT(unindexedItems.isEmpty());
+
+ QList<QGraphicsItem *> rectItems = bsp.items(rect, onlyTopLevelItems);
+ if (onlyTopLevelItems) {
+ for (int i = 0; i < untransformableItems.size(); ++i) {
+ QGraphicsItem *item = untransformableItems.at(i);
+ if (!item->d_ptr->parent) {
+ rectItems << item;
+ } else {
+ item = item->topLevelItem();
+ if (!rectItems.contains(item))
+ rectItems << item;
+ }
+ }
+ } else {
+ rectItems += untransformableItems;
+ }
+
+ sortItems(&rectItems, order, sortCacheEnabled, onlyTopLevelItems);
+ return rectItems;
+}
+
+/*!
+ Returns true if \a item1 is on top of \a item2.
+
+ \internal
+*/
+bool QGraphicsSceneBspTreeIndexPrivate::closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2)
+{
+ // Siblings? Just check their z-values.
+ const QGraphicsItemPrivate *d1 = item1->d_ptr;
+ const QGraphicsItemPrivate *d2 = item2->d_ptr;
+ if (d1->parent == d2->parent)
+ return qt_closestLeaf(item1, item2);
+
+ // Find common ancestor, and each item's ancestor closest to the common
+ // ancestor.
+ int item1Depth = d1->depth;
+ int item2Depth = d2->depth;
+ const QGraphicsItem *p = item1;
+ const QGraphicsItem *t1 = item1;
+ while (item1Depth > item2Depth && (p = p->d_ptr->parent)) {
+ if (p == item2) {
+ // item2 is one of item1's ancestors; item1 is on top
+ return !(t1->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
+ }
+ t1 = p;
+ --item1Depth;
+ }
+ p = item2;
+ const QGraphicsItem *t2 = item2;
+ while (item2Depth > item1Depth && (p = p->d_ptr->parent)) {
+ if (p == item1) {
+ // item1 is one of item2's ancestors; item1 is not on top
+ return (t2->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent);
+ }
+ t2 = p;
+ --item2Depth;
+ }
+
+ // item1Ancestor is now at the same level as item2Ancestor, but not the same.
+ const QGraphicsItem *a1 = t1;
+ const QGraphicsItem *a2 = t2;
+ while (a1) {
+ const QGraphicsItem *p1 = a1;
+ const QGraphicsItem *p2 = a2;
+ a1 = a1->parentItem();
+ a2 = a2->parentItem();
+ if (a1 && a1 == a2)
+ return qt_closestLeaf(p1, p2);
+ }
+
+ // No common ancestor? Then just compare the items' toplevels directly.
+ return qt_closestLeaf(t1->topLevelItem(), t2->topLevelItem());
+}
+
+/*!
+ Returns true if \a item2 is on top of \a item1.
+
+ \internal
+*/
+bool QGraphicsSceneBspTreeIndexPrivate::closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2)
+{
+ return closestItemFirst_withoutCache(item2, item1);
+}
+
+/*!
+ Sort a list of \a itemList in a specific \a order and use the cache if requested.
+
+ \internal
+*/
+void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList<QGraphicsItem *> *itemList, Qt::SortOrder order,
+ bool sortCacheEnabled, bool onlyTopLevelItems)
+{
+ if (order == Qt::SortOrder(-1))
+ return;
+
+ if (onlyTopLevelItems) {
+ if (order == Qt::AscendingOrder)
+ qSort(itemList->begin(), itemList->end(), qt_closestLeaf);
+ else if (order == Qt::DescendingOrder)
+ qSort(itemList->begin(), itemList->end(), qt_notclosestLeaf);
+ return;
+ }
+
+ if (sortCacheEnabled) {
+ if (order == Qt::AscendingOrder) {
+ qSort(itemList->begin(), itemList->end(), closestItemFirst_withCache);
+ } else if (order == Qt::DescendingOrder) {
+ qSort(itemList->begin(), itemList->end(), closestItemLast_withCache);
+ }
+ } else {
+ if (order == Qt::AscendingOrder) {
+ qSort(itemList->begin(), itemList->end(), closestItemFirst_withoutCache);
+ } else if (order == Qt::DescendingOrder) {
+ qSort(itemList->begin(), itemList->end(), closestItemLast_withoutCache);
+ }
+ }
+}
+
+/*!
+ Constructs a BSP scene index for the given \a scene.
+*/
+QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene)
+ : QGraphicsSceneIndex(*new QGraphicsSceneBspTreeIndexPrivate(scene), scene)
+{
+
+}
+
+QGraphicsSceneBspTreeIndex::~QGraphicsSceneBspTreeIndex()
+{
+ Q_D(QGraphicsSceneBspTreeIndex);
+ for (int i = 0; i < d->indexedItems.size(); ++i) {
+ // Ensure item bits are reset properly.
+ if (QGraphicsItem *item = d->indexedItems.at(i)) {
+ Q_ASSERT(!item->d_ptr->itemDiscovered);
+ item->d_ptr->index = -1;
+ }
+ }
+}
+
+/*!
+ \reimp
+ Clear the all the BSP index.
+*/
+void QGraphicsSceneBspTreeIndex::clear()
+{
+ Q_D(QGraphicsSceneBspTreeIndex);
+ d->bsp.clear();
+ d->lastItemCount = 0;
+ d->freeItemIndexes.clear();
+ for (int i = 0; i < d->indexedItems.size(); ++i) {
+ // Ensure item bits are reset properly.
+ if (QGraphicsItem *item = d->indexedItems.at(i)) {
+ Q_ASSERT(!item->d_ptr->itemDiscovered);
+ item->d_ptr->index = -1;
+ }
+ }
+ d->indexedItems.clear();
+ d->unindexedItems.clear();
+ d->untransformableItems.clear();
+}
+
+/*!
+ Add the \a item into the BSP index.
+*/
+void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item)
+{
+ Q_D(QGraphicsSceneBspTreeIndex);
+ d->addItem(item);
+}
+
+/*!
+ Remove the \a item from the BSP index.
+*/
+void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item)
+{
+ Q_D(QGraphicsSceneBspTreeIndex);
+ d->removeItem(item);
+}
+
+/*!
+ \reimp
+ Update the BSP when the \a item 's bounding rect has changed.
+*/
+void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item)
+{
+ if (!item)
+ return;
+
+ if (item->d_ptr->index == -1 || item->d_ptr->itemIsUntransformable()
+ || (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) {
+ return; // Item is not in BSP tree; nothing to do.
+ }
+
+ Q_D(QGraphicsSceneBspTreeIndex);
+ QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item);
+ d->removeItem(thatItem, /*recursive=*/false, /*moveToUnindexedItems=*/true);
+ for (int i = 0; i < item->d_ptr->children.size(); ++i) // ### Do we really need this?
+ prepareBoundingRectChange(item->d_ptr->children.at(i));
+}
+
+/*!
+ Returns an estimation visible items that are either inside or
+ intersect with the specified \a rect and return a list sorted using \a order.
+
+ \a deviceTransform is the transformation apply to the view.
+
+*/
+QList<QGraphicsItem *> QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order) const
+{
+ Q_D(const QGraphicsSceneBspTreeIndex);
+ return const_cast<QGraphicsSceneBspTreeIndexPrivate*>(d)->estimateItems(rect, order);
+}
+
+QList<QGraphicsItem *> QGraphicsSceneBspTreeIndex::estimateTopLevelItems(const QRectF &rect, Qt::SortOrder order) const
+{
+ Q_D(const QGraphicsSceneBspTreeIndex);
+ return const_cast<QGraphicsSceneBspTreeIndexPrivate*>(d)->estimateItems(rect, order, /*onlyTopLevels=*/true);
+}
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const;
+
+ Return all items in the BSP index and sort them using \a order.
+*/
+QList<QGraphicsItem *> QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) const
+{
+ Q_D(const QGraphicsSceneBspTreeIndex);
+ const_cast<QGraphicsSceneBspTreeIndexPrivate*>(d)->purgeRemovedItems();
+ QList<QGraphicsItem *> itemList;
+
+ // If freeItemIndexes is empty, we know there are no holes in indexedItems and
+ // unindexedItems.
+ if (d->freeItemIndexes.isEmpty()) {
+ if (d->unindexedItems.isEmpty()) {
+ itemList = d->indexedItems;
+ } else {
+ itemList = d->indexedItems + d->unindexedItems;
+ }
+ } else {
+ // Rebuild the list of items to avoid holes. ### We could also just
+ // compress the item lists at this point.
+ foreach (QGraphicsItem *item, d->indexedItems + d->unindexedItems) {
+ if (item)
+ itemList << item;
+ }
+ }
+ if (order != -1) {
+ //We sort descending order
+ d->sortItems(&itemList, order, d->sortCacheEnabled);
+ }
+ return itemList;
+}
+
+/*!
+ \property QGraphicsSceneBspTreeIndex::bspTreeDepth
+ \brief the depth of the BSP index tree
+ \since 4.6
+
+ This value determines the depth of BSP tree. The depth
+ directly affects performance and memory usage; the latter
+ growing exponentially with the depth of the tree. With an optimal tree
+ depth, the index can instantly determine the locality of items, even
+ for scenes with thousands or millions of items. This also greatly improves
+ rendering performance.
+
+ By default, the value is 0, in which case Qt will guess a reasonable
+ default depth based on the size, location and number of items in the
+ scene. If these parameters change frequently, however, you may experience
+ slowdowns as the index retunes the depth internally. You can avoid
+ potential slowdowns by fixating the tree depth through setting this
+ property.
+
+ The depth of the tree and the size of the scene rectangle decide the
+ granularity of the scene's partitioning. The size of each scene segment is
+ determined by the following algorithm:
+
+ The BSP tree has an optimal size when each segment contains between 0 and
+ 10 items.
+
+*/
+int QGraphicsSceneBspTreeIndex::bspTreeDepth()
+{
+ Q_D(const QGraphicsSceneBspTreeIndex);
+ return d->bspTreeDepth;
+}
+
+void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth)
+{
+ Q_D(QGraphicsSceneBspTreeIndex);
+ if (d->bspTreeDepth == depth)
+ return;
+ d->bspTreeDepth = depth;
+ d->resetIndex();
+}
+
+/*!
+ \reimp
+
+ This method react to the \a rect change of the scene and
+ reset the BSP tree index.
+*/
+void QGraphicsSceneBspTreeIndex::updateSceneRect(const QRectF &rect)
+{
+ Q_D(QGraphicsSceneBspTreeIndex);
+ d->sceneRect = rect;
+ d->resetIndex();
+}
+
+/*!
+ \reimp
+
+ This method react to the \a change of the \a item and use the \a value to
+ update the BSP tree if necessary.
+
+*/
+void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+ Q_D(QGraphicsSceneBspTreeIndex);
+ switch (change) {
+ case QGraphicsItem::ItemFlagsChange: {
+ // Handle ItemIgnoresTransformations
+ bool ignoredTransform = item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations;
+ bool willIgnoreTransform = value.toUInt() & QGraphicsItem::ItemIgnoresTransformations;
+ bool clipsChildren = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape;
+ bool willClipChildren = value.toUInt() & QGraphicsItem::ItemClipsChildrenToShape;
+ if ((ignoredTransform != willIgnoreTransform) || (clipsChildren != willClipChildren)) {
+ QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item);
+ // Remove item and its descendants from the index and append
+ // them to the list of unindexed items. Then, when the index
+ // is updated, they will be put into the bsp-tree or the list
+ // of untransformable items.
+ d->removeItem(thatItem, /*recursive=*/true, /*moveToUnidexedItems=*/true);
+ }
+ break;
+ }
+ case QGraphicsItem::ItemZValueChange:
+ d->invalidateSortCache();
+ break;
+ case QGraphicsItem::ItemParentChange: {
+ d->invalidateSortCache();
+ // Handle ItemIgnoresTransformations
+ QGraphicsItem *newParent = qVariantValue<QGraphicsItem *>(value);
+ bool ignoredTransform = item->d_ptr->itemIsUntransformable();
+ bool willIgnoreTransform = (item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations)
+ || (newParent && newParent->d_ptr->itemIsUntransformable());
+ bool ancestorClippedChildren = item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren;
+ bool ancestorWillClipChildren = newParent
+ && ((newParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)
+ || (newParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren));
+ if ((ignoredTransform != willIgnoreTransform) || (ancestorClippedChildren != ancestorWillClipChildren)) {
+ QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item);
+ // Remove item and its descendants from the index and append
+ // them to the list of unindexed items. Then, when the index
+ // is updated, they will be put into the bsp-tree or the list
+ // of untransformable items.
+ d->removeItem(thatItem, /*recursive=*/true, /*moveToUnidexedItems=*/true);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return QGraphicsSceneIndex::itemChange(item, change, value);
+}
+/*!
+ \reimp
+
+ Used to catch the timer event.
+
+ \internal
+*/
+bool QGraphicsSceneBspTreeIndex::event(QEvent *event)
+{
+ Q_D(QGraphicsSceneBspTreeIndex);
+ switch (event->type()) {
+ case QEvent::Timer:
+ if (d->indexTimerId && static_cast<QTimerEvent *>(event)->timerId() == d->indexTimerId) {
+ if (d->restartIndexTimer) {
+ d->restartIndexTimer = false;
+ } else {
+ // this call will kill the timer
+ d->_q_updateIndex();
+ }
+ }
+ // Fallthrough intended - support timers in subclasses.
+ default:
+ return QObject::event(event);
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qgraphicsscenebsptreeindex_p.cpp"
+
+#endif // QT_NO_GRAPHICSVIEW
+
diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
new file mode 100644
index 0000000..2e02458
--- /dev/null
+++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the 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 qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QGRAPHICSBSPTREEINDEX_H
+#define QGRAPHICSBSPTREEINDEX_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+#include "qgraphicssceneindex_p.h"
+#include "qgraphicsitem_p.h"
+#include "qgraphicsscene_bsp_p.h"
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qlist.h>
+
+static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000;
+
+class QGraphicsScene;
+class QGraphicsSceneBspTreeIndexPrivate;
+
+class Q_AUTOTEST_EXPORT QGraphicsSceneBspTreeIndex : public QGraphicsSceneIndex
+{
+ Q_OBJECT
+ Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth)
+public:
+ QGraphicsSceneBspTreeIndex(QGraphicsScene *scene = 0);
+ ~QGraphicsSceneBspTreeIndex();
+
+ QList<QGraphicsItem *> estimateItems(const QRectF &rect, Qt::SortOrder order) const;
+ QList<QGraphicsItem *> estimateTopLevelItems(const QRectF &rect, Qt::SortOrder order) const;
+ QList<QGraphicsItem *> items(Qt::SortOrder order = Qt::AscendingOrder) const;
+
+ int bspTreeDepth();
+ void setBspTreeDepth(int depth);
+
+protected Q_SLOTS:
+ void updateSceneRect(const QRectF &rect);
+
+protected:
+ bool event(QEvent *event);
+ void clear();
+
+ void addItem(QGraphicsItem *item);
+ void removeItem(QGraphicsItem *item);
+ void prepareBoundingRectChange(const QGraphicsItem *item);
+
+ void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value);
+
+private :
+ Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex)
+ Q_DISABLE_COPY(QGraphicsSceneBspTreeIndex)
+ Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateIndex())
+
+ friend class QGraphicsScene;
+ friend class QGraphicsScenePrivate;
+};
+
+class QGraphicsSceneBspTreeIndexPrivate : public QGraphicsSceneIndexPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsSceneBspTreeIndex)
+public:
+ QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene);
+
+ QGraphicsSceneBspTree bsp;
+ QRectF sceneRect;
+ int bspTreeDepth;
+ int indexTimerId;
+ bool restartIndexTimer;
+ bool regenerateIndex;
+ int lastItemCount;
+
+ QList<QGraphicsItem *> indexedItems;
+ QList<QGraphicsItem *> unindexedItems;
+ QList<QGraphicsItem *> untransformableItems;
+ QList<int> freeItemIndexes;
+
+ bool purgePending;
+ QSet<QGraphicsItem *> removedItems;
+ void purgeRemovedItems();
+
+ void _q_updateIndex();
+ void startIndexTimer(int interval = QGRAPHICSSCENE_INDEXTIMER_TIMEOUT);
+ void resetIndex();
+
+ void _q_updateSortCache();
+ bool sortCacheEnabled;
+ bool updatingSortCache;
+ void invalidateSortCache();
+ void addItem(QGraphicsItem *item, bool recursive = false);
+ void removeItem(QGraphicsItem *item, bool recursive = false, bool moveToUnindexedItems = false);
+ QList<QGraphicsItem *> estimateItems(const QRectF &, Qt::SortOrder, bool b = false);
+
+ static void climbTree(QGraphicsItem *item, int *stackingOrder);
+ static bool closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2);
+ static bool closestItemLast_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2);
+
+ static inline bool closestItemFirst_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2)
+ {
+ return item1->d_ptr->globalStackingOrder < item2->d_ptr->globalStackingOrder;
+ }
+ static inline bool closestItemLast_withCache(const QGraphicsItem *item1, const QGraphicsItem *item2)
+ {
+ return item1->d_ptr->globalStackingOrder >= item2->d_ptr->globalStackingOrder;
+ }
+
+ static void sortItems(QList<QGraphicsItem *> *itemList, Qt::SortOrder order,
+ bool cached, bool onlyTopLevelItems = false);
+};
+
+static inline bool QRectF_intersects(const QRectF &s, const QRectF &r)
+{
+ qreal xp = s.left();
+ qreal yp = s.top();
+ qreal w = s.width();
+ qreal h = s.height();
+ qreal l1 = xp;
+ qreal r1 = xp;
+ if (w < 0)
+ l1 += w;
+ else
+ r1 += w;
+
+ qreal l2 = r.left();
+ qreal r2 = r.left();
+ if (w < 0)
+ l2 += r.width();
+ else
+ r2 += r.width();
+
+ if (l1 >= r2 || l2 >= r1)
+ return false;
+
+ qreal t1 = yp;
+ qreal b1 = yp;
+ if (h < 0)
+ t1 += h;
+ else
+ b1 += h;
+
+ qreal t2 = r.top();
+ qreal b2 = r.top();
+ if (r.height() < 0)
+ t2 += r.height();
+ else
+ b2 += r.height();
+
+ return !(t1 >= b2 || t2 >= b1);
+}
+
+#endif // QT_NO_GRAPHICSVIEW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGRAPHICSBSPTREEINDEX_H
diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp
new file mode 100644
index 0000000..01efde4
--- /dev/null
+++ b/src/gui/graphicsview/qgraphicssceneindex.cpp
@@ -0,0 +1,659 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the 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 qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+/*!
+ \class QGraphicsSceneIndex
+ \brief The QGraphicsSceneIndex class provides a base class to implement
+ a custom indexing algorithm for discovering items in QGraphicsScene.
+ \since 4.6
+ \ingroup multimedia
+ \ingroup graphicsview-api
+ \mainclass
+ \internal
+
+ The QGraphicsSceneIndex class provides a base class to implement
+ a custom indexing algorithm for discovering items in QGraphicsScene. You
+ need to subclass it and reimplement addItem, removeItem, estimateItems
+ and items in order to have an functional indexing.
+
+ \sa QGraphicsScene, QGraphicsView
+*/
+
+#include "qdebug.h"
+#include "qgraphicsscene.h"
+#include "qgraphicsitem_p.h"
+#include "qgraphicsscene_p.h"
+#include "qgraphicswidget.h"
+#include "qgraphicssceneindex_p.h"
+#include "qgraphicsscenebsptreeindex_p.h"
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+QT_BEGIN_NAMESPACE
+
+class QGraphicsSceneIndexRectIntersector : public QGraphicsSceneIndexIntersector
+{
+public:
+ bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
+ const QTransform &deviceTransform) const
+ {
+ QRectF brect = item->boundingRect();
+ _q_adjustRect(&brect);
+
+ // ### Add test for this (without making things slower?)
+ Q_UNUSED(exposeRect);
+
+ bool keep = true;
+ const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
+ if (itemd->itemIsUntransformable()) {
+ // Untransformable items; map the scene rect to item coordinates.
+ const QTransform transform = item->deviceTransform(deviceTransform);
+ QRectF itemRect = (deviceTransform * transform.inverted()).mapRect(sceneRect);
+ if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
+ keep = itemRect.contains(brect) && itemRect != brect;
+ else
+ keep = itemRect.intersects(brect);
+ if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
+ QPainterPath itemPath;
+ itemPath.addRect(itemRect);
+ keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode);
+ }
+ } else {
+ Q_ASSERT(!itemd->dirtySceneTransform);
+ const QRectF itemSceneBoundingRect = itemd->sceneTransformTranslateOnly
+ ? brect.translated(itemd->sceneTransform.dx(),
+ itemd->sceneTransform.dy())
+ : itemd->sceneTransform.mapRect(brect);
+ if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
+ keep = sceneRect != brect && sceneRect.contains(itemSceneBoundingRect);
+ else
+ keep = sceneRect.intersects(itemSceneBoundingRect);
+ if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
+ QPainterPath rectPath;
+ rectPath.addRect(sceneRect);
+ if (itemd->sceneTransformTranslateOnly)
+ rectPath.translate(-itemd->sceneTransform.dx(), -itemd->sceneTransform.dy());
+ else
+ rectPath = itemd->sceneTransform.inverted().map(rectPath);
+ keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, rectPath, mode);
+ }
+ }
+ return keep;
+ }
+
+ QRectF sceneRect;
+};
+
+class QGraphicsSceneIndexPointIntersector : public QGraphicsSceneIndexIntersector
+{
+public:
+ bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
+ const QTransform &deviceTransform) const
+ {
+ QRectF brect = item->boundingRect();
+ _q_adjustRect(&brect);
+
+ // ### Add test for this (without making things slower?)
+ Q_UNUSED(exposeRect);
+
+ bool keep = false;
+ const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
+ if (itemd->itemIsUntransformable()) {
+ // Untransformable items; map the scene point to item coordinates.
+ const QTransform transform = item->deviceTransform(deviceTransform);
+ QPointF itemPoint = (deviceTransform * transform.inverted()).map(scenePoint);
+ keep = brect.contains(itemPoint);
+ if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
+ QPainterPath pointPath;
+ pointPath.addRect(QRectF(itemPoint, QSizeF(1, 1)));
+ keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode);
+ }
+ } else {
+ Q_ASSERT(!itemd->dirtySceneTransform);
+ QRectF sceneBoundingRect = itemd->sceneTransformTranslateOnly
+ ? brect.translated(itemd->sceneTransform.dx(),
+ itemd->sceneTransform.dy())
+ : itemd->sceneTransform.mapRect(brect);
+ keep = sceneBoundingRect.intersects(QRectF(scenePoint, QSizeF(1, 1)));
+ if (keep) {
+ QPointF p = itemd->sceneTransformTranslateOnly
+ ? QPointF(scenePoint.x() - itemd->sceneTransform.dx(),
+ scenePoint.y() - itemd->sceneTransform.dy())
+ : itemd->sceneTransform.inverted().map(scenePoint);
+ keep = item->contains(p);
+ }
+ }
+
+ return keep;
+ }
+
+ QPointF scenePoint;
+};
+
+class QGraphicsSceneIndexPathIntersector : public QGraphicsSceneIndexIntersector
+{
+public:
+ bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
+ const QTransform &deviceTransform) const
+ {
+ QRectF brect = item->boundingRect();
+ _q_adjustRect(&brect);
+
+ // ### Add test for this (without making things slower?)
+ Q_UNUSED(exposeRect);
+
+ bool keep = true;
+ const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
+ if (itemd->itemIsUntransformable()) {
+ // Untransformable items; map the scene rect to item coordinates.
+ const QTransform transform = item->deviceTransform(deviceTransform);
+ QPainterPath itemPath = (deviceTransform * transform.inverted()).map(scenePath);
+ if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
+ keep = itemPath.contains(brect);
+ else
+ keep = itemPath.intersects(brect);
+ if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape))
+ keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode);
+ } else {
+ Q_ASSERT(!itemd->dirtySceneTransform);
+ const QRectF itemSceneBoundingRect = itemd->sceneTransformTranslateOnly
+ ? brect.translated(itemd->sceneTransform.dx(),
+ itemd->sceneTransform.dy())
+ : itemd->sceneTransform.mapRect(brect);
+ if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
+ keep = scenePath.contains(itemSceneBoundingRect);
+ else
+ keep = scenePath.intersects(itemSceneBoundingRect);
+ if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
+ QPainterPath itemPath = itemd->sceneTransformTranslateOnly
+ ? scenePath.translated(-itemd->sceneTransform.dx(),
+ -itemd->sceneTransform.dy())
+ : itemd->sceneTransform.inverted().map(scenePath);
+ keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode);
+ }
+ }
+ return keep;
+ }
+
+ QPainterPath scenePath;
+};
+
+/*!
+ Constructs a private scene index.
+*/
+QGraphicsSceneIndexPrivate::QGraphicsSceneIndexPrivate(QGraphicsScene *scene) : scene(scene)
+{
+ pointIntersector = new QGraphicsSceneIndexPointIntersector;
+ rectIntersector = new QGraphicsSceneIndexRectIntersector;
+ pathIntersector = new QGraphicsSceneIndexPathIntersector;
+}
+
+/*!
+ Destructor of private scene index.
+*/
+QGraphicsSceneIndexPrivate::~QGraphicsSceneIndexPrivate()
+{
+ delete pointIntersector;
+ delete rectIntersector;
+ delete pathIntersector;
+}
+
+/*!
+ \internal
+
+ Checks if item collides with the path and mode, but also checks that if it
+ doesn't collide, maybe its frame rect will.
+*/
+bool QGraphicsSceneIndexPrivate::itemCollidesWithPath(const QGraphicsItem *item,
+ const QPainterPath &path,
+ Qt::ItemSelectionMode mode)
+{
+ if (item->collidesWithPath(path, mode))
+ return true;
+ if (item->isWidget()) {
+ // Check if this is a window, and if its frame rect collides.
+ const QGraphicsWidget *widget = static_cast<const QGraphicsWidget *>(item);
+ if (widget->isWindow()) {
+ QRectF frameRect = widget->windowFrameRect();
+ QPainterPath framePath;
+ framePath.addRect(frameRect);
+ bool intersects = path.intersects(frameRect);
+ if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
+ return intersects || path.contains(frameRect.topLeft())
+ || framePath.contains(path.elementAt(0));
+ return !intersects && path.contains(frameRect.topLeft());
+ }
+ }
+ return false;
+}
+
+/*!
+ \internal
+*/
+void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRectF exposeRect,
+ QGraphicsSceneIndexIntersector *intersector,
+ QList<QGraphicsItem *> *items,
+ const QTransform &viewTransform,
+ Qt::ItemSelectionMode mode, Qt::SortOrder order,
+ qreal parentOpacity) const
+{
+ Q_ASSERT(item);
+ if (!item->d_ptr->visible)
+ return;
+
+ const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
+ const bool itemIsFullyTransparent = (opacity < 0.0001);
+ const bool itemHasChildren = !item->d_ptr->children.isEmpty();
+ if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity()))
+ return;
+
+ // Update the item's scene transform if dirty.
+ const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
+ const bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform && !itemIsUntransformable;
+ if (wasDirtyParentSceneTransform) {
+ item->d_ptr->updateSceneTransformFromParent();
+ Q_ASSERT(!item->d_ptr->dirtySceneTransform);
+ }
+
+ const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
+ bool processItem = !itemIsFullyTransparent;
+ if (processItem) {
+ processItem = intersector->intersect(item, exposeRect, mode, viewTransform);
+ if (!processItem && (!itemHasChildren || itemClipsChildrenToShape)) {
+ if (wasDirtyParentSceneTransform)
+ item->d_ptr->invalidateChildrenSceneTransform();
+ return;
+ }
+ } // else we know for sure this item has children we must process.
+
+ int i = 0;
+ if (itemHasChildren) {
+ // Sort children.
+ item->d_ptr->ensureSortedChildren();
+
+ // Clip to shape.
+ if (itemClipsChildrenToShape && !itemIsUntransformable) {
+ QPainterPath mappedShape = item->d_ptr->sceneTransformTranslateOnly
+ ? item->shape().translated(item->d_ptr->sceneTransform.dx(),
+ item->d_ptr->sceneTransform.dy())
+ : item->d_ptr->sceneTransform.map(item->shape());
+ exposeRect &= mappedShape.controlPointRect();
+ }
+
+ // Process children behind
+ for (i = 0; i < item->d_ptr->children.size(); ++i) {
+ QGraphicsItem *child = item->d_ptr->children.at(i);
+ if (wasDirtyParentSceneTransform)
+ child->d_ptr->dirtySceneTransform = 1;
+ if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent))
+ break;
+ if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
+ continue;
+ recursive_items_helper(child, exposeRect, intersector, items, viewTransform,
+ mode, order, opacity);
+ }
+ }
+
+ // Process item
+ if (processItem)
+ items->append(item);
+
+ // Process children in front
+ if (itemHasChildren) {
+ for (; i < item->d_ptr->children.size(); ++i) {
+ QGraphicsItem *child = item->d_ptr->children.at(i);
+ if (wasDirtyParentSceneTransform)
+ child->d_ptr->dirtySceneTransform = 1;
+ if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
+ continue;
+ recursive_items_helper(child, exposeRect, intersector, items, viewTransform,
+ mode, order, opacity);
+ }
+ }
+}
+
+void QGraphicsSceneIndexPrivate::init()
+{
+ if (!scene)
+ return;
+
+ QObject::connect(scene, SIGNAL(sceneRectChanged(const QRectF&)),
+ q_func(), SLOT(updateSceneRect(const QRectF&)));
+}
+
+/*!
+ Constructs an abstract scene index for a given \a scene.
+*/
+QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene)
+: QObject(*new QGraphicsSceneIndexPrivate(scene), scene)
+{
+ d_func()->init();
+}
+
+/*!
+ \internal
+*/
+QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene)
+ : QObject(dd, scene)
+{
+ d_func()->init();
+}
+
+/*!
+ Destroys the scene index.
+*/
+QGraphicsSceneIndex::~QGraphicsSceneIndex()
+{
+
+}
+
+/*!
+ Returns the scene of this index.
+*/
+QGraphicsScene* QGraphicsSceneIndex::scene() const
+{
+ Q_D(const QGraphicsSceneIndex);
+ return d->scene;
+}
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPointF &pos,
+ Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform
+ &deviceTransform) const
+
+ Returns all visible items that, depending on \a mode, are at the specified
+ \a pos and return a list sorted using \a order.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with \a pos are returned.
+
+ \a deviceTransform is the transformation apply to the view.
+
+ This method use the estimation of the index (estimateItems) and refine the
+ list to get an exact result. If you want to implement your own refinement
+ algorithm you can reimplement this method.
+
+ \sa estimateItems()
+
+*/
+QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform) const
+{
+
+ Q_D(const QGraphicsSceneIndex);
+ QList<QGraphicsItem *> itemList;
+ d->pointIntersector->scenePoint = pos;
+ d->items_helper(QRectF(pos, QSizeF(1, 1)), d->pointIntersector, &itemList, deviceTransform, mode, order);
+ return itemList;
+}
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QRectF &rect,
+ Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform
+ &deviceTransform) const
+
+ \overload
+
+ Returns all visible items that, depending on \a mode, are either inside or
+ intersect with the specified \a rect and return a list sorted using \a order.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a rect are returned.
+
+ \a deviceTransform is the transformation apply to the view.
+
+ This method use the estimation of the index (estimateItems) and refine
+ the list to get an exact result. If you want to implement your own
+ refinement algorithm you can reimplement this method.
+
+ \sa estimateItems()
+
+*/
+QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform) const
+{
+ Q_D(const QGraphicsSceneIndex);
+ QRectF exposeRect = rect;
+ _q_adjustRect(&exposeRect);
+ QList<QGraphicsItem *> itemList;
+ d->rectIntersector->sceneRect = rect;
+ d->items_helper(exposeRect, d->rectIntersector, &itemList, deviceTransform, mode, order);
+ return itemList;
+}
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPolygonF
+ &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const
+ QTransform &deviceTransform) const
+
+ \overload
+
+ Returns all visible items that, depending on \a mode, are either inside or
+ intersect with the specified \a polygon and return a list sorted using \a order.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a polygon are returned.
+
+ \a deviceTransform is the transformation apply to the view.
+
+ This method use the estimation of the index (estimateItems) and refine
+ the list to get an exact result. If you want to implement your own
+ refinement algorithm you can reimplement this method.
+
+ \sa estimateItems()
+
+*/
+QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform) const
+{
+ Q_D(const QGraphicsSceneIndex);
+ QList<QGraphicsItem *> itemList;
+ QRectF exposeRect = polygon.boundingRect();
+ _q_adjustRect(&exposeRect);
+ QPainterPath path;
+ path.addPolygon(polygon);
+ d->pathIntersector->scenePath = path;
+ d->items_helper(exposeRect, d->pathIntersector, &itemList, deviceTransform, mode, order);
+ return itemList;
+}
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPainterPath
+ &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform
+ &deviceTransform) const
+
+ \overload
+
+ Returns all visible items that, depending on \a mode, are either inside or
+ intersect with the specified \a path and return a list sorted using \a order.
+
+ The default value for \a mode is Qt::IntersectsItemShape; all items whose
+ exact shape intersects with or is contained by \a path are returned.
+
+ \a deviceTransform is the transformation apply to the view.
+
+ This method use the estimation of the index (estimateItems) and refine
+ the list to get an exact result. If you want to implement your own
+ refinement algorithm you can reimplement this method.
+
+ \sa estimateItems()
+
+*/
+QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform) const
+{
+ Q_D(const QGraphicsSceneIndex);
+ QList<QGraphicsItem *> itemList;
+ QRectF exposeRect = path.controlPointRect();
+ _q_adjustRect(&exposeRect);
+ d->pathIntersector->scenePath = path;
+ d->items_helper(exposeRect, d->pathIntersector, &itemList, deviceTransform, mode, order);
+ return itemList;
+}
+
+/*!
+ This virtual function return an estimation of items at position \a point.
+ This method return a list sorted using \a order.
+*/
+QList<QGraphicsItem *> QGraphicsSceneIndex::estimateItems(const QPointF &point, Qt::SortOrder order) const
+{
+ return estimateItems(QRectF(point, QSize(1, 1)), order);
+}
+
+QList<QGraphicsItem *> QGraphicsSceneIndex::estimateTopLevelItems(const QRectF &rect, Qt::SortOrder order) const
+{
+ Q_D(const QGraphicsSceneIndex);
+ Q_UNUSED(rect);
+ QGraphicsScenePrivate *scened = d->scene->d_func();
+ scened->ensureSortedTopLevelItems();
+ if (order == Qt::AscendingOrder) {
+ QList<QGraphicsItem *> sorted;
+ for (int i = scened->topLevelItems.size() - 1; i >= 0; --i)
+ sorted << scened->topLevelItems.at(i);
+ return sorted;
+ }
+ return scened->topLevelItems;
+}
+
+/*!
+ \fn virtual QList<QGraphicsItem *>
+ QGraphicsSceneIndex::estimateItems(const QRectF &rect, Qt::SortOrder
+ order, const QTransform &deviceTransform) const = 0
+
+ This pure virtual function return an estimation of items in the \a rect.
+ This method return a list sorted using \a order.
+
+ \a deviceTransform is the transformation apply to the view.
+*/
+
+/*!
+ \fn virtual QList<QGraphicsItem *>
+ QGraphicsSceneIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const
+ = 0; This pure virtual function all items in the index and sort them using
+ \a order.
+*/
+
+
+/*!
+ Notifies the index that the scene's scene rect has changed. \a rect
+ is thew new scene rect.
+
+ \sa QGraphicsScene::sceneRect()
+*/
+void QGraphicsSceneIndex::updateSceneRect(const QRectF &rect)
+{
+ Q_UNUSED(rect);
+}
+
+/*!
+ This virtual function removes all items in the scene index.
+*/
+void QGraphicsSceneIndex::clear()
+{
+ const QList<QGraphicsItem *> allItems = items();
+ for (int i = 0 ; i < allItems.size(); ++i)
+ removeItem(allItems.at(i));
+}
+
+/*!
+ \fn virtual void QGraphicsSceneIndex::addItem(QGraphicsItem *item) = 0
+
+ This pure virtual function inserts an \a item to the scene index.
+
+ \sa removeItem(), deleteItem()
+*/
+
+/*!
+ \fn virtual void QGraphicsSceneIndex::removeItem(QGraphicsItem *item) = 0
+
+ This pure virtual function removes an \a item to the scene index.
+
+ \sa addItem(), deleteItem()
+*/
+
+/*!
+ This method is called when an \a item has been deleted.
+ The default implementation call removeItem. Be carefull,
+ if your implementation of removeItem use pure virtual method
+ of QGraphicsItem like boundingRect(), then you should reimplement
+ this method.
+
+ \sa addItem(), removeItem()
+*/
+void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item)
+{
+ removeItem(item);
+}
+
+/*!
+ This virtual function is called by QGraphicsItem to notify the index
+ that some part of the \a item 's state changes. By reimplementing this
+ function, your can react to a change, and in some cases, (depending on \a
+ change,) adjustments in the index can be made.
+
+ \a change is the parameter of the item that is changing. \a value is the
+ value that changed; the type of the value depends on \a change.
+
+ The default implementation does nothing.
+
+ \sa QGraphicsItem::GraphicsItemChange
+*/
+void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value)
+{
+ Q_UNUSED(item);
+ Q_UNUSED(change);
+ Q_UNUSED(value);
+}
+
+/*!
+ Notify the index for a geometry change of an \a item.
+
+ \sa QGraphicsItem::prepareGeometryChange()
+*/
+void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item)
+{
+ Q_UNUSED(item);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qgraphicssceneindex_p.cpp"
+
+#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h
new file mode 100644
index 0000000..8cf0294
--- /dev/null
+++ b/src/gui/graphicsview/qgraphicssceneindex_p.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the 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 qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSSCENEINDEX_H
+#define QGRAPHICSSCENEINDEX_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qgraphicsscene_p.h"
+#include "qgraphicsscene.h"
+#include <private/qobject_p.h>
+
+#include <QtCore/qnamespace.h>
+#include <QtCore/qobject.h>
+#include <QtGui/qtransform.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+class QGraphicsSceneIndexIntersector;
+class QGraphicsSceneIndexPointIntersector;
+class QGraphicsSceneIndexRectIntersector;
+class QGraphicsSceneIndexPathIntersector;
+class QGraphicsSceneIndexPrivate;
+class QPointF;
+class QRectF;
+template<typename T> class QList;
+
+class Q_AUTOTEST_EXPORT QGraphicsSceneIndex : public QObject
+{
+ Q_OBJECT
+
+public:
+ QGraphicsSceneIndex(QGraphicsScene *scene = 0);
+ virtual ~QGraphicsSceneIndex();
+
+ QGraphicsScene *scene() const;
+
+ virtual QList<QGraphicsItem *> items(Qt::SortOrder order = Qt::AscendingOrder) const = 0;
+ virtual QList<QGraphicsItem *> items(const QPointF &pos, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
+ virtual QList<QGraphicsItem *> items(const QRectF &rect, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
+ virtual QList<QGraphicsItem *> items(const QPolygonF &polygon, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
+ virtual QList<QGraphicsItem *> items(const QPainterPath &path, Qt::ItemSelectionMode mode,
+ Qt::SortOrder order, const QTransform &deviceTransform = QTransform()) const;
+ virtual QList<QGraphicsItem *> estimateItems(const QPointF &point, Qt::SortOrder order) const;
+ virtual QList<QGraphicsItem *> estimateItems(const QRectF &rect, Qt::SortOrder order) const = 0;
+ virtual QList<QGraphicsItem *> estimateTopLevelItems(const QRectF &, Qt::SortOrder order) const;
+
+protected Q_SLOTS:
+ virtual void updateSceneRect(const QRectF &rect);
+
+protected:
+ virtual void clear();
+ virtual void addItem(QGraphicsItem *item) = 0;
+ virtual void removeItem(QGraphicsItem *item) = 0;
+ virtual void deleteItem(QGraphicsItem *item);
+
+ virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value);
+ virtual void prepareBoundingRectChange(const QGraphicsItem *item);
+
+ QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene);
+
+ friend class QGraphicsScene;
+ friend class QGraphicsScenePrivate;
+ friend class QGraphicsItem;
+ friend class QGraphicsItemPrivate;
+ friend class QGraphicsSceneBspTreeIndex;
+private:
+ Q_DISABLE_COPY(QGraphicsSceneIndex)
+ Q_DECLARE_PRIVATE(QGraphicsSceneIndex)
+};
+
+class QGraphicsSceneIndexPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsSceneIndex)
+public:
+ QGraphicsSceneIndexPrivate(QGraphicsScene *scene);
+ ~QGraphicsSceneIndexPrivate();
+
+ void init();
+ static bool itemCollidesWithPath(const QGraphicsItem *item, const QPainterPath &path, Qt::ItemSelectionMode mode);
+
+ void recursive_items_helper(QGraphicsItem *item, QRectF exposeRect,
+ QGraphicsSceneIndexIntersector *intersector, QList<QGraphicsItem *> *items,
+ const QTransform &viewTransform,
+ Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const;
+ inline void items_helper(const QRectF &rect, QGraphicsSceneIndexIntersector *intersector,
+ QList<QGraphicsItem *> *items, const QTransform &viewTransform,
+ Qt::ItemSelectionMode mode, Qt::SortOrder order) const;
+
+ QGraphicsScene *scene;
+ QGraphicsSceneIndexPointIntersector *pointIntersector;
+ QGraphicsSceneIndexRectIntersector *rectIntersector;
+ QGraphicsSceneIndexPathIntersector *pathIntersector;
+};
+
+inline void QGraphicsSceneIndexPrivate::items_helper(const QRectF &rect, QGraphicsSceneIndexIntersector *intersector,
+ QList<QGraphicsItem *> *items, const QTransform &viewTransform,
+ Qt::ItemSelectionMode mode, Qt::SortOrder order) const
+{
+ Q_Q(const QGraphicsSceneIndex);
+ const QList<QGraphicsItem *> tli = q->estimateTopLevelItems(rect, Qt::DescendingOrder);
+ for (int i = 0; i < tli.size(); ++i)
+ recursive_items_helper(tli.at(i), rect, intersector, items, viewTransform, mode, order);
+ if (order == Qt::AscendingOrder) {
+ const int n = items->size();
+ for (int i = 0; i < n / 2; ++i)
+ items->swap(i, n - i - 1);
+ }
+}
+
+class QGraphicsSceneIndexIntersector
+{
+public:
+ QGraphicsSceneIndexIntersector() { }
+ virtual ~QGraphicsSceneIndexIntersector() { }
+ virtual bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
+ const QTransform &deviceTransform) const = 0;
+};
+
+#endif // QT_NO_GRAPHICSVIEW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGRAPHICSSCENEINDEX_H
diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex.cpp b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp
new file mode 100644
index 0000000..5e6ac30
--- /dev/null
+++ b/src/gui/graphicsview/qgraphicsscenelinearindex.cpp
@@ -0,0 +1,62 @@
+/*!
+ \class QGraphicsSceneLinearIndex
+ \brief The QGraphicsSceneLinearIndex class provides an implementation of
+ a linear indexing algorithm for discovering items in QGraphicsScene.
+ \since 4.6
+ \ingroup multimedia
+ \ingroup graphicsview-api
+ \mainclass
+ \internal
+
+ QGraphicsSceneLinearIndex index is default linear implementation to discover items.
+ It basically store all items in a list and return them to the scene.
+
+ \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex, QGraphicsSceneBspTreeIndex
+*/
+
+#include <private/qgraphicsscenelinearindex_p.h>
+
+/*!
+ \fn QGraphicsSceneLinearIndex::QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0):
+
+ Construct a linear index for the given \a scene.
+*/
+
+/*!
+ \fn QList<QGraphicsItem *> QGraphicsSceneLinearIndex::items(Qt::SortOrder order = Qt::AscendingOrder) const;
+
+ Return all items in the index and sort them using \a order.
+*/
+
+
+/*!
+ \fn virtual QList<QGraphicsItem *> QGraphicsSceneLinearIndex::estimateItems(const QRectF &rect, Qt::SortOrder order) const;
+
+ Returns an estimation visible items that are either inside or
+ intersect with the specified \a rect and return a list sorted using \a order.
+*/
+
+/*!
+ \fn QRectF QGraphicsSceneLinearIndex::indexedRect() const;
+ \reimp
+ Return the rect indexed by the the index.
+*/
+
+/*!
+ \fn void QGraphicsSceneLinearIndex::clear();
+ \reimp
+ Clear the all the BSP index.
+*/
+
+/*!
+ \fn virtual void QGraphicsSceneLinearIndex::addItem(QGraphicsItem *item);
+
+ Add the \a item into the index.
+*/
+
+/*!
+ \fn virtual void QGraphicsSceneLinearIndex::removeItem(QGraphicsItem *item);
+
+ Add the \a item from the index.
+*/
+
diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h
new file mode 100644
index 0000000..56dde3a
--- /dev/null
+++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the 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 qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSSCENELINEARINDEX_H
+#define QGRAPHICSSCENELINEARINDEX_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qlist.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+#include <QtCore/qrect.h>
+#include <QtCore/qlist.h>
+#include <QtGui/qgraphicsitem.h>
+#include <private/qgraphicssceneindex_p.h>
+
+class Q_AUTOTEST_EXPORT QGraphicsSceneLinearIndex : public QGraphicsSceneIndex
+{
+ Q_OBJECT
+
+public:
+ QGraphicsSceneLinearIndex(QGraphicsScene *scene = 0) : QGraphicsSceneIndex(scene)
+ { }
+
+ QList<QGraphicsItem *> items(Qt::SortOrder order = Qt::AscendingOrder) const
+ { Q_UNUSED(order); return m_items; }
+
+ virtual QList<QGraphicsItem *> estimateItems(const QRectF &rect, Qt::SortOrder order) const
+ {
+ Q_UNUSED(rect);
+ Q_UNUSED(order);
+ return m_items;
+ }
+
+protected :
+ virtual void clear()
+ { m_items.clear(); }
+
+ virtual void addItem(QGraphicsItem *item)
+ { m_items << item; }
+
+ virtual void removeItem(QGraphicsItem *item)
+ { m_items.removeOne(item); }
+
+private:
+ QList<QGraphicsItem*> m_items;
+};
+
+#endif // QT_NO_GRAPHICSVIEW
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QGRAPHICSSCENELINEARINDEX_H
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 3b29552..bcfd68c 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -813,19 +813,9 @@ QRegion QGraphicsViewPrivate::mapToViewRegion(const QGraphicsItem *item, const Q
return item->boundingRegion(itv) & itv.mapRect(rect).toAlignedRect();
}
-// QRectF::intersects() returns false always if either the source or target
-// rectangle's width or height are 0. This works around that problem.
-static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
-{
- Q_ASSERT(item);
- QRectF boundingRect(item->boundingRect());
- if (!boundingRect.width())
- boundingRect.adjust(-0.00001, 0, 0.00001, 0);
- if (!boundingRect.height())
- boundingRect.adjust(0, -0.00001, 0, 0.00001);
- return boundingRect;
-}
-
+/*!
+ \internal
+*/
void QGraphicsViewPrivate::processPendingUpdates()
{
if (!scene)
@@ -850,13 +840,29 @@ void QGraphicsViewPrivate::processPendingUpdates()
dirtyRegion = QRegion();
}
+static inline bool intersectsViewport(const QRect &r, int width, int height)
+{ return !(r.left() > width) && !(r.right() < 0) && !(r.top() >= height) && !(r.bottom() < 0); }
+
+static inline bool containsViewport(const QRect &r, int width, int height)
+{ return r.left() <= 0 && r.top() <= 0 && r.right() >= width - 1 && r.bottom() >= height - 1; }
+
+static inline void QRect_unite(QRect *rect, const QRect &other)
+{
+ if (rect->isEmpty()) {
+ *rect = other;
+ } else {
+ rect->setCoords(qMin(rect->left(), other.left()), qMin(rect->top(), other.top()),
+ qMax(rect->right(), other.right()), qMax(rect->bottom(), other.bottom()));
+ }
+}
+
bool QGraphicsViewPrivate::updateRegion(const QRegion &r)
{
if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate || r.isEmpty())
return false;
const QRect boundingRect = r.boundingRect();
- if (!boundingRect.intersects(viewport->rect()))
+ if (!intersectsViewport(boundingRect, viewport->width(), viewport->height()))
return false; // Update region outside viewport.
switch (viewportUpdateMode) {
@@ -865,8 +871,8 @@ bool QGraphicsViewPrivate::updateRegion(const QRegion &r)
viewport->update();
break;
case QGraphicsView::BoundingRectViewportUpdate:
- dirtyBoundingRect |= boundingRect;
- if (dirtyBoundingRect.contains(viewport->rect())) {
+ QRect_unite(&dirtyBoundingRect, boundingRect);
+ if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) {
fullUpdatePending = true;
viewport->update();
}
@@ -893,7 +899,7 @@ bool QGraphicsViewPrivate::updateRegion(const QRegion &r)
bool QGraphicsViewPrivate::updateRect(const QRect &r)
{
if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate
- || !r.intersects(viewport->rect())) {
+ || !intersectsViewport(r, viewport->width(), viewport->height())) {
return false;
}
@@ -903,8 +909,8 @@ bool QGraphicsViewPrivate::updateRect(const QRect &r)
viewport->update();
break;
case QGraphicsView::BoundingRectViewportUpdate:
- dirtyBoundingRect |= r;
- if (dirtyBoundingRect.contains(viewport->rect())) {
+ QRect_unite(&dirtyBoundingRect, r);
+ if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) {
fullUpdatePending = true;
viewport->update();
}
@@ -955,47 +961,32 @@ extern QPainterPath qt_regionToPath(const QRegion &region);
is at risk of painting 1 pixel outside the bounding rect. Therefore we
must search for items with an adjustment of (-1, -1, 1, 1).
*/
-QList<QGraphicsItem *> QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, bool *allItems) const
+QList<QGraphicsItem *> QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, bool *allItems,
+ const QTransform &viewTransform) const
{
Q_Q(const QGraphicsView);
// Step 1) If all items are contained within the expose region, then
- // return a list of all visible items.
+ // return a list of all visible items. ### the scene's growing bounding
+ // rect does not take into account untransformable items.
const QRectF exposedRegionSceneBounds = q->mapToScene(exposedRegion.boundingRect().adjusted(-1, -1, 1, 1))
.boundingRect();
- if (exposedRegionSceneBounds.contains(scene->d_func()->growingItemsBoundingRect)) {
+ if (exposedRegionSceneBounds.contains(scene->sceneRect())) {
Q_ASSERT(allItems);
*allItems = true;
- // All items are guaranteed within the exposed region, don't bother using the index.
- QList<QGraphicsItem *> itemList(scene->items());
- int i = 0;
- while (i < itemList.size()) {
- const QGraphicsItem *item = itemList.at(i);
- // But we only want to include items that are visible
- // The following check is basically the same as item->d_ptr->isInvisible(), except
- // that we don't check whether the item clips children to shape or propagates its
- // opacity (we loop through all items, so those checks are wrong in this context).
- if (!item->isVisible() || item->d_ptr->isClippedAway() || item->d_ptr->isFullyTransparent())
- itemList.removeAt(i);
- else
- ++i;
- }
-
- // Sort the items.
- QGraphicsScenePrivate::sortItems(&itemList, Qt::DescendingOrder, scene->d_func()->sortCacheEnabled);
- return itemList;
+ // All items are guaranteed within the exposed region.
+ return scene->items(Qt::DescendingOrder);
}
// Step 2) If the expose region is a simple rect and the view is only
// translated or scaled, search for items using
// QGraphicsScene::items(QRectF).
- bool simpleRectLookup = (scene->d_func()->largestUntransformableItem.isNull()
- && exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale);
+ bool simpleRectLookup = exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale;
if (simpleRectLookup) {
- return scene->d_func()->items_helper(exposedRegionSceneBounds,
- Qt::IntersectsItemBoundingRect,
- Qt::DescendingOrder);
+ return scene->items(exposedRegionSceneBounds,
+ Qt::IntersectsItemBoundingRect,
+ Qt::DescendingOrder, viewTransform);
}
// If the region is complex or the view has a complex transform, adjust
@@ -1005,16 +996,9 @@ QList<QGraphicsItem *> QGraphicsViewPrivate::findItems(const QRegion &exposedReg
foreach (const QRect &r, exposedRegion.rects())
adjustedRegion += r.adjusted(-1, -1, 1, 1);
- const QPainterPath exposedPath(qt_regionToPath(adjustedRegion));
- if (scene->d_func()->largestUntransformableItem.isNull()) {
- const QPainterPath exposedScenePath(q->mapToScene(exposedPath));
- return scene->d_func()->items_helper(exposedScenePath,
- Qt::IntersectsItemBoundingRect,
- Qt::DescendingOrder);
- }
-
- // NB! Path must be in viewport coordinates.
- return itemsInArea(exposedPath, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder);
+ const QPainterPath exposedScenePath(q->mapToScene(qt_regionToPath(adjustedRegion)));
+ return scene->items(exposedScenePath, Qt::IntersectsItemBoundingRect,
+ Qt::DescendingOrder, viewTransform);
}
/*!
@@ -1915,7 +1899,12 @@ void QGraphicsView::fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRati
void QGraphicsView::fitInView(const QGraphicsItem *item, Qt::AspectRatioMode aspectRatioMode)
{
QPainterPath path = item->isClipped() ? item->clipPath() : item->shape();
- fitInView(item->sceneTransform().map(path).boundingRect(), aspectRatioMode);
+ if (item->d_ptr->hasTranslateOnlySceneTransform()) {
+ path.translate(item->d_ptr->sceneTransform.dx(), item->d_ptr->sceneTransform.dy());
+ fitInView(path.boundingRect(), aspectRatioMode);
+ } else {
+ fitInView(item->d_ptr->sceneTransform.map(path).boundingRect(), aspectRatioMode);
+ }
}
/*!
@@ -1941,6 +1930,8 @@ void QGraphicsView::fitInView(const QGraphicsItem *item, Qt::AspectRatioMode asp
void QGraphicsView::render(QPainter *painter, const QRectF &target, const QRect &source,
Qt::AspectRatioMode aspectRatioMode)
{
+ // ### Switch to using the recursive rendering algorithm instead.
+
Q_D(QGraphicsView);
if (!d->scene || !(painter && painter->isActive()))
return;
@@ -2037,69 +2028,6 @@ QList<QGraphicsItem *> QGraphicsView::items() const
}
/*!
- Returns all items in the area \a path, which is in viewport coordinates,
- also taking untransformable items into consideration. This function is
- considerably slower than just checking the scene directly. There is
- certainly room for improvement.
-*/
-QList<QGraphicsItem *> QGraphicsViewPrivate::itemsInArea(const QPainterPath &path,
- Qt::ItemSelectionMode mode,
- Qt::SortOrder order) const
-{
- Q_Q(const QGraphicsView);
-
- // Determine the size of the largest untransformable subtree of children
- // mapped to scene coordinates.
- QRectF untr = scene->d_func()->largestUntransformableItem;
- QRectF ltri = matrix.inverted().mapRect(untr);
- ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height());
-
- QRectF rect = path.controlPointRect();
-
- // Find all possible items in the relevant area.
- // ### Improve this algorithm; it might be searching a too large area.
- QRectF adjustedRect = q->mapToScene(rect.adjusted(-1, -1, 1, 1).toRect()).boundingRect();
- adjustedRect.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height());
-
- // First build a (potentially large) list of all items in the vicinity
- // that might be untransformable.
- QList<QGraphicsItem *> allCandidates = scene->d_func()->estimateItemsInRect(adjustedRect);
-
- // Then find the minimal list of items that are inside \a path, and
- // convert it to a set.
- QList<QGraphicsItem *> regularCandidates = scene->items(q->mapToScene(path), mode);
- QSet<QGraphicsItem *> candSet = QSet<QGraphicsItem *>::fromList(regularCandidates);
-
- QTransform viewMatrix = q->viewportTransform();
-
- QList<QGraphicsItem *> result;
-
- // Run through all candidates and keep all items that are in candSet, or
- // are untransformable and collide with \a path. ### We can improve this
- // algorithm.
- QList<QGraphicsItem *>::Iterator it = allCandidates.begin();
- while (it != allCandidates.end()) {
- QGraphicsItem *item = *it;
- if (item->d_ptr->itemIsUntransformable()) {
- // Check if this untransformable item collides with the
- // original selection rect.
- QTransform itemTransform = item->deviceTransform(viewMatrix);
- if (QGraphicsScenePrivate::itemCollidesWithPath(item, itemTransform.inverted().map(path), mode))
- result << item;
- } else {
- if (candSet.contains(item))
- result << item;
- }
- ++it;
- }
-
- // ### Insertion sort would be faster.
- if (order != Qt::SortOrder(-1))
- QGraphicsScenePrivate::sortItems(&result, order, scene->d_func()->sortCacheEnabled);
- return result;
-}
-
-/*!
Returns a list of all the items at the position \a pos in the view. The
items are listed in descending Z order (i.e., the first item in the list
is the top-most item, and the last item is the bottom-most item). \a pos
@@ -2118,17 +2046,22 @@ QList<QGraphicsItem *> QGraphicsView::items(const QPoint &pos) const
Q_D(const QGraphicsView);
if (!d->scene)
return QList<QGraphicsItem *>();
- if (d->scene->d_func()->largestUntransformableItem.isNull()) {
- if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) {
- QTransform xinv = viewportTransform().inverted();
- return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1)));
- }
- return d->scene->items(mapToScene(pos.x(), pos.y(), 1, 1));
+ // ### Unify these two, and use the items(QPointF) version in
+ // QGraphicsScene instead. The scene items function could use the viewport
+ // transform to map the point to a rect/polygon.
+ if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) {
+ // Use the rect version
+ QTransform xinv = viewportTransform().inverted();
+ return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1)),
+ Qt::IntersectsItemShape,
+ Qt::AscendingOrder,
+ viewportTransform());
}
-
- QPainterPath path;
- path.addRect(QRectF(pos.x(), pos.y(), 1, 1));
- return d->itemsInArea(path);
+ // Use the polygon version
+ return d->scene->items(mapToScene(pos.x(), pos.y(), 1, 1),
+ Qt::IntersectsItemShape,
+ Qt::AscendingOrder,
+ viewportTransform());
}
/*!
@@ -2155,12 +2088,7 @@ QList<QGraphicsItem *> QGraphicsView::items(const QRect &rect, Qt::ItemSelection
Q_D(const QGraphicsView);
if (!d->scene)
return QList<QGraphicsItem *>();
- if (d->scene->d_func()->largestUntransformableItem.isNull())
- return d->scene->items(mapToScene(rect), mode);
-
- QPainterPath path;
- path.addRect(rect);
- return d->itemsInArea(path);
+ return d->scene->items(mapToScene(rect), mode, Qt::AscendingOrder, viewportTransform());
}
/*!
@@ -2188,13 +2116,7 @@ QList<QGraphicsItem *> QGraphicsView::items(const QPolygon &polygon, Qt::ItemSel
Q_D(const QGraphicsView);
if (!d->scene)
return QList<QGraphicsItem *>();
- if (d->scene->d_func()->largestUntransformableItem.isNull())
- return d->scene->items(mapToScene(polygon), mode);
-
- QPainterPath path;
- path.addPolygon(polygon);
- path.closeSubpath();
- return d->itemsInArea(path);
+ return d->scene->items(mapToScene(polygon), mode, Qt::AscendingOrder, viewportTransform());
}
/*!
@@ -2214,9 +2136,7 @@ QList<QGraphicsItem *> QGraphicsView::items(const QPainterPath &path, Qt::ItemSe
Q_D(const QGraphicsView);
if (!d->scene)
return QList<QGraphicsItem *>();
- if (d->scene->d_func()->largestUntransformableItem.isNull())
- return d->scene->items(mapToScene(path), mode);
- return d->itemsInArea(path);
+ return d->scene->items(mapToScene(path), mode, Qt::AscendingOrder, viewportTransform());
}
/*!
@@ -3169,7 +3089,8 @@ void QGraphicsView::mouseMoveEvent(QMouseEvent *event)
selectionArea.addPolygon(mapToScene(d->rubberBandRect));
selectionArea.closeSubpath();
if (d->scene)
- d->scene->setSelectionArea(selectionArea, d->rubberBandSelectionMode);
+ d->scene->setSelectionArea(selectionArea, d->rubberBandSelectionMode,
+ viewportTransform());
return;
}
} else
@@ -3382,8 +3303,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
} else {
// Find all exposed items
bool allItems = false;
- QList<QGraphicsItem *> itemList = d->findItems(d->exposedRegion, &allItems);
-
+ QList<QGraphicsItem *> itemList = d->findItems(d->exposedRegion, &allItems, viewTransform);
if (!itemList.isEmpty()) {
// Generate the style options.
const int numItems = itemList.size();
diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h
index 09d842d..0fa8b34 100644
--- a/src/gui/graphicsview/qgraphicsview_p.h
+++ b/src/gui/graphicsview/qgraphicsview_p.h
@@ -59,11 +59,12 @@
#include <QtGui/qevent.h>
#include "qgraphicssceneevent.h"
+#include <QtGui/qstyleoption.h>
#include <private/qabstractscrollarea_p.h>
QT_BEGIN_NAMESPACE
-class QGraphicsViewPrivate : public QAbstractScrollAreaPrivate
+class Q_AUTOTEST_EXPORT QGraphicsViewPrivate : public QAbstractScrollAreaPrivate
{
Q_DECLARE_PUBLIC(QGraphicsView)
public:
@@ -84,10 +85,6 @@ public:
qint64 horizontalScroll() const;
qint64 verticalScroll() const;
- QList<QGraphicsItem *> itemsInArea(const QPainterPath &path,
- Qt::ItemSelectionMode mode = Qt::IntersectsItemShape,
- Qt::SortOrder = Qt::AscendingOrder) const;
-
QPointF mousePressItemPoint;
QPointF mousePressScenePoint;
QPoint mousePressViewPoint;
@@ -176,7 +173,8 @@ public:
bool updateSceneSlotReimplementedChecked;
QRegion exposedRegion;
- QList<QGraphicsItem *> findItems(const QRegion &exposedRegion, bool *allItems) const;
+ QList<QGraphicsItem *> findItems(const QRegion &exposedRegion, bool *allItems,
+ const QTransform &viewTransform) const;
QPointF mapToScene(const QPointF &point) const;
QRectF mapToScene(const QRectF &rect) const;
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index dd84304..a4a69c3 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -3881,30 +3881,48 @@ bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *even
return true;
}
-QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QRect *r) const
+/*
+ \internal
+
+ returns the pair QRect/QModelIndex that should be painted on the viewports's rect
+ */
+
+QItemViewPaintPairs QAbstractItemViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
{
+ Q_ASSERT(r);
Q_Q(const QAbstractItemView);
- QRect rect = q->visualRect(indexes.at(0));
- QList<QRect> rects;
+ QRect &rect = *r;
+ const QRect viewportRect = viewport->rect();
+ QItemViewPaintPairs ret;
for (int i = 0; i < indexes.count(); ++i) {
- rects.append(q->visualRect(indexes.at(i)));
- rect |= rects.at(i);
+ const QModelIndex &index = indexes.at(i);
+ const QRect current = q->visualRect(index);
+ if (current.intersects(viewportRect)) {
+ ret += qMakePair(current, index);
+ rect |= current;
+ }
}
- rect = rect.intersected(viewport->rect());
- if (rect.width() <= 0 || rect.height() <= 0)
+ rect &= viewportRect;
+ return ret;
+}
+
+QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QRect *r) const
+{
+ Q_ASSERT(r);
+ QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r);
+ if (paintPairs.isEmpty())
return QPixmap();
- QImage image(rect.size(), QImage::Format_ARGB32_Premultiplied);
- image.fill(0);
- QPainter painter(&image);
+ QPixmap pixmap(r->size());
+ pixmap.fill(Qt::transparent);
+ QPainter painter(&pixmap);
QStyleOptionViewItemV4 option = viewOptionsV4();
option.state |= QStyle::State_Selected;
- for (int j = 0; j < indexes.count(); ++j) {
- option.rect = QRect(rects.at(j).topLeft() - rect.topLeft(), rects.at(j).size());
- delegateForIndex(indexes.at(j))->paint(&painter, option, indexes.at(j));
+ for (int j = 0; j < paintPairs.count(); ++j) {
+ option.rect = paintPairs.at(j).first.translated(r->topLeft());
+ const QModelIndex &current = paintPairs.at(j).second;
+ delegateForIndex(current)->paint(&painter, option, current);
}
- painter.end();
- if (r) *r = rect;
- return QPixmap::fromImage(image);
+ return pixmap;
}
void QAbstractItemViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command)
diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h
index 2950bcd..557e98b 100644
--- a/src/gui/itemviews/qabstractitemview_p.h
+++ b/src/gui/itemviews/qabstractitemview_p.h
@@ -61,11 +61,10 @@
#include "QtGui/qmime.h"
#include "QtGui/qpainter.h"
#include "QtCore/qpair.h"
-#include "QtCore/qtimer.h"
-#include "QtCore/qtimeline.h"
#include "QtGui/qregion.h"
#include "QtCore/qdebug.h"
#include "QtGui/qpainter.h"
+#include "QtCore/qbasictimer.h"
#ifndef QT_NO_ITEMVIEWS
@@ -87,6 +86,9 @@ struct QEditorInfo
};
+typedef QPair<QRect, QModelIndex> QItemViewPaintPair;
+typedef QList<QItemViewPaintPair> QItemViewPaintPairs;
+
class QEmptyModel : public QAbstractItemModel
{
public:
@@ -177,7 +179,9 @@ public:
q_func()->style()->drawPrimitive(QStyle::PE_IndicatorItemViewItemDrop, &opt, painter, q_func());
}
}
+
#endif
+ virtual QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
inline void releaseEditor(QWidget *editor) const {
if (editor) {
@@ -222,7 +226,7 @@ public:
void clearOrRemove();
void checkPersistentEditorFocus();
- QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r = 0) const;
+ QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r) const;
inline QPoint offset() const {
const Q_Q(QAbstractItemView);
@@ -376,7 +380,6 @@ public:
QBasicTimer updateTimer;
QBasicTimer delayedEditing;
QBasicTimer delayedAutoScroll; //used when an item is clicked
- QTimeLine timeline;
QAbstractItemView::ScrollMode verticalScrollMode;
QAbstractItemView::ScrollMode horizontalScrollMode;
diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp
index e4cb0f0..87825d9 100644
--- a/src/gui/itemviews/qitemselectionmodel.cpp
+++ b/src/gui/itemviews/qitemselectionmodel.cpp
@@ -270,24 +270,35 @@ QItemSelectionRange QItemSelectionRange::intersect(const QItemSelectionRange &ot
*/
-/*!
- Returns the list of model index items stored in the selection.
-*/
+/*
+ \internal
-QModelIndexList QItemSelectionRange::indexes() const
+ utility function for getting the indexes from a range
+ it avoid concatenating list and works on one
+ */
+
+static void indexesFromRange(const QItemSelectionRange &range, QModelIndexList &result)
{
- QModelIndex index;
- QModelIndexList result;
- if (isValid() && model()) {
- for (int column = left(); column <= right(); ++column) {
- for (int row = top(); row <= bottom(); ++row) {
- index = model()->index(row, column, parent());
- Qt::ItemFlags flags = model()->flags(index);
+ if (range.isValid() && range.model()) {
+ for (int column = range.left(); column <= range.right(); ++column) {
+ for (int row = range.top(); row <= range.bottom(); ++row) {
+ QModelIndex index = range.model()->index(row, column, range.parent());
+ Qt::ItemFlags flags = range.model()->flags(index);
if ((flags & Qt::ItemIsSelectable) && (flags & Qt::ItemIsEnabled))
result.append(index);
}
}
}
+}
+
+/*!
+ Returns the list of model index items stored in the selection.
+*/
+
+QModelIndexList QItemSelectionRange::indexes() const
+{
+ QModelIndexList result;
+ indexesFromRange(*this, result);
return result;
}
@@ -404,7 +415,7 @@ QModelIndexList QItemSelection::indexes() const
QModelIndexList result;
QList<QItemSelectionRange>::const_iterator it = begin();
for (; it != end(); ++it)
- result += (*it).indexes();
+ indexesFromRange(*it, result);
return result;
}
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
index 4652b91..9a94b31 100644
--- a/src/gui/itemviews/qlistview.cpp
+++ b/src/gui/itemviews/qlistview.cpp
@@ -709,6 +709,32 @@ void QListViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command)
selectionModel->select(selection, command);
}
+/*!
+ \reimp
+
+ We have a QListView way of knowing what elements are on the viewport
+ through the intersectingSet function
+*/
+QItemViewPaintPairs QListViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const
+{
+ Q_ASSERT(r);
+ Q_Q(const QListView);
+ QRect &rect = *r;
+ const QRect viewportRect = viewport->rect();
+ QItemViewPaintPairs ret;
+ intersectingSet(viewportRect);
+ const QSet<QModelIndex> visibleIndexes = intersectingSet(viewportRect).toList().toSet();
+ for (int i = 0; i < indexes.count(); ++i) {
+ const QModelIndex &index = indexes.at(i);
+ if (visibleIndexes.contains(index)) {
+ const QRect current = q->visualRect(index);
+ ret += qMakePair(current, index);
+ rect |= current;
+ }
+ }
+ rect &= viewportRect;
+ return ret;
+}
/*!
\internal
@@ -925,9 +951,9 @@ void QListView::dragMoveEvent(QDragMoveEvent *e)
QModelIndex index;
if (d->movement == Snap) {
QRect rect(d->dynamicListView->snapToGrid(e->pos() + d->offset()), d->gridSize());
- d->intersectingSet(rect);
- index = d->intersectVector.count() > 0
- ? d->intersectVector.last() : QModelIndex();
+ const QVector<QModelIndex> intersectVector = d->intersectingSet(rect);
+ index = intersectVector.count() > 0
+ ? intersectVector.last() : QModelIndex();
} else {
index = indexAt(e->pos());
}
@@ -1100,10 +1126,8 @@ void QListView::paintEvent(QPaintEvent *e)
return;
QStyleOptionViewItemV4 option = d->viewOptionsV4();
QPainter painter(d->viewport);
- QRect area = e->rect();
- d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false);
- const QVector<QModelIndex> toBeRendered = d->intersectVector;
+ const QVector<QModelIndex> toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false);
const QModelIndex current = currentIndex();
const QModelIndex hover = d->hover;
@@ -1225,9 +1249,9 @@ QModelIndex QListView::indexAt(const QPoint &p) const
{
Q_D(const QListView);
QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
- d->intersectingSet(rect);
- QModelIndex index = d->intersectVector.count() > 0
- ? d->intersectVector.last() : QModelIndex();
+ const QVector<QModelIndex> intersectVector = d->intersectingSet(rect);
+ QModelIndex index = intersectVector.count() > 0
+ ? intersectVector.last() : QModelIndex();
if (index.isValid() && visualRect(index).contains(p))
return index;
return QModelIndex();
@@ -1325,38 +1349,38 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
if (d->gridSize().isValid()) rect.setSize(d->gridSize());
QSize contents = d->contentsSize();
- d->intersectVector.clear();
+ QVector<QModelIndex> intersectVector;
switch (cursorAction) {
case MoveLeft:
- while (d->intersectVector.isEmpty()) {
+ while (intersectVector.isEmpty()) {
rect.translate(-rect.width(), 0);
if (rect.right() <= 0)
return current;
if (rect.left() < 0)
rect.setLeft(0);
- d->intersectingSet(rect);
- d->removeCurrentAndDisabled(&d->intersectVector, current);
+ intersectVector = d->intersectingSet(rect);
+ d->removeCurrentAndDisabled(&intersectVector, current);
}
- return d->closestIndex(initialRect, d->intersectVector);
+ return d->closestIndex(initialRect, intersectVector);
case MoveRight:
- while (d->intersectVector.isEmpty()) {
+ while (intersectVector.isEmpty()) {
rect.translate(rect.width(), 0);
if (rect.left() >= contents.width())
return current;
if (rect.right() > contents.width())
rect.setRight(contents.width());
- d->intersectingSet(rect);
- d->removeCurrentAndDisabled(&d->intersectVector, current);
+ intersectVector = d->intersectingSet(rect);
+ d->removeCurrentAndDisabled(&intersectVector, current);
}
- return d->closestIndex(initialRect, d->intersectVector);
+ return d->closestIndex(initialRect, intersectVector);
case MovePageUp:
rect.moveTop(rect.top() - d->viewport->height());
if (rect.top() < rect.height())
rect.moveTop(rect.height());
case MovePrevious:
case MoveUp:
- while (d->intersectVector.isEmpty()) {
+ while (intersectVector.isEmpty()) {
rect.translate(0, -rect.height());
if (rect.bottom() <= 0) {
#ifdef QT_KEYPAD_NAVIGATION
@@ -1372,17 +1396,17 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
}
if (rect.top() < 0)
rect.setTop(0);
- d->intersectingSet(rect);
- d->removeCurrentAndDisabled(&d->intersectVector, current);
+ intersectVector = d->intersectingSet(rect);
+ d->removeCurrentAndDisabled(&intersectVector, current);
}
- return d->closestIndex(initialRect, d->intersectVector);
+ return d->closestIndex(initialRect, intersectVector);
case MovePageDown:
rect.moveTop(rect.top() + d->viewport->height());
if (rect.bottom() > contents.height() - rect.height())
rect.moveBottom(contents.height() - rect.height());
case MoveNext:
case MoveDown:
- while (d->intersectVector.isEmpty()) {
+ while (intersectVector.isEmpty()) {
rect.translate(0, rect.height());
if (rect.top() >= contents.height()) {
#ifdef QT_KEYPAD_NAVIGATION
@@ -1399,10 +1423,10 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
}
if (rect.bottom() > contents.height())
rect.setBottom(contents.height());
- d->intersectingSet(rect);
- d->removeCurrentAndDisabled(&d->intersectVector, current);
+ intersectVector = d->intersectingSet(rect);
+ d->removeCurrentAndDisabled(&intersectVector, current);
}
- return d->closestIndex(initialRect, d->intersectVector);
+ return d->closestIndex(initialRect, intersectVector);
case MoveHome:
return d->model->index(0, d->column, d->root);
case MoveEnd:
@@ -1477,10 +1501,10 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl
QItemSelection selection;
if (rect.width() == 1 && rect.height() == 1) {
- d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset()));
+ const QVector<QModelIndex> intersectVector = d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset()));
QModelIndex tl;
- if (!d->intersectVector.isEmpty())
- tl = d->intersectVector.last(); // special case for mouse press; only select the top item
+ if (!intersectVector.isEmpty())
+ tl = intersectVector.last(); // special case for mouse press; only select the top item
if (tl.isValid() && d->isIndexEnabled(tl))
selection.select(tl, tl);
} else {
@@ -1490,14 +1514,14 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl
QModelIndex tl, br;
// get the first item
const QRect topLeft(rect.left() + horizontalOffset(), rect.top() + verticalOffset(), 1, 1);
- d->intersectingSet(topLeft);
- if (!d->intersectVector.isEmpty())
- tl = d->intersectVector.last();
+ QVector<QModelIndex> intersectVector = d->intersectingSet(topLeft);
+ if (!intersectVector.isEmpty())
+ tl = intersectVector.last();
// get the last item
const QRect bottomRight(rect.right() + horizontalOffset(), rect.bottom() + verticalOffset(), 1, 1);
- d->intersectingSet(bottomRight);
- if (!d->intersectVector.isEmpty())
- br = d->intersectVector.last();
+ intersectVector = d->intersectingSet(bottomRight);
+ if (!intersectVector.isEmpty())
+ br = intersectVector.last();
// get the ranges
if (tl.isValid() && br.isValid()
@@ -1633,14 +1657,16 @@ QRegion QListView::visualRegionForSelection(const QItemSelection &selection) con
QModelIndexList QListView::selectedIndexes() const
{
Q_D(const QListView);
- QModelIndexList viewSelected;
- QModelIndexList modelSelected;
- if (d->selectionModel)
- modelSelected = d->selectionModel->selectedIndexes();
- for (int i = 0; i < modelSelected.count(); ++i) {
- QModelIndex index = modelSelected.at(i);
+ if (!d->selectionModel)
+ return QModelIndexList();
+
+ QModelIndexList viewSelected = d->selectionModel->selectedIndexes();
+ for (int i = 0; i < viewSelected.count(); ++i) {
+ const QModelIndex &index = viewSelected.at(i);
if (!isIndexHidden(index) && index.parent() == d->root && index.column() == d->column)
- viewSelected.append(index);
+ ++i;
+ else
+ viewSelected.removeAt(i);
}
return viewSelected;
}
@@ -2116,8 +2142,8 @@ QItemSelection QListViewPrivate::selection(const QRect &rect) const
{
QItemSelection selection;
QModelIndex tl, br;
- intersectingSet(rect);
- QVector<QModelIndex>::iterator it = intersectVector.begin();
+ const QVector<QModelIndex> intersectVector = intersectingSet(rect);
+ QVector<QModelIndex>::const_iterator it = intersectVector.begin();
for (; it != intersectVector.end(); ++it) {
if (!tl.isValid() && !br.isValid()) {
tl = br = *it;
@@ -2408,9 +2434,9 @@ void QStaticListViewBase::doStaticLayout(const QListViewLayoutInfo &info)
Finds the set of items intersecting with \a area.
In this function, itemsize is counted from topleft to the start of the next item.
*/
-void QStaticListViewBase::intersectingStaticSet(const QRect &area) const
+QVector<QModelIndex> QStaticListViewBase::intersectingStaticSet(const QRect &area) const
{
- clearIntersections();
+ QVector<QModelIndex> ret;
int segStartPosition;
int segEndPosition;
int flowStartPosition;
@@ -2427,7 +2453,7 @@ void QStaticListViewBase::intersectingStaticSet(const QRect &area) const
flowEndPosition = area.bottom();
}
if (segmentPositions.count() < 2 || flowPositions.isEmpty())
- return;
+ return ret;
// the last segment position is actually the edge of the last segment
const int segLast = segmentPositions.count() - 2;
int seg = qBinarySearch<int>(segmentPositions, segStartPosition, 0, segLast + 1);
@@ -2442,13 +2468,14 @@ void QStaticListViewBase::intersectingStaticSet(const QRect &area) const
continue;
QModelIndex index = modelIndex(row);
if (index.isValid())
- appendToIntersections(index);
+ ret += index;
#if 0 // for debugging
else
qWarning("intersectingStaticSet: row %d was invalid", row);
#endif
}
}
+ return ret;
}
int QStaticListViewBase::itemIndex(const QListViewItem &item) const
@@ -2769,12 +2796,15 @@ void QDynamicListViewBase::doDynamicLayout(const QListViewLayoutInfo &info)
viewport()->update();
}
-void QDynamicListViewBase::intersectingDynamicSet(const QRect &area) const
+QVector<QModelIndex> QDynamicListViewBase::intersectingDynamicSet(const QRect &area) const
{
- clearIntersections();
- QListViewPrivate *that = const_cast<QListViewPrivate*>(dd);
+ QDynamicListViewBase *that = const_cast<QDynamicListViewBase*>(this);
QBspTree::Data data(static_cast<void*>(that));
- that->dynamicListView->tree.climbTree(area, &QDynamicListViewBase::addLeaf, data);
+ QVector<QModelIndex> res;
+ that->interSectingVector = &res;
+ that->tree.climbTree(area, &QDynamicListViewBase::addLeaf, data);
+ that->interSectingVector = 0;
+ return res;
}
void QDynamicListViewBase::createItems(int to)
@@ -2851,20 +2881,20 @@ int QDynamicListViewBase::itemIndex(const QListViewItem &item) const
}
void QDynamicListViewBase::addLeaf(QVector<int> &leaf, const QRect &area,
- uint visited, QBspTree::Data data)
+ uint visited, QBspTree::Data data)
{
QListViewItem *vi;
- QListViewPrivate *_this = static_cast<QListViewPrivate *>(data.ptr);
+ QDynamicListViewBase *_this = static_cast<QDynamicListViewBase *>(data.ptr);
for (int i = 0; i < leaf.count(); ++i) {
int idx = leaf.at(i);
- if (idx < 0 || idx >= _this->dynamicListView->items.count())
+ if (idx < 0 || idx >= _this->items.count())
continue;
- vi = &_this->dynamicListView->items[idx];
+ vi = &_this->items[idx];
Q_ASSERT(vi);
if (vi->isValid() && vi->rect().intersects(area) && vi->visited != visited) {
- QModelIndex index = _this->listViewItemToIndex(*vi);
+ QModelIndex index = _this->dd->listViewItemToIndex(*vi);
Q_ASSERT(index.isValid());
- _this->intersectVector.append(index);
+ _this->interSectingVector->append(index);
vi->visited = visited;
}
}
diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h
index a7a7000..1727ba4 100644
--- a/src/gui/itemviews/qlistview_p.h
+++ b/src/gui/itemviews/qlistview_p.h
@@ -153,9 +153,6 @@ public:
inline bool isHidden(int row) const;
inline int hiddenCount() const;
- inline void clearIntersections() const;
- inline void appendToIntersections(const QModelIndex &idx) const;
-
inline bool isRightToLeft() const;
QListViewPrivate *dd;
@@ -186,7 +183,7 @@ public:
QPoint initStaticLayout(const QListViewLayoutInfo &info);
void doStaticLayout(const QListViewLayoutInfo &info);
- void intersectingStaticSet(const QRect &area) const;
+ QVector<QModelIndex> intersectingStaticSet(const QRect &area) const;
int itemIndex(const QListViewItem &item) const;
@@ -216,7 +213,7 @@ class QDynamicListViewBase : public QCommonListViewBase
friend class QListViewPrivate;
public:
QDynamicListViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d),
- batchStartRow(0), batchSavedDeltaSeg(0) {}
+ batchStartRow(0), batchSavedDeltaSeg(0), interSectingVector(0) {}
QBspTree tree;
QVector<QListViewItem> items;
@@ -230,6 +227,7 @@ public:
// used when laying out in batches
int batchStartRow;
int batchSavedDeltaSeg;
+ QVector<QModelIndex> *interSectingVector; //used from within intersectingDynamicSet
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max);
@@ -237,7 +235,7 @@ public:
void initBspTree(const QSize &contents);
QPoint initDynamicLayout(const QListViewLayoutInfo &info);
void doDynamicLayout(const QListViewLayoutInfo &info);
- void intersectingDynamicSet(const QRect &area) const;
+ QVector<QModelIndex> intersectingDynamicSet(const QRect &area) const;
static void addLeaf(QVector<int> &leaf, const QRect &area,
uint visited, QBspTree::Data data);
@@ -277,11 +275,11 @@ public:
bool doItemsLayout(int num);
- inline void intersectingSet(const QRect &area, bool doLayout = true) const {
+ inline QVector<QModelIndex> intersectingSet(const QRect &area, bool doLayout = true) const {
if (doLayout) executePostedLayout();
QRect a = (q_func()->isRightToLeft() ? flipX(area.normalized()) : area.normalized());
- if (viewMode == QListView::ListMode) staticListView->intersectingStaticSet(a);
- else dynamicListView->intersectingDynamicSet(a);
+ return (viewMode == QListView::ListMode) ? staticListView->intersectingStaticSet(a)
+ : dynamicListView->intersectingDynamicSet(a);
}
// ### FIXME:
@@ -351,6 +349,8 @@ public:
void scrollElasticBandBy(int dx, int dy);
+ QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
+
// ### FIXME: we only need one at a time
QDynamicListViewBase *dynamicListView;
QStaticListViewBase *staticListView;
@@ -383,9 +383,6 @@ public:
QRect layoutBounds;
- // used for intersecting set
- mutable QVector<QModelIndex> intersectVector;
-
// timers
QBasicTimer batchLayoutTimer;
@@ -438,9 +435,6 @@ inline QAbstractItemDelegate *QCommonListViewBase::delegate(const QModelIndex &i
inline bool QCommonListViewBase::isHidden(int row) const { return dd->isHidden(row); }
inline int QCommonListViewBase::hiddenCount() const { return dd->hiddenRows.count(); }
-inline void QCommonListViewBase::clearIntersections() const { dd->intersectVector.clear(); }
-inline void QCommonListViewBase::appendToIntersections(const QModelIndex &idx) const { dd->intersectVector.append(idx); }
-
inline bool QCommonListViewBase::isRightToLeft() const { return qq->isRightToLeft(); }
QT_END_NAMESPACE
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index c676237..2009499 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -1528,6 +1528,8 @@ void QTableView::updateGeometries()
++columnsInViewport;
}
}
+ columnsInViewport = qMax(columnsInViewport, 1); //there must be always at least 1 column
+
if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
const int visibleColumns = columnCount - d->horizontalHeader->hiddenSectionCount();
horizontalScrollBar()->setRange(0, visibleColumns - columnsInViewport);
@@ -1554,6 +1556,8 @@ void QTableView::updateGeometries()
++rowsInViewport;
}
}
+ rowsInViewport = qMax(rowsInViewport, 1); //there must be always at least 1 row
+
if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {
const int visibleRows = rowCount - d->verticalHeader->hiddenSectionCount();
verticalScrollBar()->setRange(0, visibleRows - rowsInViewport);
@@ -2036,7 +2040,7 @@ void QTableView::scrollTo(const QModelIndex &index, ScrollHint hint)
if (positionAtRight || hint == PositionAtCenter || positionAtLeft) {
int hiddenSections = 0;
if (d->horizontalHeader->sectionsHidden()) {
- for (int s = horizontalIndex; s >= 0; --s) {
+ for (int s = horizontalIndex - 1; s >= 0; --s) {
int column = d->horizontalHeader->logicalIndex(s);
if (d->horizontalHeader->isSectionHidden(column))
++hiddenSections;
@@ -2091,7 +2095,7 @@ void QTableView::scrollTo(const QModelIndex &index, ScrollHint hint)
if (hint == PositionAtBottom || hint == PositionAtCenter || hint == PositionAtTop) {
int hiddenSections = 0;
if (d->verticalHeader->sectionsHidden()) {
- for (int s = verticalIndex; s >= 0; --s) {
+ for (int s = verticalIndex - 1; s >= 0; --s) {
int row = d->verticalHeader->logicalIndex(s);
if (d->verticalHeader->isSectionHidden(row))
++hiddenSections;
diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp
index 7c319dc..f13ff0c 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/gui/itemviews/qtreeview.cpp
@@ -262,10 +262,6 @@ void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel)
Q_D(QTreeView);
Q_ASSERT(selectionModel);
if (d->selectionModel) {
- if (d->allColumnsShowFocus) {
- QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));
- }
// support row editing
disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
d->model, SLOT(submit()));
@@ -275,10 +271,6 @@ void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel)
QAbstractItemView::setSelectionModel(selectionModel);
if (d->selectionModel) {
- if (d->allColumnsShowFocus) {
- QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));
- }
// support row editing
connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
d->model, SLOT(submit()));
@@ -901,15 +893,6 @@ void QTreeView::setAllColumnsShowFocus(bool enable)
Q_D(QTreeView);
if (d->allColumnsShowFocus == enable)
return;
- if (d->selectionModel) {
- if (enable) {
- QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));
- } else {
- QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));
- }
- }
d->allColumnsShowFocus = enable;
d->viewport->update();
}
@@ -1267,10 +1250,13 @@ void QTreeView::paintEvent(QPaintEvent *event)
Q_D(QTreeView);
d->executePostedLayout();
QPainter painter(viewport());
+#ifndef QT_NO_ANIMATION
if (d->isAnimating()) {
- drawTree(&painter, event->region() - d->animationRect());
+ drawTree(&painter, event->region() - d->animatedOperation.rect());
d->drawAnimatedOperation(&painter);
- } else {
+ } else
+#endif //QT_NO_ANIMATION
+ {
drawTree(&painter, event->region());
#ifndef QT_NO_DRAGANDDROP
d->paintDropIndicator(&painter);
@@ -1306,13 +1292,13 @@ bool QTreeViewPrivate::expandOrCollapseItemAtPos(const QPoint &pos)
{
Q_Q(QTreeView);
// we want to handle mousePress in EditingState (persistent editors)
- if ((q->state() != QAbstractItemView::NoState
- && q->state() != QAbstractItemView::EditingState)
+ if ((state != QAbstractItemView::NoState
+ && state != QAbstractItemView::EditingState)
|| !viewport->rect().contains(pos))
return true;
int i = itemDecorationAt(pos);
- if ((i != -1) && q->itemsExpandable() && hasVisibleChildren(viewItems.at(i).index)) {
+ if ((i != -1) && itemsExpandable && hasVisibleChildren(viewItems.at(i).index)) {
if (viewItems.at(i).expanded)
collapse(i, true);
else
@@ -2851,10 +2837,9 @@ void QTreeViewPrivate::initialize()
header->setStretchLastSection(true);
header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter);
q->setHeader(header);
-
- // animation
- QObject::connect(&timeline, SIGNAL(frameChanged(int)), q, SLOT(_q_animate()));
- QObject::connect(&timeline, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()), Qt::QueuedConnection);
+#ifndef QT_NO_ANIMATION
+ QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()));
+#endif //QT_NO_ANIMATION
}
void QTreeViewPrivate::expand(int item, bool emitSignal)
@@ -2864,10 +2849,11 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
if (item == -1 || viewItems.at(item).expanded)
return;
+#ifndef QT_NO_ANIMATION
if (emitSignal && animationsEnabled)
- prepareAnimatedOperation(item, AnimatedOperation::Expand);
-
- QAbstractItemView::State oldState = q->state();
+ prepareAnimatedOperation(item, QVariantAnimation::Forward);
+#endif //QT_NO_ANIMATION
+ QAbstractItemView::State oldState = state;
q->setState(QAbstractItemView::ExpandingState);
const QModelIndex index = viewItems.at(item).index;
storeExpanded(index);
@@ -2877,8 +2863,10 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
if (emitSignal) {
emit q->expanded(index);
+#ifndef QT_NO_ANIMATION
if (animationsEnabled)
beginAnimatedOperation();
+#endif //QT_NO_ANIMATION
}
if (model->canFetchMore(index))
model->fetchMore(index);
@@ -2902,10 +2890,12 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal)
if (it == expandedIndexes.end() || viewItems.at(item).expanded == false)
return; // nothing to do
+#ifndef QT_NO_ANIMATION
if (emitSignal && animationsEnabled)
- prepareAnimatedOperation(item, AnimatedOperation::Collapse);
+ prepareAnimatedOperation(item, QVariantAnimation::Backward);
+#endif //QT_NO_ANIMATION
- QAbstractItemView::State oldState = q->state();
+ QAbstractItemView::State oldState = state;
q->setState(QAbstractItemView::CollapsingState);
expandedIndexes.erase(it);
viewItems[item].expanded = false;
@@ -2922,29 +2912,33 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal)
if (emitSignal) {
emit q->collapsed(modelIndex);
+#ifndef QT_NO_ANIMATION
if (animationsEnabled)
beginAnimatedOperation();
+#endif //QT_NO_ANIMATION
}
}
-void QTreeViewPrivate::prepareAnimatedOperation(int item, AnimatedOperation::Type type)
+#ifndef QT_NO_ANIMATION
+void QTreeViewPrivate::prepareAnimatedOperation(int item, QVariantAnimation::Direction direction)
{
animatedOperation.item = item;
- animatedOperation.type = type;
+ animatedOperation.viewport = viewport;
+ animatedOperation.setDirection(direction);
int top = coordinateForItem(item) + itemHeight(item);
QRect rect = viewport->rect();
rect.setTop(top);
- if (type == AnimatedOperation::Collapse) {
+ if (direction == QVariantAnimation::Backward) {
const int limit = rect.height() * 2;
int h = 0;
int c = item + viewItems.at(item).total + 1;
for (int i = item + 1; i < c && h < limit; ++i)
h += itemHeight(i);
rect.setHeight(h);
- animatedOperation.duration = h;
+ animatedOperation.setEndValue(top + h);
}
- animatedOperation.top = top;
+ animatedOperation.setStartValue(top);
animatedOperation.before = renderTreeToPixmapForAnimation(rect);
}
@@ -2953,50 +2947,29 @@ void QTreeViewPrivate::beginAnimatedOperation()
Q_Q(QTreeView);
QRect rect = viewport->rect();
- rect.setTop(animatedOperation.top);
- if (animatedOperation.type == AnimatedOperation::Expand) {
+ rect.setTop(animatedOperation.top());
+ if (animatedOperation.direction() == QVariantAnimation::Forward) {
const int limit = rect.height() * 2;
int h = 0;
int c = animatedOperation.item + viewItems.at(animatedOperation.item).total + 1;
for (int i = animatedOperation.item + 1; i < c && h < limit; ++i)
h += itemHeight(i);
rect.setHeight(h);
- animatedOperation.duration = h;
+ animatedOperation.setEndValue(animatedOperation.top() + h);
}
animatedOperation.after = renderTreeToPixmapForAnimation(rect);
q->setState(QAbstractItemView::AnimatingState);
-
- timeline.stop();
- timeline.setDuration(250);
- timeline.setFrameRange(animatedOperation.top, animatedOperation.top + animatedOperation.duration);
- timeline.start();
-}
-
-void QTreeViewPrivate::_q_endAnimatedOperation()
-{
- Q_Q(QTreeView);
- animatedOperation.before = QPixmap();
- animatedOperation.after = QPixmap();
- q->setState(QAbstractItemView::NoState);
- q->updateGeometries();
- viewport->update();
-}
-
-void QTreeViewPrivate::_q_animate()
-{
- QRect rect = viewport->rect();
- rect.moveTop(animatedOperation.top);
- viewport->repaint(rect);
+ animatedOperation.start(); //let's start the animation
}
void QTreeViewPrivate::drawAnimatedOperation(QPainter *painter) const
{
- int start = timeline.startFrame();
- int end = timeline.endFrame();
- bool collapsing = animatedOperation.type == AnimatedOperation::Collapse;
- int current = collapsing ? end - timeline.currentFrame() + start : timeline.currentFrame();
+ const int start = animatedOperation.startValue().toInt(),
+ end = animatedOperation.endValue().toInt(),
+ current = animatedOperation.currentValue().toInt();
+ bool collapsing = animatedOperation.direction() == QVariantAnimation::Backward;
const QPixmap top = collapsing ? animatedOperation.before : animatedOperation.after;
painter->drawPixmap(0, start, top, 0, end - current - 1, top.width(), top.height());
const QPixmap bottom = collapsing ? animatedOperation.after : animatedOperation.before;
@@ -3039,26 +3012,14 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons
return pixmap;
}
-void QTreeViewPrivate::_q_currentChanged(const QModelIndex &current, const QModelIndex &previous)
+void QTreeViewPrivate::_q_endAnimatedOperation()
{
Q_Q(QTreeView);
- if (previous.isValid()) {
- QRect previousRect = q->visualRect(previous);
- if (allColumnsShowFocus) {
- previousRect.setX(0);
- previousRect.setWidth(viewport->width());
- }
- viewport->update(previousRect);
- }
- if (current.isValid()) {
- QRect currentRect = q->visualRect(current);
- if (allColumnsShowFocus) {
- currentRect.setX(0);
- currentRect.setWidth(viewport->width());
- }
- viewport->update(currentRect);
- }
+ q->setState(QAbstractItemView::NoState);
+ q->updateGeometries();
+ viewport->update();
}
+#endif //QT_NO_ANIMATION
void QTreeViewPrivate::_q_modelAboutToBeReset()
{
@@ -3787,6 +3748,21 @@ void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &pr
}
#endif
QAbstractItemView::currentChanged(current, previous);
+
+ if (allColumnsShowFocus()) {
+ if (previous.isValid()) {
+ QRect previousRect = visualRect(previous);
+ previousRect.setX(0);
+ previousRect.setWidth(viewport()->width());
+ viewport()->update(previousRect);
+ }
+ if (current.isValid()) {
+ QRect currentRect = visualRect(current);
+ currentRect.setX(0);
+ currentRect.setWidth(viewport()->width());
+ viewport()->update(currentRect);
+ }
+ }
}
/*!
diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h
index 0347645..4411781 100644
--- a/src/gui/itemviews/qtreeview.h
+++ b/src/gui/itemviews/qtreeview.h
@@ -223,12 +223,11 @@ private:
Q_DECLARE_PRIVATE(QTreeView)
Q_DISABLE_COPY(QTreeView)
+#ifndef QT_NO_ANIMATION
Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation())
- Q_PRIVATE_SLOT(d_func(), void _q_animate())
- Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex&, const QModelIndex &))
+#endif //QT_NO_ANIMATION
Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset())
Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order))
- Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
};
#endif // QT_NO_TREEVIEW
diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h
index 6a1dfe5..6fb2e41 100644
--- a/src/gui/itemviews/qtreeview_p.h
+++ b/src/gui/itemviews/qtreeview_p.h
@@ -54,6 +54,7 @@
//
#include "private/qabstractitemview_p.h"
+#include <QtCore/qvariantanimation.h>
#ifndef QT_NO_TREEVIEW
@@ -81,42 +82,39 @@ public:
uniformRowHeights(false), rootDecoration(true),
itemsExpandable(true), sortingEnabled(false),
expandsOnDoubleClick(true),
- allColumnsShowFocus(false),
+ allColumnsShowFocus(false), current(0),
animationsEnabled(false), columnResizeTimerID(0),
autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false) {}
~QTreeViewPrivate() {}
void initialize();
- struct AnimatedOperation
+#ifndef QT_NO_ANIMATION
+ struct AnimatedOperation : public QVariantAnimation
{
- enum Type { Expand, Collapse };
int item;
- int top;
- int duration;
- Type type;
QPixmap before;
QPixmap after;
- };
-
- void expand(int item, bool emitSignal);
- void collapse(int item, bool emitSignal);
-
- void prepareAnimatedOperation(int item, AnimatedOperation::Type type);
+ QWidget *viewport;
+ AnimatedOperation() : item(0) { setEasingCurve(QEasingCurve::InOutQuad); }
+ int top() const { return startValue().toInt(); }
+ QRect rect() const { QRect rect = viewport->rect(); rect.moveTop(top()); return rect; }
+ void updateCurrentValue(const QVariant &) { viewport->update(rect()); }
+ void updateState(State, State state) { if (state == Stopped) before = after = QPixmap(); }
+ } animatedOperation;
+ void prepareAnimatedOperation(int item, QVariantAnimation::Direction d);
void beginAnimatedOperation();
- void _q_endAnimatedOperation();
void drawAnimatedOperation(QPainter *painter) const;
QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const;
+ void _q_endAnimatedOperation();
+#endif //QT_NO_ANIMATION
- inline QRect animationRect() const
- { return QRect(0, animatedOperation.top, viewport->width(),
- viewport->height() - animatedOperation.top); }
+ void expand(int item, bool emitSignal);
+ void collapse(int item, bool emitSignal);
- void _q_currentChanged(const QModelIndex&, const QModelIndex&);
void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int);
void _q_columnsRemoved(const QModelIndex &, int, int);
void _q_modelAboutToBeReset();
- void _q_animate();
void _q_sortIndicatorChanged(int column, Qt::SortOrder order);
void _q_modelDestroyed();
@@ -177,8 +175,6 @@ public:
// used when expanding and collapsing items
QSet<QPersistentModelIndex> expandedIndexes;
- QStack<bool> expandParent;
- AnimatedOperation animatedOperation;
bool animationsEnabled;
inline bool storeExpanded(const QPersistentModelIndex &idx) {
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 839e465..b168188 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -126,7 +126,7 @@ int QApplicationPrivate::app_compile_version = 0x040000; //we don't know exactly
QApplication::Type qt_appType=QApplication::Tty;
QApplicationPrivate *QApplicationPrivate::self = 0;
-QInputContext *QApplicationPrivate::inputContext;
+QInputContext *QApplicationPrivate::inputContext = 0;
bool QApplicationPrivate::quitOnLastWindowClosed = true;
@@ -3716,6 +3716,13 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
Qt::MouseFocusReason);
}
+ // ### Qt 5 These dynamic tool tips should be an OPT-IN feature. Some platforms
+ // like Mac OS X (probably others too), can optimize their views by not
+ // dispatching mouse move events. We have attributes to control hover,
+ // and mouse tracking, but as long as we are deciding to implement this
+ // feature without choice of opting-in or out, you ALWAYS have to have
+ // tracking enabled. Therefore, the other properties give a false sense of
+ // performance enhancement.
if (e->type() == QEvent::MouseMove && mouse->buttons() == 0) {
d->toolTipWidget = w;
d->toolTipPos = relpos;
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index 0884976..beccfb0 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -1316,8 +1316,13 @@ void QApplication::setOverrideCursor(const QCursor &cursor)
{
qApp->d_func()->cursor_list.prepend(cursor);
+#ifdef QT_MAC_USE_COCOA
+ QMacCocoaAutoReleasePool pool;
+ [static_cast<NSCursor *>(qt_mac_nsCursorForQCursor(cursor)) push];
+#else
if (qApp && qApp->activeWindow())
qt_mac_set_cursor(&qApp->d_func()->cursor_list.first(), QCursor::pos());
+#endif
}
void QApplication::restoreOverrideCursor()
@@ -1326,12 +1331,17 @@ void QApplication::restoreOverrideCursor()
return;
qApp->d_func()->cursor_list.removeFirst();
+#ifdef QT_MAC_USE_COCOA
+ QMacCocoaAutoReleasePool pool;
+ [NSCursor pop];
+#else
if (qApp && qApp->activeWindow()) {
const QCursor def(Qt::ArrowCursor);
qt_mac_set_cursor(qApp->d_func()->cursor_list.isEmpty() ? &def : &qApp->d_func()->cursor_list.first(), QCursor::pos());
}
-}
#endif
+}
+#endif // QT_NO_CURSOR
QWidget *QApplication::topLevelAt(const QPoint &p)
{
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index db77b07..90eaba0 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -158,17 +158,19 @@ inline QPointF QTabletDeviceData::scaleCoord(int coordX, int coordY,
int outOriginY, int outExtentY) const
{
QPointF ret;
+
if (sign(outExtentX) == sign(maxX))
- ret.setX(((coordX - minX) * qAbs(outExtentX) / qAbs(qreal(maxX))) + outOriginX);
+ ret.setX(((coordX - minX) * qAbs(outExtentX) / qAbs(qreal(maxX - minX))) + outOriginX);
else
- ret.setX(((qAbs(maxX) - (coordX - minX)) * qAbs(outExtentX) / qAbs(qreal(maxX)))
+ ret.setX(((qAbs(maxX) - (coordX - minX)) * qAbs(outExtentX) / qAbs(qreal(maxX - minX)))
+ outOriginX);
if (sign(outExtentY) == sign(maxY))
- ret.setY(((coordY - minY) * qAbs(outExtentY) / qAbs(qreal(maxY))) + outOriginY);
+ ret.setY(((coordY - minY) * qAbs(outExtentY) / qAbs(qreal(maxY - minY))) + outOriginY);
else
- ret.setY(((qAbs(maxY) - (coordY - minY)) * qAbs(outExtentY) / qAbs(qreal(maxY)))
+ ret.setY(((qAbs(maxY) - (coordY - minY)) * qAbs(outExtentY) / qAbs(qreal(maxY - minY)))
+ outOriginY);
+
return ret;
}
#endif
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index e0eda82..e0c62b7 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -2956,7 +2956,9 @@ bool QETWidget::translateMouseEvent(const MSG &msg)
if (alienWidget && alienWidget->internalWinId())
alienWidget = 0;
- if (type == QEvent::MouseMove || type == QEvent::NonClientAreaMouseMove) {
+ if (type == QEvent::MouseMove || type == QEvent::NonClientAreaMouseMove
+ || type == QEvent::TabletMove) {
+
if (!(state & Qt::MouseButtonMask))
qt_button_down = 0;
#ifndef QT_NO_CURSOR
@@ -3087,6 +3089,8 @@ bool QETWidget::translateMouseEvent(const MSG &msg)
popupButtonFocus = popupChild;
break;
case QEvent::MouseButtonRelease:
+ case QEvent::TabletRelease:
+
releaseAfter = true;
break;
default:
@@ -3324,17 +3328,19 @@ static void tabletInit(UINT wActiveCsr, HCTX hTab)
tdd.minTanPressure = int(np.axMin);
tdd.maxTanPressure = int(np.axMax);
- ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_X, &np);
- tdd.minX = int(np.axMin);
- tdd.maxX = int(np.axMax);
+ LOGCONTEXT lcMine;
+
+ /* get default region */
+ ptrWTInfo(WTI_DEFCONTEXT, 0, &lcMine);
+
+ tdd.minX = 0;
+ tdd.maxX = int(lcMine.lcInExtX) - int(lcMine.lcInOrgX);
- ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_Y, &np);
- tdd.minY = int(np.axMin);
- tdd.maxY = int(np.axMax);
+ tdd.minY = 0;
+ tdd.maxY = int(lcMine.lcInExtY) - int(lcMine.lcInOrgY);
- ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_Z, &np);
- tdd.minZ = int(np.axMin);
- tdd.maxZ = int(np.axMax);
+ tdd.minZ = 0;
+ tdd.maxZ = int(lcMine.lcInExtZ) - int(lcMine.lcInOrgZ);
int csr_type,
csr_physid;
@@ -3444,13 +3450,34 @@ bool QETWidget::translateTabletEvent(const MSG &msg, PACKET *localPacketBuf,
}
QPoint globalPos(qRound(hiResGlobal.x()), qRound(hiResGlobal.y()));
+ if (t == QEvent::TabletPress)
+ {
+ qt_button_down = QApplication::widgetAt(globalPos);
+ }
+
// make sure the tablet event get's sent to the proper widget...
- QWidget *w = QApplication::widgetAt(globalPos);
+ QWidget *w = 0;
+
if (qt_button_down)
w = qt_button_down; // Pass it to the thing that's grabbed it.
+ else
+ w = QApplication::widgetAt(globalPos);
if (!w)
w = this;
+
+ if (t == QEvent::TabletRelease)
+ {
+ if (qt_win_ignoreNextMouseReleaseEvent) {
+ qt_win_ignoreNextMouseReleaseEvent = false;
+ if (qt_button_down && qt_button_down->internalWinId() == autoCaptureWnd) {
+ releaseAutoCapture();
+ qt_button_down = 0;
+ }
+ }
+
+ }
+
QPoint localPos = w->mapFromGlobal(globalPos);
#ifndef QT_NO_TABLETEVENT
if (currentTabletPointer.currentDevice == QTabletEvent::Airbrush) {
diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm
index bdc7ecb..1e0bbdf 100644
--- a/src/gui/kernel/qcocoapanel_mac.mm
+++ b/src/gui/kernel/qcocoapanel_mac.mm
@@ -85,6 +85,12 @@ QT_USE_NAMESPACE
last resort (i.e., this is code that can potentially be removed).
*/
+- (void)toggleToolbarShown:(id)sender
+{
+ macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]);
+ [super toggleToolbarShown:sender];
+}
+
- (void)keyDown:(NSEvent *)theEvent
{
bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 64cdae6..52685ca 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -290,11 +290,18 @@ extern "C" {
{
if (qwidget->testAttribute(Qt::WA_DropSiteRegistered) == false)
return NSDragOperationNone;
+ NSPoint windowPoint = [sender draggingLocation];
+ if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
+ // pass the drag enter event to the view underneath.
+ NSView *candidateView = [[[self window] contentView] hitTest:windowPoint];
+ if (candidateView && candidateView != self)
+ return [candidateView draggingEntered:sender];
+ }
+ dragEnterSequence = [sender draggingSequenceNumber];
[self addDropData:sender];
QMimeData *mimeData = dropData;
if (QDragManager::self()->source())
mimeData = QDragManager::self()->dragPrivate()->data;
- NSPoint windowPoint = [sender draggingLocation];
NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
QPoint posDrag(localPoint.x, localPoint.y);
@@ -318,6 +325,9 @@ extern "C" {
[self removeDropData];
return NSDragOperationNone;
} else {
+ // save the mouse position, used by draggingExited handler.
+ DnDParams *dndParams = [QCocoaView currentMouseEvent];
+ dndParams->activeDragEnterPos = windowPoint;
// send a drag move event immediately after a drag enter event (as per documentation).
QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers);
qDMEvent.setDropAction(qDEEvent.dropAction());
@@ -338,11 +348,22 @@ extern "C" {
- (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender
{
- // drag enter event was rejected, so ignore the move event.
+ NSPoint windowPoint = [sender draggingLocation];
+ if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
+ // pass the drag move event to the view underneath.
+ NSView *candidateView = [[[self window] contentView] hitTest:windowPoint];
+ if (candidateView && candidateView != self)
+ return [candidateView draggingUpdated:sender];
+ }
+ // in cases like QFocusFrame, the view under the mouse might
+ // not have received the drag enter. Generate a synthetic
+ // drag enter event for that view.
+ if (dragEnterSequence != [sender draggingSequenceNumber])
+ [self draggingEntered:sender];
+ // drag enter event was rejected, so ignore the move event.
if (dropData == 0)
return NSDragOperationNone;
// return last value, if we are still in the answerRect.
- NSPoint windowPoint = [sender draggingLocation];
NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
NSDragOperation nsActions = [sender draggingSourceOperationMask];
@@ -381,21 +402,34 @@ extern "C" {
- (void)draggingExited:(id < NSDraggingInfo >)sender
{
- Q_UNUSED(sender)
- // drag enter event was rejected, so ignore the move event.
+ dragEnterSequence = -1;
+ if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
+ // try sending the leave event to the last view which accepted drag enter.
+ DnDParams *dndParams = [QCocoaView currentMouseEvent];
+ NSView *candidateView = [[[self window] contentView] hitTest:dndParams->activeDragEnterPos];
+ if (candidateView && candidateView != self)
+ return [candidateView draggingExited:sender];
+ }
+ // drag enter event was rejected, so ignore the move event.
if (dropData) {
QDragLeaveEvent de;
QApplication::sendEvent(qwidget, &de);
[self removeDropData];
}
-
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
+ NSPoint windowPoint = [sender draggingLocation];
+ dragEnterSequence = -1;
+ if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
+ // pass the drop event to the view underneath.
+ NSView *candidateView = [[[self window] contentView] hitTest:windowPoint];
+ if (candidateView && candidateView != self)
+ return [candidateView performDragOperation:sender];
+ }
[self addDropData:sender];
- NSPoint windowPoint = [sender draggingLocation];
NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
QPoint posDrop(localPoint.x, localPoint.y);
@@ -574,11 +608,15 @@ extern "C" {
[self removeTrackingArea:t];
}
}
+
+ // Ideally, we shouldn't have NSTrackingMouseMoved events included below, it should
+ // only be turned on if mouseTracking, hover is on or a tool tip is set.
+ // Unfortunately, Qt will send "tooltip" events on mouse moves, so we need to
+ // turn it on in ALL case. That means EVERY QCocoaView gets to pay the cost of
+ // mouse moves delivered to it (Apple recommends keeping it OFF because there
+ // is a performance hit). So it goes.
NSUInteger trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp
- | NSTrackingInVisibleRect;
- if (qwidget->hasMouseTracking() || !qwidgetprivate->toolTip.isEmpty()
- || qwidget->testAttribute(Qt::WA_Hover))
- trackingOptions |= NSTrackingMouseMoved;
+ | NSTrackingInVisibleRect | NSTrackingMouseMoved;
NSTrackingArea *ta = [[NSTrackingArea alloc] initWithRect:NSMakeRect(0, 0,
qwidget->width(),
qwidget->height())
@@ -643,62 +681,6 @@ extern "C" {
qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton);
}
-- (NSView *)viewUnderTransparentForMouseView:(NSView *)mouseView widget:(QWidget *)widgetToGetMouse
- withWindowPoint:(NSPoint)windowPoint
-{
- NSMutableArray *viewsToLookAt = [NSMutableArray arrayWithCapacity:5];
- [viewsToLookAt addObject:mouseView];
- QWidget *parentWidget = widgetToGetMouse->parentWidget();
- while (parentWidget) {
- [viewsToLookAt addObject:qt_mac_nativeview_for(parentWidget)];
- parentWidget = parentWidget->parentWidget();
- }
-
- // Now walk through the subviews of each view and determine which subview should
- // get the event. We look through all the subviews at a given level with
- // the assumption that the last item to be found the candidate has a higher z-order.
- // Unfortunately, fast enumeration doesn't go backwards in 10.5, so assume go fast
- // forward is quicker than the slow normal way backwards.
- NSView *candidateView = nil;
- for (NSView *lookView in viewsToLookAt) {
- NSPoint tmpPoint = [lookView convertPoint:windowPoint fromView:nil];
- for (NSView *view in [lookView subviews]) {
- if (view == mouseView || [view isHidden])
- continue;
- NSRect frameRect = [view frame];
- if (NSMouseInRect(tmpPoint, [view frame], [view isFlipped]))
- candidateView = view;
- }
- if (candidateView)
- break;
- }
-
-
- if (candidateView != nil) {
- // Now that we've got a candidate, we have to dig into it's tree and see where it is.
- NSView *lowerView = nil;
- NSView *viewForDescent = candidateView;
- while (viewForDescent) {
- NSPoint tmpPoint = [viewForDescent convertPoint:windowPoint fromView:nil];
- // Apply same rule as above wrt z-order.
- for (NSView *view in [viewForDescent subviews]) {
- if (![view isHidden] && NSMouseInRect(tmpPoint, [view frame], [view isFlipped]))
- lowerView = view;
- }
- if (!lowerView) // Low as we can be at this point.
- candidateView = viewForDescent;
-
- // Try to go deeper, will also exit out of the loop, if we found the point.
- viewForDescent = lowerView;
- lowerView = nil;
- }
- }
- // I am transparent, so I can't be a candidate.
- if (candidateView == mouseView)
- candidateView = nil;
- return candidateView;
-}
-
- (void)mouseDown:(NSEvent *)theEvent
{
qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::LeftButton);
diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h
index 6583139..4762b17 100644
--- a/src/gui/kernel/qcocoaview_mac_p.h
+++ b/src/gui/kernel/qcocoaview_mac_p.h
@@ -68,6 +68,7 @@ struct DnDParams
NSEvent *theEvent;
NSPoint localPoint;
NSDragOperation performedAction;
+ NSPoint activeDragEnterPos;
};
QT_END_NAMESPACE
@@ -86,6 +87,7 @@ Q_GUI_EXPORT
bool sendKeyEvents;
QString *composingText;
QStringList *currentCustomTypes;
+ NSInteger dragEnterSequence;
}
- (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate;
- (void) finishInitWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate;
@@ -104,8 +106,6 @@ Q_GUI_EXPORT
- (QWidget *)qt_qwidget;
- (BOOL)qt_leftButtonIsRightButton;
- (void)qt_setLeftButtonIsRightButton:(BOOL)isSwapped;
-- (NSView *)viewUnderTransparentForMouseView:(NSView *)mouseView widget:(QWidget *)widgetToGetMouse
- withWindowPoint:(NSPoint)windowPoint;
+ (DnDParams*)currentMouseEvent;
@end
diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm
index 7084416..eb08982 100644
--- a/src/gui/kernel/qcocoawindow_mac.mm
+++ b/src/gui/kernel/qcocoawindow_mac.mm
@@ -104,6 +104,12 @@ QT_USE_NAMESPACE
last resort (i.e., this is code that can potentially be removed).
*/
+- (void)toggleToolbarShown:(id)sender
+{
+ macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]);
+ [super toggleToolbarShown:sender];
+}
+
- (void)keyDown:(NSEvent *)theEvent
{
bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
diff --git a/src/gui/kernel/qmultitouch_mac.mm b/src/gui/kernel/qmultitouch_mac.mm
index 3fe85a9..3d2eae6 100644
--- a/src/gui/kernel/qmultitouch_mac.mm
+++ b/src/gui/kernel/qmultitouch_mac.mm
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
#ifdef QT_MAC_USE_COCOA
-QHash<int, QCocoaTouch*> QCocoaTouch::_currentTouches;
+QHash<qint64, QCocoaTouch*> QCocoaTouch::_currentTouches;
QPointF QCocoaTouch::_screenReferencePos;
QPointF QCocoaTouch::_trackpadReferencePos;
int QCocoaTouch::_idAssignmentCount = 0;
@@ -62,7 +62,7 @@ QCocoaTouch::QCocoaTouch(NSTouch *nstouch)
_touchPoint.setId(_idAssignmentCount++);
_touchPoint.setPressure(1.0);
- _identity = int([nstouch identity]);
+ _identity = qint64([nstouch identity]);
_currentTouches.insert(_identity, this);
updateTouchData(nstouch, NSTouchPhaseBegan);
}
@@ -100,7 +100,7 @@ void QCocoaTouch::updateTouchData(NSTouch *nstouch, NSTouchPhase phase)
QCocoaTouch *QCocoaTouch::findQCocoaTouch(NSTouch *nstouch)
{
- int identity = int([nstouch identity]);
+ qint64 identity = qint64([nstouch identity]);
if (_currentTouches.contains(identity))
return _currentTouches.value(identity);
return 0;
diff --git a/src/gui/kernel/qmultitouch_mac_p.h b/src/gui/kernel/qmultitouch_mac_p.h
index 3fa8f6c..618e9ca 100644
--- a/src/gui/kernel/qmultitouch_mac_p.h
+++ b/src/gui/kernel/qmultitouch_mac_p.h
@@ -74,7 +74,7 @@ class QCocoaTouch
static void setMouseInDraggingState(bool inDraggingState);
private:
- static QHash<int, QCocoaTouch*> _currentTouches;
+ static QHash<qint64, QCocoaTouch*> _currentTouches;
static QPointF _screenReferencePos;
static QPointF _trackpadReferencePos;
static int _idAssignmentCount;
@@ -82,7 +82,7 @@ class QCocoaTouch
static bool _updateInternalStateOnly;
QTouchEvent::TouchPoint _touchPoint;
- int _identity;
+ qint64 _identity;
QCocoaTouch(NSTouch *nstouch);
~QCocoaTouch();
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 13b0e50..a98a7f8 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -177,11 +177,10 @@ void macWindowToolbarShow(const QWidget *widget, bool show )
{
OSWindowRef wnd = qt_mac_window_for(widget);
#if QT_MAC_USE_COCOA
- NSToolbar *toolbar = [wnd toolbar];
- if (toolbar) {
+ if (NSToolbar *toolbar = [wnd toolbar]) {
QMacCocoaAutoReleasePool pool;
if (show != [toolbar isVisible]) {
- [wnd toggleToolbarShown:wnd];
+ [toolbar setVisible:show];
} else {
// The toolbar may be in sync, but we are not, update our framestrut.
qt_widget_private(const_cast<QWidget *>(widget))->updateFrameStrut();
@@ -197,22 +196,21 @@ void macWindowToolbarSet( void * /*OSWindowRef*/ window, void *toolbarRef )
{
OSWindowRef wnd = static_cast<OSWindowRef>(window);
#if QT_MAC_USE_COCOA
- [wnd setToolbar:static_cast<NSToolbar *>(toolbarRef)];
+ [wnd setToolbar:static_cast<NSToolbar *>(toolbarRef)];
#else
SetWindowToolbar(wnd, static_cast<HIToolbarRef>(toolbarRef));
#endif
}
-bool macWindowToolbarVisible( void * /*OSWindowRef*/ window )
+bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window )
{
OSWindowRef wnd = static_cast<OSWindowRef>(window);
#if QT_MAC_USE_COCOA
- NSToolbar *toolbar = [wnd toolbar];
- if (toolbar)
+ if (NSToolbar *toolbar = [wnd toolbar])
return [toolbar isVisible];
return false;
#else
- return IsWindowToolbarVisible(wnd);
+ return IsWindowToolbarVisible(wnd);
#endif
}
@@ -220,12 +218,12 @@ void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow )
{
OSWindowRef wnd = static_cast<OSWindowRef>(window);
#if QT_MAC_USE_COCOA
- [wnd setHasShadow:BOOL(hasShadow)];
+ [wnd setHasShadow:BOOL(hasShadow)];
#else
- if (hasShadow)
- ChangeWindowAttributes(wnd, 0, kWindowNoShadowAttribute);
- else
- ChangeWindowAttributes(wnd, kWindowNoShadowAttribute, 0);
+ if (hasShadow)
+ ChangeWindowAttributes(wnd, 0, kWindowNoShadowAttribute);
+ else
+ ChangeWindowAttributes(wnd, kWindowNoShadowAttribute, 0);
#endif
}
@@ -233,9 +231,9 @@ void macWindowFlush(void * /*OSWindowRef*/ window)
{
OSWindowRef wnd = static_cast<OSWindowRef>(window);
#if QT_MAC_USE_COCOA
- [wnd flushWindowIfNeeded];
+ [wnd flushWindowIfNeeded];
#else
- HIWindowFlush(wnd);
+ HIWindowFlush(wnd);
#endif
}
@@ -352,6 +350,12 @@ Qt::MouseButton qt_mac_get_button(EventMouseButton button)
return Qt::NoButton;
}
+void macSendToolbarChangeEvent(QWidget *widget)
+{
+ QToolBarChangeEvent ev(!(GetCurrentKeyModifiers() & cmdKey));
+ qt_sendSpontaneousEvent(widget, &ev);
+}
+
Q_GLOBAL_STATIC(QMacTabletHash, tablet_hash)
QMacTabletHash *qt_mac_tablet_hash()
{
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
index 3881ccd..5f6204f 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h
+++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
@@ -118,9 +118,10 @@ void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds = 0);
bool macWindowIsTextured(void * /*OSWindowRef*/ window);
void macWindowToolbarShow(const QWidget *widget, bool show );
void macWindowToolbarSet( void * /*OSWindowRef*/ window, void* toolbarRef );
-bool macWindowToolbarVisible( void * /*OSWindowRef*/ window );
+bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window );
void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow );
void macWindowFlush(void * /*OSWindowRef*/ window);
+void macSendToolbarChangeEvent(QWidget *widget);
struct HIContentBorderMetrics;
void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::HIContentBorderMetrics &metrics);
void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm);
diff --git a/src/gui/kernel/qt_mac.cpp b/src/gui/kernel/qt_mac.cpp
index 27df5d1..0c3b707 100644
--- a/src/gui/kernel/qt_mac.cpp
+++ b/src/gui/kernel/qt_mac.cpp
@@ -134,7 +134,7 @@ QColor qcolorForThemeTextColor(ThemeTextColor themeColor)
#ifdef Q_OS_MAC32
RGBColor c;
GetThemeTextColor(themeColor, 32, true, &c);
- QColor color = QColor(c.red / 265, c.green / 256, c.blue / 256);
+ QColor color = QColor(c.red / 256, c.green / 256, c.blue / 256);
return color;
#else
// There is no equivalent to GetThemeTextColor in 64-bit and it was rather bad that
@@ -156,13 +156,13 @@ QColor qcolorForThemeTextColor(ThemeTextColor themeColor)
case kThemeTextColorAlertInactive:
case kThemeTextColorDialogInactive:
case kThemeTextColorPlacardInactive:
- return QColor(67, 69, 69, 255);
+ return QColor(69, 69, 69, 255);
case kThemeTextColorPopupButtonInactive:
case kThemeTextColorPopupLabelInactive:
case kThemeTextColorPushButtonInactive:
case kThemeTextColorTabFrontInactive:
case kThemeTextColorBevelButtonInactive:
- return QColor(123, 127, 127, 255);
+ return QColor(127, 127, 127, 255);
default: {
QNativeImage nativeImage(16,16, QNativeImage::systemFormat());
CGRect cgrect = CGRectMake(0, 0, 16, 16);
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index d1ab45a..c21ebda 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -4541,6 +4541,11 @@ void QWidget::unsetLayoutDirection()
By default, this property contains a cursor with the Qt::ArrowCursor
shape.
+ Some underlying window implementations will reset the cursor if it
+ leaves a widget even if the mouse is grabbed. If you want to have
+ a cursor set for all widgets, even when outside the window, consider
+ QApplication::setOverrideCursor().
+
\sa QApplication::setOverrideCursor()
*/
@@ -9894,11 +9899,8 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
break;
case Qt::WA_InputMethodEnabled: {
QInputContext *ic = d->ic;
- if (!ic) {
- // implicitly create input context only if we have a focus
- if (hasFocus())
- ic = d->inputContext();
- }
+ if (!ic && (!on || hasFocus()))
+ ic = d->inputContext();
if (ic) {
if (on && hasFocus() && ic->focusWidget() != this && isEnabled()) {
ic->setFocusWidget(this);
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index ad16485..5e2dfb6 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -843,8 +843,7 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event,
extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
qt_button_down = 0;
} else if(ekind == kEventWindowToolbarSwitchMode) {
- QToolBarChangeEvent ev(!(GetCurrentKeyModifiers() & cmdKey));
- QApplication::sendSpontaneousEvent(widget, &ev);
+ macSendToolbarChangeEvent(widget);
HIToolbarRef toolbar;
if (GetWindowToolbar(wid, &toolbar) == noErr) {
if (toolbar) {
@@ -1521,12 +1520,16 @@ void QWidgetPrivate::toggleDrawers(bool visible)
*****************************************************************************/
bool QWidgetPrivate::qt_mac_update_sizer(QWidget *w, int up)
{
+ // I'm not sure what "up" is
if(!w || !w->isWindow())
return false;
QTLWExtra *topData = w->d_func()->topData();
QWExtra *extraData = w->d_func()->extraData();
- topData->resizer += up;
+ // topData->resizer is only 4 bits, so subtracting -1 from zero causes bad stuff
+ // to happen, prevent that here (you really want the thing hidden).
+ if (up >= 0 || topData->resizer != 0)
+ topData->resizer += up;
OSWindowRef windowRef = qt_mac_window_for(OSViewRef(w->winId()));
{
#ifndef QT_MAC_USE_COCOA
@@ -1539,7 +1542,6 @@ bool QWidgetPrivate::qt_mac_update_sizer(QWidget *w, int up)
bool remove_grip = (topData->resizer || (w->windowFlags() & Qt::FramelessWindowHint)
|| (extraData->maxw && extraData->maxh &&
extraData->maxw == extraData->minw && extraData->maxh == extraData->minh));
-
#ifndef QT_MAC_USE_COCOA
WindowAttributes attr;
GetWindowAttributes(windowRef, &attr);
diff --git a/src/gui/math3d/qgenericmatrix.h b/src/gui/math3d/qgenericmatrix.h
index 1131f9b..7bdf70a 100644
--- a/src/gui/math3d/qgenericmatrix.h
+++ b/src/gui/math3d/qgenericmatrix.h
@@ -119,7 +119,9 @@ Q_INLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT>::QGenericMatrix()
template <int N, int M, typename T, typename InnerT>
Q_INLINE_TEMPLATE QGenericMatrix<N, M, T, InnerT>::QGenericMatrix(const QGenericMatrix<N, M, T, InnerT>& other)
{
- qMemCopy(m, other.m, sizeof(m));
+ for (int col = 0; col < N; ++col)
+ for (int row = 0; row < M; ++row)
+ m[col][row] = other.m[col][row];
}
template <int N, int M, typename T, typename InnerT>
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp
index b998353..88f58c8 100644
--- a/src/gui/math3d/qmatrix4x4.cpp
+++ b/src/gui/math3d/qmatrix4x4.cpp
@@ -53,10 +53,6 @@ QT_BEGIN_NAMESPACE
\brief The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
\since 4.6
- The matrix elements are stored internally using the most efficient
- numeric representation for the underlying hardware: floating-point
- or fixed-point.
-
\sa QVector3D, QGenericMatrix
*/
@@ -308,8 +304,7 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform)
// The 4x4 matrix inverse algorithm is based on that described at:
// http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q24
// Some optimization has been done to avoid making copies of 3x3
-// sub-matrices, to do calculations in fixed-point where required,
-// and to unroll the loops.
+// sub-matrices and to unroll the loops.
// Calculate the determinant of a 3x3 sub-matrix.
// | A B C |
diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp
index 9988e2b..d9d4160 100644
--- a/src/gui/math3d/qquaternion.cpp
+++ b/src/gui/math3d/qquaternion.cpp
@@ -55,10 +55,6 @@ QT_BEGIN_NAMESPACE
Quaternions are used to represent rotations in 3D space, and
consist of a 3D rotation axis specified by the x, y, and z
coordinates, and a scalar representing the rotation angle.
-
- The components of a quaternion are stored internally using the most
- efficient representation for the GL rendering engine, which will be
- either floating-point or fixed-point.
*/
/*!
diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp
index 9b5d123..b492aa8 100644
--- a/src/gui/math3d/qvector2d.cpp
+++ b/src/gui/math3d/qvector2d.cpp
@@ -57,9 +57,7 @@ QT_BEGIN_NAMESPACE
The QVector2D class can also be used to represent vertices in 2D space.
We therefore do not need to provide a separate vertex class.
- The coordinates are stored internally using the most efficient
- representation for the GL rendering engine, which will be either
- floating-point or fixed-point.
+ \sa QVector3D, QVector4D, QQuaternion
*/
/*!
diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp
index 977152a..95550cd 100644
--- a/src/gui/math3d/qvector3d.cpp
+++ b/src/gui/math3d/qvector3d.cpp
@@ -61,9 +61,7 @@ QT_BEGIN_NAMESPACE
The QVector3D class can also be used to represent vertices in 3D space.
We therefore do not need to provide a separate vertex class.
- The coordinates are stored internally using the most efficient
- representation for the GL rendering engine, which will be either
- floating-point or fixed-point.
+ \sa QVector2D, QVector4D, QQuaternion
*/
/*!
diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp
index a28d2a1..1f7d921 100644
--- a/src/gui/math3d/qvector4d.cpp
+++ b/src/gui/math3d/qvector4d.cpp
@@ -57,10 +57,6 @@ QT_BEGIN_NAMESPACE
The QVector4D class can also be used to represent vertices in 4D space.
We therefore do not need to provide a separate vertex class.
- The coordinates are stored internally using the most efficient
- representation for the GL rendering engine, which will be either
- floating-point or fixed-point.
-
\sa QQuaternion, QVector2D, QVector3D
*/
diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp
index db1a38e..f69562d 100644
--- a/src/gui/text/qsyntaxhighlighter.cpp
+++ b/src/gui/text/qsyntaxhighlighter.cpp
@@ -65,6 +65,18 @@ public:
void _q_reformatBlocks(int from, int charsRemoved, int charsAdded);
void reformatBlock(QTextBlock block);
+
+ inline void rehighlight(QTextCursor &cursor, QTextCursor::MoveOperation operation) {
+ QObject::disconnect(doc, SIGNAL(contentsChange(int,int,int)),
+ q_func(), SLOT(_q_reformatBlocks(int,int,int)));
+ cursor.beginEditBlock();
+ int from = cursor.position();
+ cursor.movePosition(operation);
+ _q_reformatBlocks(from, 0, cursor.position() - from);
+ cursor.endEditBlock();
+ QObject::connect(doc, SIGNAL(contentsChange(int,int,int)),
+ q_func(), SLOT(_q_reformatBlocks(int,int,int)));
+ }
inline void _q_delayedRehighlight() {
if (!rehighlightPending)
@@ -356,6 +368,8 @@ QTextDocument *QSyntaxHighlighter::document() const
\since 4.2
Redoes the highlighting of the whole document.
+
+ \sa rehighlightBlock()
*/
void QSyntaxHighlighter::rehighlight()
{
@@ -363,15 +377,25 @@ void QSyntaxHighlighter::rehighlight()
if (!d->doc)
return;
- disconnect(d->doc, SIGNAL(contentsChange(int,int,int)),
- this, SLOT(_q_reformatBlocks(int,int,int)));
QTextCursor cursor(d->doc);
- cursor.beginEditBlock();
- cursor.movePosition(QTextCursor::End);
- d->_q_reformatBlocks(0, 0, cursor.position());
- cursor.endEditBlock();
- connect(d->doc, SIGNAL(contentsChange(int,int,int)),
- this, SLOT(_q_reformatBlocks(int,int,int)));
+ d->rehighlight(cursor, QTextCursor::End);
+}
+
+/*!
+ \since 4.6
+
+ Redoes the highlighting of the given QTextBlock \a block.
+
+ \sa rehighlight()
+*/
+void QSyntaxHighlighter::rehighlightBlock(const QTextBlock &block)
+{
+ Q_D(QSyntaxHighlighter);
+ if (!d->doc)
+ return;
+
+ QTextCursor cursor(block);
+ d->rehighlight(cursor, QTextCursor::EndOfBlock);
}
/*!
diff --git a/src/gui/text/qsyntaxhighlighter.h b/src/gui/text/qsyntaxhighlighter.h
index 4e5271b..ee249b8 100644
--- a/src/gui/text/qsyntaxhighlighter.h
+++ b/src/gui/text/qsyntaxhighlighter.h
@@ -78,6 +78,7 @@ public:
public Q_SLOTS:
void rehighlight();
+ void rehighlightBlock(const QTextBlock &block);
protected:
virtual void highlightBlock(const QString &text) = 0;
diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h
index 7e0f444..aef8ac5 100644
--- a/src/gui/widgets/qabstractscrollarea_p.h
+++ b/src/gui/widgets/qabstractscrollarea_p.h
@@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE
class QScrollBar;
class QAbstractScrollAreaScrollBarContainer;
-class QAbstractScrollAreaPrivate: public QFramePrivate
+class Q_AUTOTEST_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate
{
Q_DECLARE_PUBLIC(QAbstractScrollArea)
diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp
index da18d13..433406c 100644
--- a/src/gui/widgets/qabstractspinbox.cpp
+++ b/src/gui/widgets/qabstractspinbox.cpp
@@ -1577,7 +1577,7 @@ void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const
option->initFrom(this);
option->activeSubControls = QStyle::SC_None;
option->buttonSymbols = d->buttonSymbols;
- option->subControls = QStyle::SC_SpinBoxFrame;
+ option->subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField;
if (d->buttonSymbols != QAbstractSpinBox::NoButtons) {
option->subControls |= QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown;
if (d->buttonState & Up) {
diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp
index b905ccd..ee29b55 100644
--- a/src/gui/widgets/qdockarealayout.cpp
+++ b/src/gui/widgets/qdockarealayout.cpp
@@ -1707,7 +1707,7 @@ QDockAreaLayoutItem &QDockAreaLayoutInfo::item(const QList<int> &path)
Q_ASSERT(!path.isEmpty());
const int index = path.first();
if (path.count() > 1) {
- const QDockAreaLayoutItem &item = item_list.at(index);
+ const QDockAreaLayoutItem &item = item_list[index];
Q_ASSERT(item.subinfo != 0);
return item.subinfo->item(path.mid(1));
}
diff --git a/src/gui/widgets/qeffects.cpp b/src/gui/widgets/qeffects.cpp
index d6d0a16..f3b1b76 100644
--- a/src/gui/widgets/qeffects.cpp
+++ b/src/gui/widgets/qeffects.cpp
@@ -128,7 +128,8 @@ QAlphaWidget::~QAlphaWidget()
{
#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
// Restore user-defined opacity value
- widget->setWindowOpacity(windowOpacity);
+ if (widget)
+ widget->setWindowOpacity(windowOpacity);
#endif
}
diff --git a/src/gui/widgets/qgroupbox.cpp b/src/gui/widgets/qgroupbox.cpp
index 2380e78..5758b6a 100644
--- a/src/gui/widgets/qgroupbox.cpp
+++ b/src/gui/widgets/qgroupbox.cpp
@@ -478,11 +478,7 @@ void QGroupBox::focusInEvent(QFocusEvent *fe)
if (focusPolicy() == Qt::NoFocus) {
d->_q_fixFocus(fe->reason());
} else {
- QStyleOptionGroupBox box;
- initStyleOption(&box);
- QRect rect = style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this)
- | style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxLabel, this);
- update(rect);
+ QWidget::focusInEvent(fe);
}
}
diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp
index 0c841eb..c51bed9 100644
--- a/src/gui/widgets/qmainwindow.cpp
+++ b/src/gui/widgets/qmainwindow.cpp
@@ -1369,20 +1369,25 @@ bool QMainWindow::event(QEvent *event)
#ifdef Q_WS_MAC
case QEvent::Show:
if (unifiedTitleAndToolBarOnMac())
- macWindowToolbarShow(this, true);
+ d->layout->syncUnifiedToolbarVisibility();
+ d->layout->blockVisiblityCheck = false;
break;
-# ifdef QT_MAC_USE_COCOA
case QEvent::WindowStateChange:
{
+ if (isHidden()) {
+ // We are coming out of a minimize, leave things as is.
+ d->layout->blockVisiblityCheck = true;
+ }
+# ifdef QT_MAC_USE_COCOA
// We need to update the HIToolbar status when we go out of or into fullscreen.
QWindowStateChangeEvent *wce = static_cast<QWindowStateChangeEvent *>(event);
if ((windowState() & Qt::WindowFullScreen) || (wce->oldState() & Qt::WindowFullScreen)) {
d->layout->updateHIToolBarStatus();
}
+# endif // Cocoa
}
break;
-# endif // Cocoa
-#endif
+#endif // Q_WS_MAC
#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR)
case QEvent::CursorChange:
if (d->cursorAdjusted) {
diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp
index aba9120..3936a67 100644
--- a/src/gui/widgets/qmainwindowlayout.cpp
+++ b/src/gui/widgets/qmainwindowlayout.cpp
@@ -939,15 +939,70 @@ void QMainWindowLayout::getStyleOptionInfo(QStyleOptionToolBar *option, QToolBar
void QMainWindowLayout::toggleToolBarsVisible()
{
- layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible;
- if (!layoutState.mainWindow->isMaximized()){
- QPoint topLeft = parentWidget()->geometry().topLeft();
- QRect r = parentWidget()->geometry();
- r = layoutState.toolBarAreaLayout.rectHint(r);
- r.moveTo(topLeft);
- parentWidget()->setGeometry(r);
- } else{
- update();
+ bool updateNonUnifiedParts = true;
+#ifdef Q_WS_MAC
+ if (layoutState.mainWindow->unifiedTitleAndToolBarOnMac()) {
+ // If we hit this case, someone has pressed the "toolbar button" which will
+ // toggle the unified toolbar visiblity, because that's what the user wants.
+ // We might be in a situation where someone has hidden all the toolbars
+ // beforehand (maybe in construction), but now they've hit this button and
+ // and are expecting the items to show. What do we do?
+ // 1) Check the visibility of all the toolbars, if one is visible, do nothing, this
+ // preserves what people would expect (these toolbars were visible when I clicked last time).
+ // 2) If NONE are visible, then show them all. Again, this preserves the user expectation
+ // of, "I want to see the toolbars." The user may get more toolbars than expected, but this
+ // is better seeing nothing.
+ // Don't worry about any of this if we are going invisible. This does mean we may get
+ // into issues when switching into and out of fullscreen mode, but this is probably minor.
+ // If we ever need to do hiding, that would have to be taken care of after the unified toolbar
+ // has finished hiding.
+ // People can of course handle the QEvent::ToolBarChange event themselves and do
+ // WHATEVER they want if they don't like what we are doing (though the unified toolbar
+ // will fire regardless).
+
+ // Check if we REALLY need to update the geometry below. If we only have items in the
+ // unified toolbar, all the docks will be empty, so there's very little point
+ // in doing the geometry as Apple will do it (we also avoid flicker in Cocoa as well).
+ // FWIW, layoutState.toolBarAreaLayout.visible and the state of the unified toolbar
+ // visibility can get out of sync. I really don't think it's a big issue. It is kept
+ // to a minimum because we only change the visibility if we absolutely must.
+ // update the "non unified parts."
+ updateNonUnifiedParts = !layoutState.toolBarAreaLayout.isEmpty();
+
+ // We get this function before the unified toolbar does its thing.
+ // So, the value will be opposite of what we expect.
+ bool goingVisible = !macWindowToolbarIsVisible(qt_mac_window_for(layoutState.mainWindow));
+ if (goingVisible) {
+ const int ToolBarCount = qtoolbarsInUnifiedToolbarList.size();
+ bool needAllVisible = true;
+ for (int i = 0; i < ToolBarCount; ++i) {
+ if (!qtoolbarsInUnifiedToolbarList.at(i)->isHidden()) {
+ needAllVisible = false;
+ break;
+ }
+ }
+ if (needAllVisible) {
+ QBoolBlocker blocker(blockVisiblityCheck); // Disable the visibilty check because
+ // the toggle has already happened.
+ for (int i = 0; i < ToolBarCount; ++i)
+ qtoolbarsInUnifiedToolbarList.at(i)->setVisible(true);
+ }
+ }
+ if (!updateNonUnifiedParts)
+ layoutState.toolBarAreaLayout.visible = goingVisible;
+ }
+#endif
+ if (updateNonUnifiedParts) {
+ layoutState.toolBarAreaLayout.visible = !layoutState.toolBarAreaLayout.visible;
+ if (!layoutState.mainWindow->isMaximized()) {
+ QPoint topLeft = parentWidget()->geometry().topLeft();
+ QRect r = parentWidget()->geometry();
+ r = layoutState.toolBarAreaLayout.rectHint(r);
+ r.moveTo(topLeft);
+ parentWidget()->setGeometry(r);
+ } else {
+ update();
+ }
}
}
@@ -1574,9 +1629,6 @@ void QMainWindowLayout::animationFinished(QWidget *widget)
#ifndef QT_NO_DOCKWIDGET
#ifndef QT_NO_TABBAR
- //it is important to set the current tab before applying the layout
- //so that applyState will not try to counter the result of the animation
- //by putting the item in negative space
if (qobject_cast<QDockWidget*>(widget) != 0) {
// info() might return null if the widget is destroyed while
// animating but before the animationFinished signal is received.
@@ -1586,8 +1638,6 @@ void QMainWindowLayout::animationFinished(QWidget *widget)
#endif
#endif
- applyState(layoutState, false);
-
savedState.clear();
currentGapPos.clear();
pluggingWidget = 0;
@@ -1641,6 +1691,9 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow)
#ifndef QT_NO_RUBBERBAND
, gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow))
#endif //QT_NO_RUBBERBAND
+#ifdef Q_WS_MAC
+ , blockVisiblityCheck(false)
+#endif
{
#ifndef QT_NO_DOCKWIDGET
#ifndef QT_NO_TABBAR
diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm
index 6632be7..61719c2 100644
--- a/src/gui/widgets/qmainwindowlayout_mac.mm
+++ b/src/gui/widgets/qmainwindowlayout_mac.mm
@@ -338,18 +338,16 @@ void QMainWindowLayout::updateHIToolBarStatus()
0, kWindowUnifiedTitleAndToolbarAttribute);
}
#endif
- macWindowToolbarShow(layoutState.mainWindow, useMacToolbar);
layoutState.mainWindow->setUpdatesEnabled(false); // reduces a little bit of flicker, not all though
if (!useMacToolbar) {
- OSWindowRef windowRef = qt_mac_window_for(parentWidget());
- macWindowToolbarShow(parentWidget(), false);
+ macWindowToolbarShow(layoutState.mainWindow, false);
// Move everything out of the HIToolbar into the main toolbar.
while (!qtoolbarsInUnifiedToolbarList.isEmpty()) {
// Should shrink the list by one every time.
layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, qtoolbarsInUnifiedToolbarList.first());
}
- macWindowToolbarSet(windowRef, NULL);
+ macWindowToolbarSet(qt_mac_window_for(layoutState.mainWindow), 0);
} else {
QList<QToolBar *> toolbars = layoutState.mainWindow->findChildren<QToolBar *>();
for (int i = 0; i < toolbars.size(); ++i) {
@@ -359,6 +357,7 @@ void QMainWindowLayout::updateHIToolBarStatus()
layoutState.mainWindow->addToolBar(Qt::TopToolBarArea, toolbar);
}
}
+ syncUnifiedToolbarVisibility();
}
layoutState.mainWindow->setUpdatesEnabled(true);
}
@@ -439,7 +438,7 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar
#else
NSString *toolbarID = kQToolBarNSToolbarIdentifier;
toolbarID = [toolbarID stringByAppendingFormat:@"%p", toolbar];
- cocoaItemIDToToolbarHash.insert(QCFString::toQString(CFStringRef(toolbarID)), toolbar);
+ cocoaItemIDToToolbarHash.insert(qt_mac_NSStringToQString(toolbarID), toolbar);
[macToolbar insertItemWithItemIdentifier:toolbarID atIndex:beforeIndex];
#endif
}
@@ -487,6 +486,7 @@ void QMainWindowLayout::cleanUpMacToolbarItems()
void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const
{
+#ifdef QT_MAC_USE_COCOA
QHash<void *, QToolBar *>::const_iterator it = unifiedToolbarHash.constBegin();
NSToolbarItem *item = nil;
while (it != unifiedToolbarHash.constEnd()) {
@@ -507,5 +507,26 @@ void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const
nssize.height = size.height() - 2;
[item setMinSize:nssize];
}
+#else
+ Q_UNUSED(tb);
+#endif
}
+
+void QMainWindowLayout::syncUnifiedToolbarVisibility()
+{
+ if (blockVisiblityCheck)
+ return;
+
+ Q_ASSERT(layoutState.mainWindow->unifiedTitleAndToolBarOnMac());
+ bool show = false;
+ const int ToolBarCount = qtoolbarsInUnifiedToolbarList.count();
+ for (int i = 0; i < ToolBarCount; ++i) {
+ if (qtoolbarsInUnifiedToolbarList.at(i)->isVisible()) {
+ show = true;
+ break;
+ }
+ }
+ macWindowToolbarShow(layoutState.mainWindow, show);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h
index 45f62cd..524fdbf 100644
--- a/src/gui/widgets/qmainwindowlayout_p.h
+++ b/src/gui/widgets/qmainwindowlayout_p.h
@@ -335,6 +335,8 @@ public:
void cleanUpMacToolbarItems();
void fixSizeInUnifiedToolbar(QToolBar *tb) const;
bool useHIToolBar;
+ void syncUnifiedToolbarVisibility();
+ bool blockVisiblityCheck;
#endif
};
QT_END_NAMESPACE
diff --git a/src/gui/widgets/qprogressbar.cpp b/src/gui/widgets/qprogressbar.cpp
index ac3338b..d168028 100644
--- a/src/gui/widgets/qprogressbar.cpp
+++ b/src/gui/widgets/qprogressbar.cpp
@@ -204,7 +204,7 @@ bool QProgressBarPrivate::repaintRequired() const
\o A progress bar shown in the Plastique widget style.
\endtable
- \sa QTimeLine, QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator}
+ \sa QProgressDialog, {fowler}{GUI Design Handbook: Progress Indicator}
*/
/*!
diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp
index e069a21..3933272 100644
--- a/src/gui/widgets/qspinbox.cpp
+++ b/src/gui/widgets/qspinbox.cpp
@@ -50,6 +50,7 @@
#include <qdebug.h>
#include <math.h>
+#include <float.h>
QT_BEGIN_NAMESPACE
@@ -823,8 +824,8 @@ void QDoubleSpinBox::setRange(double minimum, double maximum)
Sets how many decimals the spinbox will use for displaying and
interpreting doubles.
- \warning The results might not be reliable with very high values
- for \a decimals.
+ \warning The maximum value for \a decimals is DBL_MAX_10_EXP +
+ DBL_DIG (ie. 323) because of the limitations of the double type.
Note: The maximum, minimum and value might change as a result of
changing this property.
@@ -840,7 +841,7 @@ int QDoubleSpinBox::decimals() const
void QDoubleSpinBox::setDecimals(int decimals)
{
Q_D(QDoubleSpinBox);
- d->decimals = qMax(0, decimals);
+ d->decimals = qBound(0, decimals, DBL_MAX_10_EXP + DBL_DIG);
setRange(minimum(), maximum()); // make sure values are rounded
setValue(value());
diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp
index 11cb6a1..690e624 100644
--- a/src/gui/widgets/qtabbar.cpp
+++ b/src/gui/widgets/qtabbar.cpp
@@ -663,7 +663,7 @@ void QTabBarPrivate::refresh()
if (pressedIndex != -1
&& movable
&& QApplication::mouseButtons() == Qt::NoButton) {
- _q_moveTabFinished(pressedIndex);
+ moveTabFinished(pressedIndex);
if (!validIndex(pressedIndex))
pressedIndex = -1;
}
@@ -1662,26 +1662,17 @@ void QTabBarPrivate::slide(int from, int to)
q->setUpdatesEnabled(true);
int postLocation = vertical ? q->tabRect(to).y() : q->tabRect(to).x();
int length = postLocation - preLocation;
- tabList[to].makeTimeLine(q);
- tabList[to].dragOffset += -1 * length;
- tabList[to].timeLine->setFrameRange(tabList[to].dragOffset, 0);
- animations[tabList[to].timeLine] = to;
- tabList[to].timeLine->setDuration(ANIMATION_DURATION);
- if (tabList[to].timeLine->state() != QTimeLine::Running)
- tabList[to].timeLine->start();
+ tabList[to].dragOffset -= length;
+ tabList[to].startAnimation(this, ANIMATION_DURATION);
}
-void QTabBarPrivate::_q_moveTab(int offset)
+void QTabBarPrivate::moveTab(int index, int offset)
{
- Q_Q(QTabBar);
- if (QTimeLine *timeLine = qobject_cast<QTimeLine *>(q->sender())) {
- int index = animations[timeLine];
- if (!validIndex(index))
- return;
- tabList[index].dragOffset = offset;
- layoutTab(index); // Make buttons follow tab
- q->update();
- }
+ if (!validIndex(index))
+ return;
+ tabList[index].dragOffset = offset;
+ layoutTab(index); // Make buttons follow tab
+ q_func()->update();
}
/*!\reimp
@@ -1695,7 +1686,7 @@ void QTabBar::mousePressEvent(QMouseEvent *event)
}
// Be safe!
if (d->pressedIndex != -1 && d->movable)
- d->_q_moveTabFinished(d->pressedIndex);
+ d->moveTabFinished(d->pressedIndex);
d->pressedIndex = d->indexAtPos(event->pos());
if (d->validIndex(d->pressedIndex)) {
@@ -1721,7 +1712,7 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event)
// Be safe!
if (d->pressedIndex != -1
&& event->buttons() == Qt::NoButton)
- d->_q_moveTabFinished(d->pressedIndex);
+ d->moveTabFinished(d->pressedIndex);
// Start drag
if (!d->dragInProgress && d->pressedIndex != -1) {
@@ -1789,16 +1780,6 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event)
optTabBase.documentMode = d->documentMode;
}
-void QTabBarPrivate::_q_moveTabFinished()
-{
- Q_Q(QTabBar);
- if (QTimeLine *timeLine = qobject_cast<QTimeLine *>(q->sender())) {
- int index = animations[timeLine];
- animations.remove(timeLine);
- _q_moveTabFinished(index);
- }
-}
-
void QTabBarPrivate::setupMovableTab()
{
Q_Q(QTabBar);
@@ -1838,11 +1819,19 @@ void QTabBarPrivate::setupMovableTab()
movingTab->setVisible(true);
}
-void QTabBarPrivate::_q_moveTabFinished(int index)
+void QTabBarPrivate::moveTabFinished(int index)
{
Q_Q(QTabBar);
bool cleanup = (pressedIndex == index) || (pressedIndex == -1) || !validIndex(index);
- if (animations.isEmpty() && cleanup) {
+ bool allAnimationsFinished = true;
+#ifndef QT_NO_ANIMATION
+ for(int i = 0; allAnimationsFinished && i < tabList.count(); ++i) {
+ const Tab &t = tabList.at(i);
+ if (t.animation && t.animation->state() == QAbstractAnimation::Running)
+ allAnimationsFinished = false;
+ }
+#endif //QT_NO_ANIMATION
+ if (allAnimationsFinished && cleanup) {
movingTab->setVisible(false); // We might not get a mouse release
for (int i = 0; i < tabList.count(); ++i) {
tabList[i].dragOffset = 0;
@@ -1877,17 +1866,8 @@ void QTabBar::mouseReleaseEvent(QMouseEvent *event)
? tabRect(d->pressedIndex).height()
: tabRect(d->pressedIndex).width();
int duration = qMin(ANIMATION_DURATION,
- ((length < 0 ? (-1 * length) : length) * ANIMATION_DURATION) / width);
- if (duration > 0) {
- d->tabList[d->pressedIndex].makeTimeLine(this);
- d->tabList[d->pressedIndex].timeLine->setFrameRange(length, 0);
- d->animations[d->tabList[d->pressedIndex].timeLine] = d->pressedIndex;
- d->tabList[d->pressedIndex].timeLine->setDuration(duration);
- if (d->tabList[d->pressedIndex].timeLine->state() != QTimeLine::Running)
- d->tabList[d->pressedIndex].timeLine->start();
- } else {
- d->_q_moveTabFinished(d->pressedIndex);
- }
+ (qAbs(length) * ANIMATION_DURATION) / width);
+ d->tabList[d->pressedIndex].startAnimation(d, duration);
d->dragInProgress = false;
d->movingTab->setVisible(false);
d->dragStartPosition = QPoint();
diff --git a/src/gui/widgets/qtabbar.h b/src/gui/widgets/qtabbar.h
index 7514486..402f54b 100644
--- a/src/gui/widgets/qtabbar.h
+++ b/src/gui/widgets/qtabbar.h
@@ -215,8 +215,6 @@ private:
Q_DECLARE_PRIVATE(QTabBar)
Q_PRIVATE_SLOT(d_func(), void _q_scrollTabs())
Q_PRIVATE_SLOT(d_func(), void _q_closeTab())
- Q_PRIVATE_SLOT(d_func(), void _q_moveTab(int))
- Q_PRIVATE_SLOT(d_func(), void _q_moveTabFinished())
};
#endif // QT_NO_TABBAR
diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h
index dbae055..b9b9fba 100644
--- a/src/gui/widgets/qtabbar_p.h
+++ b/src/gui/widgets/qtabbar_p.h
@@ -58,9 +58,8 @@
#include <qicon.h>
#include <qtoolbutton.h>
-#include <qtimeline.h>
-#include <qhash.h>
#include <qdebug.h>
+#include <qvariantanimation.h>
#ifndef QT_NO_TABBAR
@@ -75,9 +74,10 @@ class QTabBarPrivate : public QWidgetPrivate
Q_DECLARE_PUBLIC(QTabBar)
public:
QTabBarPrivate()
- :currentIndex(-1), pressedIndex(-1),
- shape(QTabBar::RoundedNorth),
- layoutDirty(false), drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false), movingTab(0) {}
+ :currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), layoutDirty(false),
+ drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false),
+ selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false),
+ dragInProgress(false), documentMode(false), movingTab(0) {}
int currentIndex;
int pressedIndex;
@@ -88,16 +88,13 @@ public:
struct Tab {
inline Tab(const QIcon &ico, const QString &txt)
- : enabled(true)
- , shortcutId(0)
- , text(txt)
- , icon(ico)
- , leftWidget(0)
- , rightWidget(0)
- , lastTab(-1)
- , timeLine(0)
- , dragOffset(0)
+ : enabled(true) , shortcutId(0), text(txt), icon(ico),
+ leftWidget(0), rightWidget(0), lastTab(-1), dragOffset(0)
+#ifndef QT_NO_ANIMATION
+ , animation(0)
+#endif //QT_NO_ANIMATION
{}
+ bool operator==(const Tab &other) const { return &other == this; }
bool enabled;
int shortcutId;
QString text;
@@ -117,21 +114,39 @@ public:
QWidget *leftWidget;
QWidget *rightWidget;
int lastTab;
-
- QTimeLine *timeLine;
int dragOffset;
- void makeTimeLine(QWidget *q) {
- if (timeLine)
- return;
- timeLine = new QTimeLine(ANIMATION_DURATION, q);
- q->connect(timeLine, SIGNAL(frameChanged(int)), q, SLOT(_q_moveTab(int)));
- q->connect(timeLine, SIGNAL(finished()), q, SLOT(_q_moveTabFinished()));
+#ifndef QT_NO_ANIMATION
+ ~Tab() { delete animation; }
+ struct TabBarAnimation : public QVariantAnimation {
+ TabBarAnimation(Tab *t, QTabBarPrivate *_priv) : tab(t), priv(_priv)
+ { setEasingCurve(QEasingCurve::InOutQuad); }
+
+ void updateCurrentValue(const QVariant &current)
+ { priv->moveTab(priv->tabList.indexOf(*tab), current.toInt()); }
+
+ void updateState(State, State newState)
+ { if (newState == Stopped) priv->moveTabFinished(priv->tabList.indexOf(*tab)); }
+ private:
+ //these are needed for the callbacks
+ Tab *tab;
+ QTabBarPrivate *priv;
+ } *animation;
+
+ void startAnimation(QTabBarPrivate *priv, int duration) {
+ if (!animation)
+ animation = new TabBarAnimation(this, priv);
+ animation->setStartValue(dragOffset);
+ animation->setEndValue(0);
+ animation->setDuration(duration);
+ animation->start();
}
-
+#else
+ void startAnimation(QTabBarPrivate *priv, int duration)
+ { Q_UNUSED(duration); priv->moveTabFinished(priv->tabList.indexOf(*this)); }
+#endif //QT_NO_ANIMATION
};
QList<Tab> tabList;
- QHash<QTimeLine*, int> animations;
int calculateNewPosition(int from, int to, int index) const;
void slide(int from, int to);
@@ -152,9 +167,8 @@ public:
void _q_scrollTabs();
void _q_closeTab();
- void _q_moveTab(int);
- void _q_moveTabFinished();
- void _q_moveTabFinished(int offset);
+ void moveTab(int index, int offset);
+ void moveTabFinished(int index);
QRect hoverRect;
void refresh();
diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp
index b249915..b65f1ba 100644
--- a/src/gui/widgets/qtoolbar.cpp
+++ b/src/gui/widgets/qtoolbar.cpp
@@ -1074,6 +1074,15 @@ static bool waitForPopup(QToolBar *tb, QWidget *popup)
return false;
}
+#if defined(Q_WS_MAC)
+static bool toolbarInUnifiedToolBar(QToolBar *toolbar)
+{
+ const QMainWindow *mainWindow = qobject_cast<const QMainWindow *>(toolbar->parentWidget());
+ return mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()
+ && mainWindow->toolBarArea(toolbar) == Qt::TopToolBarArea;
+}
+#endif
+
/*! \reimp */
bool QToolBar::event(QEvent *event)
{
@@ -1096,7 +1105,15 @@ bool QToolBar::event(QEvent *event)
// fallthrough intended
case QEvent::Show:
d->toggleViewAction->setChecked(event->type() == QEvent::Show);
-#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
+#if defined(Q_WS_MAC)
+ if (toolbarInUnifiedToolBar(this)) {
+ // I can static_cast because I did the qobject_cast in the if above, therefore
+ // we must have a QMainWindowLayout here.
+ QMainWindowLayout *mwLayout = static_cast<QMainWindowLayout *>(parentWidget()->layout());
+ mwLayout->fixSizeInUnifiedToolbar(this);
+ mwLayout->syncUnifiedToolbarVisibility();
+ }
+# if !defined(QT_MAC_USE_COCOA)
// Fall through
case QEvent::LayoutRequest: {
// There's currently no way to invalidate the size and let
@@ -1111,10 +1128,9 @@ bool QToolBar::event(QEvent *event)
}
if (needUpdate) {
- OSWindowRef windowRef = qt_mac_window_for(this);
- if (mainWindow->unifiedTitleAndToolBarOnMac()
- && mainWindow->toolBarArea(this) == Qt::TopToolBarArea
- && macWindowToolbarVisible(windowRef)) {
+ OSWindowRef windowRef = qt_mac_window_for(mainWindow);
+ if (toolbarInUnifiedToolBar(this)
+ && macWindowToolbarIsVisible(windowRef)) {
DisableScreenUpdates();
macWindowToolbarShow(this, false);
macWindowToolbarShow(this, true);
@@ -1126,7 +1142,8 @@ bool QToolBar::event(QEvent *event)
return earlyResult;
}
}
-#endif
+# endif // !QT_MAC_USE_COCOA
+#endif // Q_WS_MAC
break;
case QEvent::ParentChange:
d->layout->checkUsePopupMenu();
diff --git a/src/gui/widgets/qwidgetanimator.cpp b/src/gui/widgets/qwidgetanimator.cpp
index 26cf905..1a93b51 100644
--- a/src/gui/widgets/qwidgetanimator.cpp
+++ b/src/gui/widgets/qwidgetanimator.cpp
@@ -100,7 +100,6 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo
m_animation_map[widget] = anim;
connect(anim, SIGNAL(finished()), SLOT(animationFinished()));
anim->start(QPropertyAnimation::DeleteWhenStopped);
- Q_ASSERT(animate || widget->geometry() == final_geometry);
#else
//we do it in one shot
widget->setGeometry(final_geometry);
diff --git a/src/gui/widgets/qwidgetanimator_p.h b/src/gui/widgets/qwidgetanimator_p.h
index 64697a9..5a3e39d 100644
--- a/src/gui/widgets/qwidgetanimator_p.h
+++ b/src/gui/widgets/qwidgetanimator_p.h
@@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE
class QWidget;
class QMainWindowLayout;
class QPropertyAnimation;
+class QRect;
class QWidgetAnimator : public QObject
{
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index 483589b..7a616aa 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -201,6 +201,7 @@ bool QHttpNetworkReply::isFinished() const
QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl)
: QHttpNetworkHeaderPrivate(newUrl), state(NothingDoneState), statusCode(100),
majorVersion(0), minorVersion(0), bodyLength(0), contentRead(0), totalProgress(0),
+ chunkedTransferEncoding(0),
currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false),
autoDecompress(false), responseData(0), requestIsPrepared(false)
{
@@ -506,6 +507,9 @@ qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket)
state = ReadingDataState;
fragment.clear(); // next fragment
bodyLength = contentLength(); // cache the length
+
+ // cache isChunked() since it is called often
+ chunkedTransferEncoding = headerField("transfer-encoding").toLower().contains("chunked");
}
return bytes;
}
@@ -546,7 +550,7 @@ void QHttpNetworkReplyPrivate::parseHeader(const QByteArray &header)
bool QHttpNetworkReplyPrivate::isChunked()
{
- return headerField("transfer-encoding").toLower().contains("chunked");
+ return chunkedTransferEncoding;
}
bool QHttpNetworkReplyPrivate::connectionCloseEnabled()
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index b86cfaa..5eb70ce 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -198,6 +198,7 @@ public:
qint64 contentRead;
qint64 totalProgress;
QByteArray fragment; // used for header, status, chunk header etc, not for reply data
+ bool chunkedTransferEncoding;
qint64 currentChunkSize;
qint64 currentChunkRead;
QPointer<QHttpNetworkConnection> connection;
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index de39970..28319bb 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -461,8 +461,8 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data)
void QNetworkReplyImplPrivate::finished()
{
Q_Q(QNetworkReplyImpl);
- Q_ASSERT_X(state != Finished, "QNetworkReplyImpl",
- "Backend called finished/finishedWithError more than once");
+ if (state == Finished || state == Aborted)
+ return;
state = Finished;
pendingNotifications.clear();
diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp
index 1d968c2..608db65 100644
--- a/src/network/kernel/qnetworkproxy.cpp
+++ b/src/network/kernel/qnetworkproxy.cpp
@@ -366,7 +366,7 @@ static QNetworkProxy::Capabilities defaultCapabilitiesForType(QNetworkProxy::Pro
int(QNetworkProxy::HostNameLookupCapability)),
};
- if (int(type) < 0 && int(type) > int(QNetworkProxy::FtpCachingProxy))
+ if (int(type) < 0 || int(type) > int(QNetworkProxy::FtpCachingProxy))
type = QNetworkProxy::DefaultProxy;
return QNetworkProxy::Capabilities(defaults[int(type)]);
}
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index 1a971f0..794b2b7 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -168,7 +168,7 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
// we have a valid handle
d->serverName = name;
- if (setSocketDescriptor((quintptr)localSocket), openMode) {
+ if (setSocketDescriptor((quintptr)localSocket, ConnectedState, openMode)) {
d->handle = localSocket;
emit connected();
}
@@ -299,8 +299,6 @@ void QLocalSocket::abort()
DWORD QLocalSocketPrivate::bytesAvailable()
{
Q_Q(QLocalSocket);
- if (q->state() != QLocalSocket::ConnectedState)
- return 0;
DWORD bytes;
if (PeekNamedPipe(handle, NULL, 0, NULL, &bytes, NULL)) {
return bytes;
@@ -410,7 +408,7 @@ bool QLocalSocket::setSocketDescriptor(quintptr socketDescriptor,
d->handle = (int*)socketDescriptor;
d->state = socketState;
emit stateChanged(d->state);
- if (d->state == ConnectedState) {
+ if (d->state == ConnectedState && openMode.testFlag(QIODevice::ReadOnly)) {
d->startAsyncRead();
d->checkReadyRead();
}
@@ -471,6 +469,10 @@ bool QLocalSocket::waitForDisconnected(int msecs)
Q_D(QLocalSocket);
if (state() == UnconnectedState)
return false;
+ if (!openMode().testFlag(QIODevice::ReadOnly)) {
+ qWarning("QLocalSocket::waitForDisconnected isn't supported for write only pipes.");
+ return false;
+ }
QIncrementalSleepTimer timer(msecs);
forever {
d->bytesAvailable(); // to check if PeekNamedPipe fails
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
index 096bf40..4928b67 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
@@ -81,7 +81,7 @@ template <> inline const bool* ptr<bool>(const bool &) { return 0; }
template <typename device, typename T1, typename T2, typename T3>
static void rasterFallbackWarn(const char *msg, const char *func, const device *dev,
int scale, bool matrixRotShear, bool simplePen,
- bool dfbHandledClip,
+ bool dfbHandledClip, bool unsupportedCompositionMode,
const char *nameOne, const T1 &one,
const char *nameTwo, const T2 &two,
const char *nameThree, const T3 &three)
@@ -98,7 +98,8 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device *
dbg << "scale" << scale
<< "matrixRotShear" << matrixRotShear
<< "simplePen" << simplePen
- << "dfbHandledClip" << dfbHandledClip;
+ << "dfbHandledClip" << dfbHandledClip
+ << "unsupportedCompositionMode" << unsupportedCompositionMode;
const T1 *t1 = ptr(one);
const T2 *t2 = ptr(two);
@@ -124,6 +125,7 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device *
__FUNCTION__, state()->painter->device(), \
d_func()->scale, d_func()->matrixRotShear, \
d_func()->simplePen, d_func()->dfbCanHandleClip(), \
+ d_func()->unsupportedCompositionMode, \
#one, one, #two, two, #three, three); \
if (op & (QT_DIRECTFB_DISABLE_RASTERFALLBACKS)) \
return;
@@ -138,6 +140,7 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device *
__FUNCTION__, state()->painter->device(), \
d_func()->scale, d_func()->matrixRotShear, \
d_func()->simplePen, d_func()->dfbCanHandleClip(), \
+ d_func()->unsupportedCompositionMode, \
#one, one, #two, two, #three, three);
#else
#define RASTERFALLBACK(op, one, two, three)
@@ -238,7 +241,7 @@ public:
void fillRects(const QRectF *rects, int count);
void drawRects(const QRectF *rects, int count);
- void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap);
+ void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos);
void blit(const QRectF &dest, IDirectFBSurface *surface, const QRectF &src);
inline void updateClip();
@@ -281,6 +284,7 @@ private:
bool unsupportedCompositionMode;
QDirectFBPaintEngine *q;
+ QRect currentClip;
friend class QDirectFBPaintEngine;
};
@@ -340,6 +344,7 @@ bool QDirectFBPaintEngine::end()
#if (Q_DIRECTFB_VERSION >= 0x010000)
d->surface->ReleaseSource(d->surface);
#endif
+ d->currentClip = QRect();
d->surface->SetClip(d->surface, NULL);
d->surface = 0;
return QRasterPaintEngine::end();
@@ -610,30 +615,26 @@ void QDirectFBPaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm)
void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r,
const QPixmap &pixmap,
- const QPointF &sp)
+ const QPointF &offset)
{
Q_D(QDirectFBPaintEngine);
d->updateClip();
if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) {
- RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), sp);
+ RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset);
d->lock();
- QRasterPaintEngine::drawTiledPixmap(r, pixmap, sp);
- } else if (d->unsupportedCompositionMode || !d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()
+ QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset);
+ } else if (d->unsupportedCompositionMode || !d->dfbCanHandleClip(r) || d->matrixRotShear
|| d->scale == QDirectFBPaintEnginePrivate::NegativeScale) {
- RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), sp);
+ RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset);
const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer(DSLF_READ);
d->lock();
QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType);
data->fromImage(*img, Qt::AutoColor);
const QPixmap pix(data);
- QRasterPaintEngine::drawTiledPixmap(r, pix, sp);
+ QRasterPaintEngine::drawTiledPixmap(r, pix, offset);
} else {
d->unlock();
- QPixmapData *data = pixmap.pixmapData();
- Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
- QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
- dfbData->unlockDirectFB();
- d->drawTiledPixmap(r, pixmap);
+ d->drawTiledPixmap(r, pixmap, offset);
}
}
@@ -730,14 +731,17 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
d->surface->FillRectangle(d->surface, r.x(), r.y(),
r.width(), r.height());
return; }
- case Qt::TexturePattern:
- if (state()->brushOrigin == QPointF() && brush.transform().isIdentity()) {
- //could handle certain types of brush.transform() E.g. scale
- d->unlock();
- d->drawTiledPixmap(rect, brush.texture());
- return;
- }
- break;
+ case Qt::TexturePattern: {
+ if (d->scale == QDirectFBPaintEnginePrivate::NegativeScale)
+ break;
+
+ const QPixmap texture = brush.texture();
+ if (texture.pixmapData()->classId() != QPixmapData::DirectFBClass)
+ break;
+
+ d->unlock();
+ d->drawTiledPixmap(rect, texture, rect.topLeft() - state()->brushOrigin);
+ return; }
default:
break;
}
@@ -1059,6 +1063,8 @@ void QDirectFBPaintEnginePrivate::blit(const QRectF &dest, IDirectFBSurface *s,
{
const QRect sr = src.toRect();
const QRect dr = transform.mapRect(dest).toRect();
+ if (dr.isEmpty())
+ return;
const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() };
DFBResult result;
@@ -1072,55 +1078,105 @@ void QDirectFBPaintEnginePrivate::blit(const QRectF &dest, IDirectFBSurface *s,
DirectFBError("QDirectFBPaintEngine::drawPixmap()", result);
}
-void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest,
- const QPixmap &pixmap)
+static inline qreal fixCoord(qreal rect_pos, qreal pixmapSize, qreal offset)
{
+ qreal pos = rect_pos - offset;
+ while (pos > rect_pos)
+ pos -= pixmapSize;
+ while (pos + pixmapSize < rect_pos)
+ pos += pixmapSize;
+ return pos;
+}
+
+void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &off)
+{
+ Q_ASSERT(!dirtyClip);
+ const QRect destinationRect = transform.mapRect(dest).toRect().normalized();
+ QRect newClip = destinationRect;
+ if (!currentClip.isEmpty())
+ newClip &= currentClip;
+
+ if (newClip.isNull())
+ return;
+
+ const DFBRegion clip = {
+ newClip.x(),
+ newClip.y(),
+ newClip.x() + newClip.width() - 1,
+ newClip.y() + newClip.height() - 1
+ };
+ surface->SetClip(surface, &clip);
+
+ QPointF offset = off;
+ Q_ASSERT(transform.type() <= QTransform::TxScale);
prepareForBlit(pixmap.hasAlphaChannel());
QPixmapData *data = pixmap.pixmapData();
Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
- IDirectFBSurface *s = dfbData->directFBSurface();
- const QRect dr = transform.mapRect(dest).toRect();
- DFBResult result = DFB_OK;
-
- if (scale == NoScale && dr == QRect(0, 0, fbWidth, fbHeight)) {
- result = surface->TileBlit(surface, s, 0, 0, 0);
- } else if (scale == NoScale) {
- const int dx = pixmap.width();
- const int dy = pixmap.height();
- const DFBRectangle rect = { 0, 0, dx, dy };
- QVarLengthArray<DFBRectangle> rects;
- QVarLengthArray<DFBPoint> points;
-
- for (int y = dr.y(); y <= dr.bottom(); y += dy) {
- for (int x = dr.x(); x <= dr.right(); x += dx) {
- rects.append(rect);
- const DFBPoint point = { x, y };
- points.append(point);
+ dfbData->unlockDirectFB();
+ const QSize pixmapSize = dfbData->size();
+ IDirectFBSurface *sourceSurface = dfbData->directFBSurface();
+ if (transform.isScaling()) {
+ Q_ASSERT(qMin(transform.m11(), transform.m22()) >= 0);
+ offset.rx() *= transform.m11();
+ offset.ry() *= transform.m22();
+
+ const QSizeF mappedSize(pixmapSize.width() * transform.m11(), pixmapSize.height() * transform.m22());
+ qreal y = ::fixCoord(destinationRect.y(), mappedSize.height(), offset.y());
+ const qreal startX = ::fixCoord(destinationRect.x(), mappedSize.width(), offset.x());
+ while (y < destinationRect.bottom()) {
+ qreal x = startX;
+ while (x < destinationRect.right()) {
+ const DFBRectangle destination = { qRound(x), qRound(y), mappedSize.width(), mappedSize.height() };
+ surface->StretchBlit(surface, sourceSurface, 0, &destination);
+ x += mappedSize.width();
}
+ y += mappedSize.height();
}
- result = surface->BatchBlit(surface, s, rects.constData(),
- points.constData(), points.size());
} else {
- const QRect sr = transform.mapRect(QRect(0, 0, pixmap.width(), pixmap.height()));
- const int dx = sr.width();
- const int dy = sr.height();
- const DFBRectangle sRect = { 0, 0, dx, dy };
-
- for (int y = dr.y(); y <= dr.bottom(); y += dy) {
- for (int x = dr.x(); x <= dr.right(); x += dx) {
- const DFBRectangle dRect = { x, y, dx, dy };
- result = surface->StretchBlit(surface, s, &sRect, &dRect);
- if (result != DFB_OK) {
- y = dr.bottom() + 1;
- break;
- }
+ qreal y = ::fixCoord(destinationRect.y(), pixmapSize.height(), offset.y());
+ const qreal startX = ::fixCoord(destinationRect.x(), pixmapSize.width(), offset.x());
+ int horizontal = qMax(1, destinationRect.width() / pixmapSize.width()) + 1;
+ if (startX != destinationRect.x())
+ ++horizontal;
+ int vertical = qMax(1, destinationRect.height() / pixmapSize.height()) + 1;
+ if (y != destinationRect.y())
+ ++vertical;
+
+ const int maxCount = (vertical * horizontal);
+ QVarLengthArray<DFBRectangle, 16> sourceRects(maxCount);
+ QVarLengthArray<DFBPoint, 16> points(maxCount);
+
+ int i = 0;
+ while (y < destinationRect.bottom()) {
+ Q_ASSERT(i < maxCount);
+ qreal x = startX;
+ while (x < destinationRect.right()) {
+ points[i].x = qRound(x);
+ points[i].y = qRound(y);
+ sourceRects[i].x = 0;
+ sourceRects[i].y = 0;
+ sourceRects[i].w = int(pixmapSize.width());
+ sourceRects[i].h = int(pixmapSize.height());
+ x += pixmapSize.width();
+ ++i;
}
+ y += pixmapSize.height();
}
+ surface->BatchBlit(surface, sourceSurface, sourceRects.constData(), points.constData(), i);
}
- if (result != DFB_OK)
- DirectFBError("QDirectFBPaintEngine::drawTiledPixmap()", result);
+ if (currentClip.isEmpty()) {
+ surface->SetClip(surface, 0);
+ } else {
+ const DFBRegion clip = {
+ currentClip.x(),
+ currentClip.y(),
+ currentClip.x() + currentClip.width(),
+ currentClip.y() + currentClip.height()
+ };
+ surface->SetClip(surface, &clip);
+ }
}
void QDirectFBPaintEnginePrivate::updateClip()
@@ -1128,6 +1184,7 @@ void QDirectFBPaintEnginePrivate::updateClip()
if (!dirtyClip)
return;
+ currentClip = QRect();
const QClipData *clipData = clip();
if (!clipData || !clipData->enabled) {
surface->SetClip(surface, NULL);
@@ -1140,6 +1197,8 @@ void QDirectFBPaintEnginePrivate::updateClip()
clipData->clipRect.y() + clipData->clipRect.height()
};
surface->SetClip(surface, &r);
+ currentClip = clipData->clipRect.normalized();
+ // ### is this guaranteed to always be normalized?
dfbHandledClip = true;
} else if (clipData->hasRegionClip && ignoreSystemClip && clipData->clipRegion == systemClip) {
dfbHandledClip = true;
diff --git a/src/plugins/kbddrivers/sl5000/main.cpp b/src/plugins/kbddrivers/sl5000/main.cpp
index 4d61266..cc68747 100644
--- a/src/plugins/kbddrivers/sl5000/main.cpp
+++ b/src/plugins/kbddrivers/sl5000/main.cpp
@@ -66,10 +66,9 @@ QStringList QSL5000KbdDriver::keys() const
QWSKeyboardHandler* QSL5000KbdDriver::create(const QString &driver,
const QString &device)
{
- Q_UNUSED(device);
if (driver.compare(QLatin1String("SL5000"), Qt::CaseInsensitive))
return 0;
- return new QWSSL5000KeyboardHandler(driver);
+ return new QWSSL5000KeyboardHandler(device);
}
Q_EXPORT_PLUGIN2(qwssl5000kbddriver, QSL5000KbdDriver)
diff --git a/src/plugins/kbddrivers/vr41xx/main.cpp b/src/plugins/kbddrivers/vr41xx/main.cpp
index 2cba1f7..c9ba4d7 100644
--- a/src/plugins/kbddrivers/vr41xx/main.cpp
+++ b/src/plugins/kbddrivers/vr41xx/main.cpp
@@ -66,10 +66,9 @@ QStringList QVr41xxKbdDriver::keys() const
QWSKeyboardHandler* QVr41xxKbdDriver::create(const QString &driver,
const QString &device)
{
- Q_UNUSED(device);
if (driver.compare(QLatin1String("VR41xx"), Qt::CaseInsensitive))
return 0;
- return new QWSVr41xxKeyboardHandler(driver);
+ return new QWSVr41xxKeyboardHandler(device);
}
Q_EXPORT_PLUGIN2(qwsvr41xxkbddriver, QVr41xxKbdDriver)
diff --git a/src/plugins/kbddrivers/yopy/main.cpp b/src/plugins/kbddrivers/yopy/main.cpp
index bfddabe..7079d88 100644
--- a/src/plugins/kbddrivers/yopy/main.cpp
+++ b/src/plugins/kbddrivers/yopy/main.cpp
@@ -66,10 +66,9 @@ QStringList QYopyKbdDriver::keys() const
QWSKeyboardHandler* QYopyKbdDriver::create(const QString &driver,
const QString &device)
{
- Q_UNUSED(device);
if (driver.compare(QLatin1String("Yopy"), Qt::CaseInsensitive))
return 0;
- return new QWSYopyKeyboardHandler(driver);
+ return new QWSYopyKeyboardHandler(device);
}
Q_EXPORT_PLUGIN2(qwsyopykbddriver, QYopyKbdDriver)
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp
index 979eeec..617f116 100644
--- a/src/sql/drivers/oci/qsql_oci.cpp
+++ b/src/sql/drivers/oci/qsql_oci.cpp
@@ -609,7 +609,7 @@ static QSqlField qFromOraInf(const OraFieldInfo &ofi)
QSqlField f(ofi.name, ofi.type);
f.setRequired(ofi.oraIsNull == 0);
- if (ofi.type == QVariant::String)
+ if (ofi.type == QVariant::String && ofi.oraType != SQLT_NUM && ofi.oraType != SQLT_VNU)
f.setLength(ofi.oraFieldLength);
else
f.setLength(ofi.oraPrecision == 0 ? 38 : int(ofi.oraPrecision));
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index 50defdf..fa9031a 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -89,7 +89,8 @@ public:
enum DefaultCase{Lower, Mixed, Upper, Sensitive};
QODBCDriverPrivate()
: hEnv(0), hDbc(0), useSchema(false), disconnectCount(0), isMySqlServer(false),
- isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false)
+ isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false),
+ isQuoteInitialized(false), quote(QLatin1Char('"'))
{
unicode = false;
}
@@ -116,7 +117,10 @@ public:
QString &schema, QString &table);
DefaultCase defaultCase() const;
QString adjustCase(const QString&) const;
- QChar quoteChar() const;
+ QChar quoteChar();
+private:
+ bool isQuoteInitialized;
+ QChar quote;
};
class QODBCPrivate
@@ -566,10 +570,8 @@ static int qGetODBCVersion(const QString &connOpts)
return SQL_OV_ODBC2;
}
-QChar QODBCDriverPrivate::quoteChar() const
+QChar QODBCDriverPrivate::quoteChar()
{
- static bool isQuoteInitialized = false;
- static QChar quote = QChar::fromLatin1('"');
if (!isQuoteInitialized) {
char driverResponse[4];
SQLSMALLINT length;
@@ -579,9 +581,9 @@ QChar QODBCDriverPrivate::quoteChar() const
sizeof(driverResponse),
&length);
if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
- quote = QChar::fromLatin1(driverResponse[0]);
+ quote = QLatin1Char(driverResponse[0]);
} else {
- quote = QChar::fromLatin1('"');
+ quote = QLatin1Char('"');
}
isQuoteInitialized = true;
}
diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp
index 0c92013..c61c526 100644
--- a/src/sql/drivers/psql/qsql_psql.cpp
+++ b/src/sql/drivers/psql/qsql_psql.cpp
@@ -54,11 +54,33 @@
#include <qstringlist.h>
#include <qmutex.h>
+
#include <libpq-fe.h>
#include <pg_config.h>
#include <stdlib.h>
#include <math.h>
+// below code taken from an example at http://www.gnu.org/software/hello/manual/autoconf/Function-Portability.html
+#ifndef isnan
+ # define isnan(x) \
+ (sizeof (x) == sizeof (long double) ? isnan_ld (x) \
+ : sizeof (x) == sizeof (double) ? isnan_d (x) \
+ : isnan_f (x))
+ static inline int isnan_f (float x) { return x != x; }
+ static inline int isnan_d (double x) { return x != x; }
+ static inline int isnan_ld (long double x) { return x != x; }
+#endif
+
+#ifndef isinf
+ # define isinf(x) \
+ (sizeof (x) == sizeof (long double) ? isinf_ld (x) \
+ : sizeof (x) == sizeof (double) ? isinf_d (x) \
+ : isinf_f (x))
+ static inline int isinf_f (float x) { return isnan (x - x); }
+ static inline int isinf_d (double x) { return isnan (x - x); }
+ static inline int isinf_ld (long double x) { return isnan (x - x); }
+#endif
+
// workaround for postgres defining their OIDs in a private header file
#define QBOOLOID 16
@@ -601,10 +623,9 @@ static QPSQLDriver::Protocol getPSQLVersion(PGconn* connection)
{
QPSQLDriver::Protocol serverVersion = QPSQLDriver::Version6;
PGresult* result = PQexec(connection, "select version()");
- int status = PQresultStatus(result);
+ int status = PQresultStatus(result);
if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK) {
QString val = QString::fromAscii(PQgetvalue(result, 0, 0));
- PQclear(result);
QRegExp rx(QLatin1String("(\\d+)\\.(\\d+)"));
rx.setMinimal(true); // enforce non-greedy RegExp
if (rx.indexIn(val) != -1) {
@@ -645,6 +666,7 @@ static QPSQLDriver::Protocol getPSQLVersion(PGconn* connection)
}
}
}
+ PQclear(result);
if (serverVersion < QPSQLDriver::Version71)
qWarning("This version of PostgreSQL is not supported and may not work.");
@@ -1161,6 +1183,21 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
qPQfreemem(data);
break;
}
+ case QVariant::Double: {
+ double val = field.value().toDouble();
+ if (isnan(val))
+ r = QLatin1String("'NaN'");
+ else {
+ int res = isinf(val);
+ if (res == 1)
+ r = QLatin1String("'Infinity'");
+ else if (res == -1)
+ r = QLatin1String("'-Infinity'");
+ else
+ r = QSqlDriver::formatValue(field, trimStrings);
+ }
+ break;
+ }
default:
r = QSqlDriver::formatValue(field, trimStrings);
break;
@@ -1265,15 +1302,15 @@ QStringList QPSQLDriver::subscribedToNotificationsImplementation() const
void QPSQLDriver::_q_handleNotification(int)
{
PQconsumeInput(d->connection);
- PGnotify *notify = PQnotifies(d->connection);
- if (notify) {
- QString name(QLatin1String(notify->relname));
+ PGnotify *notify = 0;
+ while((notify = PQnotifies(d->connection)) != 0) {
+ QString name(QLatin1String(notify->relname));
if (d->seid.contains(name))
emit notification(name);
else
qWarning("QPSQLDriver: received notification for '%s' which isn't subscribed to.",
- qPrintable(name));
+ qPrintable(name));
qPQfreemem(notify);
}
diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 156af26..4315a8c 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -205,7 +205,7 @@ bool QSqlTableModelPrivate::exec(const QString &stmt, bool prepStatement,
editQuery.addBindValue(rec.value(i));
}
for (i = 0; i < whereValues.count(); ++i) {
- if (whereValues.isGenerated(i))
+ if (whereValues.isGenerated(i) && !whereValues.isNull(i))
editQuery.addBindValue(whereValues.value(i));
}
@@ -538,6 +538,7 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in
isOk = updateRowInTable(index.row(), d->editBuffer);
if (isOk)
select();
+ emit dataChanged(index, index);
break; }
case OnRowChange:
if (index.row() == d->insertIndex) {
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index 5950fac..5f9d1dd 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -68,6 +68,7 @@
QT_BEGIN_NAMESPACE
+
double qstrtod(const char *s00, char const **se, bool *ok);
static bool parsePathDataFast(const QStringRef &data, QPainterPath &path);
@@ -320,6 +321,7 @@ static qreal toDouble(const QChar *&str)
++str;
}
}
+
temp[pos] = '\0';
qreal val;
@@ -365,16 +367,24 @@ static qreal toDouble(const QChar *&str)
return val;
}
-static qreal toDouble(const QString &str)
+static qreal toDouble(const QString &str, bool *ok = NULL)
{
const QChar *c = str.constData();
- return toDouble(c);
+ qreal res = toDouble(c);
+ if (ok) {
+ *ok = ((*c) == QLatin1Char('\0'));
+ }
+ return res;
}
-static qreal toDouble(const QStringRef &str)
+static qreal toDouble(const QStringRef &str, bool *ok = NULL)
{
const QChar *c = str.constData();
- return toDouble(c);
+ qreal res = toDouble(c);
+ if (ok) {
+ *ok = (c == (str.constData() + str.length()));
+ }
+ return res;
}
static QVector<qreal> parseNumbersList(const QChar *&str)
@@ -497,14 +507,17 @@ static bool constructColor(const QString &colorStr, const QString &opacity,
if (!resolveColor(colorStr, color, handler))
return false;
if (!opacity.isEmpty()) {
- qreal op = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity)));
+ bool ok = true;
+ qreal op = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity, &ok)));
+ if (!ok)
+ op = 1.0;
color.setAlphaF(op);
}
return true;
}
static qreal parseLength(const QString &str, QSvgHandler::LengthType &type,
- QSvgHandler *handler)
+ QSvgHandler *handler, bool *ok = NULL)
{
QString numStr = str.trimmed();
@@ -533,15 +546,15 @@ static qreal parseLength(const QString &str, QSvgHandler::LengthType &type,
type = handler->defaultCoordinateSystem();
//type = QSvgHandler::LT_OTHER;
}
- qreal len = toDouble(numStr);
+ qreal len = toDouble(numStr, ok);
//qDebug()<<"len is "<<len<<", from '"<<numStr << "'";
return len;
}
-static inline qreal convertToNumber(const QString &str, QSvgHandler *handler)
+static inline qreal convertToNumber(const QString &str, QSvgHandler *handler, bool *ok = NULL)
{
QSvgHandler::LengthType type;
- qreal num = parseLength(str, type, handler);
+ qreal num = parseLength(str, type, handler, ok);
if (type == QSvgHandler::LT_PERCENT) {
num = num/100.0;
}
@@ -631,15 +644,32 @@ static void parseBrush(QSvgNode *node,
QString opacity = attributes.value(QLatin1String("fill-opacity")).toString();
QString myId = someId(attributes);
- value = value.trimmed();
- fillRule = fillRule.trimmed();
- if (!value.isEmpty() || !fillRule.isEmpty()) {
- Qt::FillRule f = Qt::WindingFill;
+ QSvgFillStyle *inherited =
+ static_cast<QSvgFillStyle*>(node->parent()->styleProperty(
+ QSvgStyleProperty::FILL));
+ QSvgFillStyle *prop = new QSvgFillStyle(QColor(Qt::black));
+
+ //fill-rule attribute handling
+ Qt::FillRule f = Qt::WindingFill;
+ if (!fillRule.isEmpty() && fillRule != QLatin1String("inherit")) {
if (fillRule == QLatin1String("evenodd"))
f = Qt::OddEvenFill;
+ } else if (inherited) {
+ f = inherited->fillRule();
+ }
+
+ //fill-opacity atttribute handling
+ qreal fillOpacity = 1.0;
+ if (!opacity.isEmpty() && opacity != QLatin1String("inherit")) {
+ fillOpacity = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity)));
+ } else if (inherited) {
+ fillOpacity = inherited->fillOpacity();
+ }
+
+ //fill attribute handling
+ if ((!value.isEmpty()) && (value != QLatin1String("inherit")) ) {
if (value.startsWith(QLatin1String("url"))) {
value = value.remove(0, 3);
- QSvgFillStyle *prop = new QSvgFillStyle(0);
QSvgStyleProperty *style = styleFromUrl(node, value);
if (style) {
prop->setFillStyle(style);
@@ -648,30 +678,26 @@ static void parseBrush(QSvgNode *node,
prop->setGradientId(id);
prop->setGradientResolved(false);
}
- if (!opacity.isEmpty()) {
- qreal clampedOpacity = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity)));
- prop->setFillOpacity(clampedOpacity);
- }
- if (!fillRule.isEmpty())
- prop->setFillRule(f);
- node->appendStyleProperty(prop,myId);
} else if (value != QLatin1String("none")) {
QColor color;
- if (constructColor(value, opacity, color, handler)) {
- QSvgFillStyle *prop = new QSvgFillStyle(QBrush(color));
- if (!fillRule.isEmpty())
- prop->setFillRule(f);
- node->appendStyleProperty(prop, myId);
- }
+ if (resolveColor(value, color, handler))
+ prop->setBrush(QBrush(color));
} else {
- QSvgFillStyle *prop = new QSvgFillStyle(QBrush(Qt::NoBrush));
- if (!fillRule.isEmpty())
- prop->setFillRule(f);
- node->appendStyleProperty(prop, myId);
+ prop->setBrush(QBrush(Qt::NoBrush));
+ }
+ } else if (inherited) {
+ if (inherited->style()) {
+ prop->setFillStyle(inherited->style());
+ } else {
+ prop->setBrush(inherited->qbrush());
}
}
+ prop->setFillOpacity(fillOpacity);
+ prop->setFillRule(f);
+ node->appendStyleProperty(prop,myId);
}
+
static void parseQPen(QPen &pen, QSvgNode *node,
const QSvgAttributes &attributes,
QSvgHandler *handler)
@@ -3006,7 +3032,11 @@ static bool parseStopNode(QSvgStyleProperty *parent,
QString colorStr = attrs.value(QString(), QLatin1String("stop-color")).toString();
QString opacityStr = attrs.value(QString(), QLatin1String("stop-opacity")).toString();
QColor color;
- qreal offset = convertToNumber(offsetStr, handler);
+
+ bool ok = true;
+ qreal offset = convertToNumber(offsetStr, handler, &ok);
+ if (!ok)
+ offset = 0.0;
if (colorStr.isEmpty()) {
colorStr = QLatin1String("#000000");
}
@@ -3095,12 +3125,16 @@ static QSvgNode *createSvgNode(QSvgNode *parent,
QStringList lst = viewBoxStr.split(QLatin1Char(' '), QString::SkipEmptyParts);
if (lst.count() != 4)
lst = viewBoxStr.split(QLatin1Char(','), QString::SkipEmptyParts);
+ int count = lst.count();
+ while (count < 4) {
+ lst.append(QLatin1String(""));
+ count++;
+ }
QString xStr = lst.at(0).trimmed();
QString yStr = lst.at(1).trimmed();
QString widthStr = lst.at(2).trimmed();
QString heightStr = lst.at(3).trimmed();
-
QSvgHandler::LengthType lt;
qreal x = parseLength(xStr, lt, handler);
qreal y = parseLength(yStr, lt, handler);
@@ -3108,15 +3142,14 @@ static QSvgNode *createSvgNode(QSvgNode *parent,
qreal h = parseLength(heightStr, lt, handler);
node->setViewBox(QRectF(x, y, w, h));
- } else if (width && height){
+
+ } else if (width && height) {
if (type == QSvgHandler::LT_PT) {
width = convertToPixels(width, false, type);
height = convertToPixels(height, false, type);
}
-
node->setViewBox(QRectF(0, 0, width, height));
}
-
handler->setDefaultCoordinateSystem(QSvgHandler::LT_PX);
return node;
diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp
index 556201b..4c8247b 100644
--- a/src/svg/qsvgstyle.cpp
+++ b/src/svg/qsvgstyle.cpp
@@ -81,12 +81,12 @@ void QSvgQualityStyle::revert(QPainter *, QSvgExtraStates &)
}
QSvgFillStyle::QSvgFillStyle(const QBrush &brush)
- : m_fill(brush), m_style(0), m_fillRuleSet(false), m_fillOpacitySet(false), m_gradientResolved (true)
+ : m_fill(brush), m_style(0), m_fillRuleSet(false), m_fillOpacitySet(false), m_fillRule(Qt::WindingFill), m_fillOpacity(1.0), m_gradientResolved (true)
{
}
QSvgFillStyle::QSvgFillStyle(QSvgStyleProperty *style)
- : m_style(style), m_fillRuleSet(false), m_fillOpacitySet(false), m_gradientResolved (true)
+ : m_style(style), m_fillRuleSet(false), m_fillOpacitySet(false), m_fillRule(Qt::WindingFill), m_fillOpacity(1.0), m_gradientResolved (true)
{
}
@@ -102,6 +102,16 @@ void QSvgFillStyle::setFillOpacity(qreal opacity)
m_fillOpacity = opacity;
}
+void QSvgFillStyle::setFillStyle(QSvgStyleProperty* style)
+{
+ m_style = style;
+}
+
+void QSvgFillStyle::setBrush(QBrush brush)
+{
+ m_fill = brush;
+}
+
static void recursivelySetFill(QSvgNode *node, Qt::FillRule f)
{
if (node->type() == QSvgNode::PATH) {
diff --git a/src/svg/qsvgstyle_p.h b/src/svg/qsvgstyle_p.h
index f1d0811..ac5e109 100644
--- a/src/svg/qsvgstyle_p.h
+++ b/src/svg/qsvgstyle_p.h
@@ -224,12 +224,29 @@ public:
void setFillRule(Qt::FillRule f);
void setFillOpacity(qreal opacity);
+ void setFillStyle(QSvgStyleProperty* style);
+ void setBrush(QBrush brush);
const QBrush & qbrush() const
{
return m_fill;
}
+ qreal fillOpacity() const
+ {
+ return m_fillOpacity;
+ }
+
+ Qt::FillRule fillRule() const
+ {
+ return m_fillRule;
+ }
+
+ QSvgStyleProperty* style() const
+ {
+ return m_style;
+ }
+
void setGradientId(const QString &Id)
{
m_gradientId = Id;
@@ -240,7 +257,6 @@ public:
return m_gradientId;
}
-
void setGradientResolved(bool resolved)
{
m_gradientResolved = resolved;
@@ -251,16 +267,6 @@ public:
return m_gradientResolved;
}
- void setFillStyle(QSvgStyleProperty* style)
- {
- m_style = style;
- }
-
- void setBrush(QBrush brush)
- {
- m_fill = brush;
- }
-
private:
// fill v v 'inherit' | <Paint.datatype>
// fill-opacity v v 'inherit' | <OpacityValue.datatype>
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 9924904..f94d428 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -150,6 +150,7 @@ SUBDIRS += _networkselftest \
qgraphicspolygonitem \
qgraphicsproxywidget \
qgraphicsscene \
+ qgraphicssceneindex \
qgraphicsview \
qgraphicswidget \
qgridlayout \
diff --git a/tests/auto/linguist/lconvert/data/makeplurals.pl b/tests/auto/linguist/lconvert/data/makeplurals.pl
new file mode 100755
index 0000000..19bffe0
--- /dev/null
+++ b/tests/auto/linguist/lconvert/data/makeplurals.pl
@@ -0,0 +1,42 @@
+#! /usr/bin/env perl
+
+sub makeit2($$$)
+{
+ for (my $i = 0; $i < (1 << $_[0]); $i++) {
+ print OUTFILE "\n";
+ print OUTFILE "$_[2]\n" unless $3 eq "";
+ print OUTFILE "msgid \"singular $_[1] $i\"\n";
+ print OUTFILE "msgid_plural \"plural $_[1] $i\"\n";
+ for (my $j = 0; $j < $_[0]; $j++) {
+ my $tr;
+ if (($i & (1 << $j)) == 0) {
+ $tr = "translated $_[1] $i $j";
+ }
+ print OUTFILE "msgstr[$j] \"$tr\"\n";
+ }
+ }
+}
+
+sub makeit($$)
+{
+ open OUTFILE, ">${OUTDIR}plural-$_[0].po" || die "cannot write file in $OUTDIR";
+ print OUTFILE <<EOF;
+msgid ""
+msgstr ""
+"X-FooBar: yup\\n"
+"X-Language: $_[1]\\n"
+EOF
+ makeit2($_[0], "one", "");
+ makeit2($_[0], "two", "#, fuzzy
+#| msgid \"old untranslated one\"");
+ makeit2($_[0], "three", "#, fuzzy
+#| msgid \"old untranslated two\"
+#| msgid_plural \"old untranslated plural two\"");
+ makeit2($_[0], "four", "#, fuzzy
+#| msgid_plural \"old untranslated only plural three\"");
+}
+
+$OUTDIR = $ARGV[0];
+makeit(1, "zh_CN");
+makeit(2, "de_DE");
+makeit(3, "pl_PL");
diff --git a/tests/auto/linguist/lconvert/data/makeplurals.sh b/tests/auto/linguist/lconvert/data/makeplurals.sh
deleted file mode 100755
index 2e0f375..0000000
--- a/tests/auto/linguist/lconvert/data/makeplurals.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#! /bin/bash
-
-function makeit2()
-{
- for ((i = 0; i < (1 << $1); i++)); do
- echo
- test -n "$3" && echo "$3"
- echo "msgid \"singular $2 $i\""
- echo "msgid_plural \"plural $2 $i\""
- for ((j = 0; j < $1; j++)); do
- tr=
- if test $((i & (1 << j))) = 0; then
- tr="translated $2 $i $j"
- fi
- echo "msgstr[$j] \"$tr\""
- done
- done
-}
-
-function makeit()
-{
- {
- cat <<EOF
-msgid ""
-msgstr ""
-"X-FooBar: yup\n"
-"X-Language: $2\n"
-EOF
- makeit2 $1 one ""
- makeit2 $1 two "#, fuzzy
-#| msgid \"old untranslated one\""
- makeit2 $1 three "#, fuzzy
-#| msgid \"old untranslated two\"
-#| msgid_plural \"old untranslated plural two\""
- makeit2 $1 four "#, fuzzy
-#| msgid_plural \"old untranslated only plural three\""
- } > ${OUTDIR}plural-$1.po
-}
-
-OUTDIR=$1
-makeit 1 zh_CN
-makeit 2 de_DE
-makeit 3 pl_PL
diff --git a/tests/auto/linguist/lconvert/tst_lconvert.cpp b/tests/auto/linguist/lconvert/tst_lconvert.cpp
index 40be55a..1ed71ab 100644
--- a/tests/auto/linguist/lconvert/tst_lconvert.cpp
+++ b/tests/auto/linguist/lconvert/tst_lconvert.cpp
@@ -47,7 +47,7 @@ class tst_lconvert : public QObject
Q_OBJECT
public:
- tst_lconvert() : dataDir("data/") {}
+ tst_lconvert() : dataDir("data/"), binDir(QLibraryInfo::location(QLibraryInfo::BinariesPath)) {}
private slots:
void initTestCase();
@@ -73,12 +73,13 @@ private:
const QList<QStringList> &args);
QString dataDir;
+ QString binDir;
};
void tst_lconvert::initTestCase()
{
if (!QFile::exists(QLatin1String("data/plural-1.po")))
- QProcess::execute(QLatin1String("data/makeplurals.sh"), QStringList() << QLatin1String("data/"));
+ QProcess::execute(QLatin1String("perl"), QStringList() << QLatin1String("data/makeplurals.pl") << QLatin1String("data/"));
QVERIFY(QFile::exists(QLatin1String("data/plural-1.po")));
}
@@ -151,7 +152,7 @@ void tst_lconvert::doCompare(QIODevice *actualDev, const QString &expectedFn)
void tst_lconvert::verifyReadFail(const QString &fn)
{
QProcess cvt;
- cvt.start("lconvert", QStringList() << (dataDir + fn));
+ cvt.start(binDir + "/lconvert", QStringList() << (dataDir + fn));
QVERIFY(cvt.waitForFinished(1000));
QVERIFY(cvt.exitStatus() == QProcess::NormalExit);
QVERIFY2(cvt.exitCode() == 2, "Accepted invalid input");
@@ -178,7 +179,7 @@ void tst_lconvert::convertChain(const QString &_inFileName, const QString &_outF
if (!argList.isEmpty())
args += argList[i];
args << "-if" << stations[i] << "-i" << "-" << "-of" << stations[i + 1];
- cvts.at(i)->start("lconvert", args);
+ cvts.at(i)->start(binDir + "/lconvert", args);
}
int st = 0;
foreach (QProcess *cvt, cvts)
@@ -242,7 +243,7 @@ void tst_lconvert::converts()
QString outFileNameFq = dataDir + outFileName;
QProcess cvt;
- cvt.start("lconvert", QStringList() << "-i" << (dataDir + inFileName) << "-of" << format);
+ cvt.start(binDir + "/lconvert", QStringList() << "-i" << (dataDir + inFileName) << "-of" << format);
doWait(&cvt, 0);
if (QTest::currentTestFailed())
return;
diff --git a/tests/auto/linguist/lrelease/tst_lrelease.cpp b/tests/auto/linguist/lrelease/tst_lrelease.cpp
index ff90b3c..45e9d6b 100644
--- a/tests/auto/linguist/lrelease/tst_lrelease.cpp
+++ b/tests/auto/linguist/lrelease/tst_lrelease.cpp
@@ -49,6 +49,10 @@
class tst_lrelease : public QObject
{
Q_OBJECT
+
+public:
+ tst_lrelease() : binDir(QLibraryInfo::location(QLibraryInfo::BinariesPath)) {}
+
private:
private slots:
@@ -60,6 +64,8 @@ private slots:
private:
void doCompare(const QStringList &actual, const QString &expectedFn);
+
+ QString binDir;
};
void tst_lrelease::doCompare(const QStringList &actual, const QString &expectedFn)
@@ -112,7 +118,7 @@ void tst_lrelease::doCompare(const QStringList &actual, const QString &expectedF
void tst_lrelease::translate()
{
- QVERIFY(!QProcess::execute("lrelease testdata/translate.ts"));
+ QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/translate.ts"));
QTranslator translator;
QVERIFY(translator.load("testdata/translate.qm"));
@@ -162,8 +168,8 @@ void tst_lrelease::translate()
void tst_lrelease::mixedcodecs()
{
- QVERIFY(!QProcess::execute("lrelease testdata/mixedcodecs-ts11.ts"));
- QVERIFY(!QProcess::execute("lrelease testdata/mixedcodecs-ts20.ts"));
+ QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/mixedcodecs-ts11.ts"));
+ QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/mixedcodecs-ts20.ts"));
QVERIFY(!QProcess::execute("cmp testdata/mixedcodecs-ts11.qm testdata/mixedcodecs-ts20.qm"));
QTranslator translator;
QVERIFY(translator.load("testdata/mixedcodecs-ts11.qm"));
@@ -177,7 +183,7 @@ void tst_lrelease::mixedcodecs()
void tst_lrelease::compressed()
{
- QVERIFY(!QProcess::execute("lrelease -compress testdata/compressed.ts"));
+ QVERIFY(!QProcess::execute(binDir + "/lrelease -compress testdata/compressed.ts"));
QTranslator translator;
QVERIFY(translator.load("testdata/compressed.qm"));
@@ -207,7 +213,7 @@ void tst_lrelease::idbased()
void tst_lrelease::dupes()
{
QProcess proc;
- proc.start("lrelease testdata/dupes.ts");
+ proc.start(binDir + "/lrelease testdata/dupes.ts");
QVERIFY(proc.waitForFinished());
QVERIFY(proc.exitStatus() == QProcess::NormalExit);
doCompare(QString(proc.readAllStandardError()).trimmed().remove('\r').split('\n'), "testdata/dupes.errors");
diff --git a/tests/auto/linguist/lupdate/testlupdate.cpp b/tests/auto/linguist/lupdate/testlupdate.cpp
index 8abc2b0..04c03f1 100644
--- a/tests/auto/linguist/lupdate/testlupdate.cpp
+++ b/tests/auto/linguist/lupdate/testlupdate.cpp
@@ -56,8 +56,9 @@
TestLUpdate::TestLUpdate()
{
childProc = 0;
- m_cmdLupdate = QLatin1String("lupdate");
- m_cmdQMake = QLatin1String("qmake");
+ QString binPath = QLibraryInfo::location(QLibraryInfo::BinariesPath);
+ m_cmdLupdate = binPath + QLatin1String("/lupdate");
+ m_cmdQMake = binPath + QLatin1String("/qmake");
}
TestLUpdate::~TestLUpdate()
diff --git a/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp b/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp
index 7facf4a..d799c1b 100644
--- a/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp
+++ b/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp
@@ -172,22 +172,22 @@ private slots:
private:
static void setMatrix(QMatrix2x2& m, const qreal *values);
- static void setMatrixFixed(QMatrix2x2& m, const qreal *values);
+ static void setMatrixDirect(QMatrix2x2& m, const qreal *values);
static bool isSame(const QMatrix2x2& m, const qreal *values);
static bool isIdentity(const QMatrix2x2& m);
static void setMatrix(QMatrix3x3& m, const qreal *values);
- static void setMatrixFixed(QMatrix3x3& m, const qreal *values);
+ static void setMatrixDirect(QMatrix3x3& m, const qreal *values);
static bool isSame(const QMatrix3x3& m, const qreal *values);
static bool isIdentity(const QMatrix3x3& m);
static void setMatrix(QMatrix4x4& m, const qreal *values);
- static void setMatrixFixed(QMatrix4x4& m, const qreal *values);
+ static void setMatrixDirect(QMatrix4x4& m, const qreal *values);
static bool isSame(const QMatrix4x4& m, const qreal *values);
static bool isIdentity(const QMatrix4x4& m);
static void setMatrix(QMatrix4x3& m, const qreal *values);
- static void setMatrixFixed(QMatrix4x3& m, const qreal *values);
+ static void setMatrixDirect(QMatrix4x3& m, const qreal *values);
static bool isSame(const QMatrix4x3& m, const qreal *values);
static bool isIdentity(const QMatrix4x3& m);
};
@@ -321,8 +321,9 @@ void tst_QMatrix::setMatrix(QMatrix4x3& m, const qreal *values)
}
// Set a matrix to a specified array of values, which are assumed
-// to be in row-major order. This sets the values using fixed-point.
-void tst_QMatrix::setMatrixFixed(QMatrix2x2& m, const qreal *values)
+// to be in row-major order. This sets the values directly into
+// the internal data() array.
+void tst_QMatrix::setMatrixDirect(QMatrix2x2& m, const qreal *values)
{
float *data = m.data();
for (int row = 0; row < 2; ++row) {
@@ -331,7 +332,7 @@ void tst_QMatrix::setMatrixFixed(QMatrix2x2& m, const qreal *values)
}
}
}
-void tst_QMatrix::setMatrixFixed(QMatrix3x3& m, const qreal *values)
+void tst_QMatrix::setMatrixDirect(QMatrix3x3& m, const qreal *values)
{
float *data = m.data();
for (int row = 0; row < 3; ++row) {
@@ -340,7 +341,7 @@ void tst_QMatrix::setMatrixFixed(QMatrix3x3& m, const qreal *values)
}
}
}
-void tst_QMatrix::setMatrixFixed(QMatrix4x4& m, const qreal *values)
+void tst_QMatrix::setMatrixDirect(QMatrix4x4& m, const qreal *values)
{
float *data = m.data();
for (int row = 0; row < 4; ++row) {
@@ -349,7 +350,7 @@ void tst_QMatrix::setMatrixFixed(QMatrix4x4& m, const qreal *values)
}
}
}
-void tst_QMatrix::setMatrixFixed(QMatrix4x3& m, const qreal *values)
+void tst_QMatrix::setMatrixDirect(QMatrix4x3& m, const qreal *values)
{
float *data = m.data();
for (int row = 0; row < 3; ++row) {
@@ -359,8 +360,8 @@ void tst_QMatrix::setMatrixFixed(QMatrix4x3& m, const qreal *values)
}
}
-// qFuzzyCompare isn't quite "fuzzy" enough to handle conversion
-// to fixed-point and back again. So create "fuzzier" compares.
+// qFuzzyCompare isn't always "fuzzy" enough to handle conversion
+// between float, double, and qreal. So create "fuzzier" compares.
static bool fuzzyCompare(float x, float y, qreal epsilon = 0.001)
{
float diff = x - y;
@@ -511,7 +512,7 @@ void tst_QMatrix::create2x2()
QVERIFY(!m2.isIdentity());
QMatrix2x2 m3;
- setMatrixFixed(m3, uniqueValues2);
+ setMatrixDirect(m3, uniqueValues2);
QVERIFY(isSame(m3, uniqueValues2));
QMatrix2x2 m4(m3);
@@ -546,7 +547,7 @@ void tst_QMatrix::create3x3()
QVERIFY(!m2.isIdentity());
QMatrix3x3 m3;
- setMatrixFixed(m3, uniqueValues3);
+ setMatrixDirect(m3, uniqueValues3);
QVERIFY(isSame(m3, uniqueValues3));
QMatrix3x3 m4(m3);
@@ -581,7 +582,7 @@ void tst_QMatrix::create4x4()
QVERIFY(!m2.isIdentity());
QMatrix4x4 m3;
- setMatrixFixed(m3, uniqueValues4);
+ setMatrixDirect(m3, uniqueValues4);
QVERIFY(isSame(m3, uniqueValues4));
QMatrix4x4 m4(m3);
@@ -623,7 +624,7 @@ void tst_QMatrix::create4x3()
QVERIFY(!m2.isIdentity());
QMatrix4x3 m3;
- setMatrixFixed(m3, uniqueValues4x3);
+ setMatrixDirect(m3, uniqueValues4x3);
QVERIFY(isSame(m3, uniqueValues4x3));
QMatrix4x3 m4(m3);
@@ -2961,10 +2962,6 @@ void tst_QMatrix::extractTranslation()
QVERIFY(fuzzyCompare(vec.y(), y, epsilon));
QVERIFY(fuzzyCompare(vec.z(), z, epsilon));
- // Have to be careful with numbers here, it is really easy to blow away
- // the precision of a fixed pointer number, especially when doing distance
- // formula for vector normalization
-
QMatrix4x4 lookAt;
QVector3D eye(1.5f, -2.5f, 2.5f);
lookAt.lookAt(eye,
diff --git a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp
index 395032f..16b87a1 100644
--- a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp
+++ b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp
@@ -95,8 +95,8 @@ private slots:
void nlerp();
};
-// qFuzzyCompare isn't quite "fuzzy" enough to handle conversion
-// to fixed-point and back again. So create "fuzzier" compares.
+// qFuzzyCompare isn't always "fuzzy" enough to handle conversion
+// between float, double, and qreal. So create "fuzzier" compares.
static bool fuzzyCompare(float x, float y)
{
float diff = x - y;
diff --git a/tests/auto/math3d/qvectornd/tst_qvectornd.cpp b/tests/auto/math3d/qvectornd/tst_qvectornd.cpp
index 0eb5b07..9c1ea83 100644
--- a/tests/auto/math3d/qvectornd/tst_qvectornd.cpp
+++ b/tests/auto/math3d/qvectornd/tst_qvectornd.cpp
@@ -139,8 +139,8 @@ private slots:
void dotProduct4();
};
-// qFuzzyCompare isn't quite "fuzzy" enough to handle conversion
-// to fixed-point and back again. So create "fuzzier" compares.
+// qFuzzyCompare isn't always "fuzzy" enough to handle conversion
+// between float, double, and qreal. So create "fuzzier" compares.
static bool fuzzyCompare(float x, float y)
{
float diff = x - y;
diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp
index fa786f1..0a2e46e 100644
--- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp
+++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp
@@ -157,11 +157,9 @@ void tst_Q3SqlCursor::createTestTables( QSqlDatabase db )
}
if (tst_Databases::isMSAccess(db)) {
- QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision") + " (col1 number)"));
- } else if (db.driverName().startsWith("QIBASE")) {
- QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision") + " (col1 numeric(15, 14))"));
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision") + " (col1 number)"));
} else {
- QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision") + " (col1 numeric(15, 14))"));
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtest_precision") + " (col1 numeric(15, 14))"));
}
}
@@ -557,7 +555,7 @@ void tst_Q3SqlCursor::unicode()
void tst_Q3SqlCursor::precision()
{
- static const QString precStr = "1.23456789012345";
+ static const QString precStr = QLatin1String("1.23456789012345");
static const double precDbl = 2.23456789012345;
QFETCH( QString, dbName );
@@ -576,7 +574,10 @@ void tst_Q3SqlCursor::precision()
QVERIFY_SQL(cur, select());
QVERIFY( cur.next() );
- QCOMPARE( cur.value( 0 ).asString(), QString( precStr ) );
+ if(!tst_Databases::isSqlServer(db))
+ QCOMPARE( cur.value( 0 ).asString(), precStr );
+ else
+ QCOMPARE( cur.value( 0 ).asString(), precStr.left(precStr.size()-1) ); // Sql server fails at counting.
QVERIFY( cur.next() );
QCOMPARE( cur.value( 0 ).asDouble(), precDbl );
}
@@ -760,9 +761,10 @@ void tst_Q3SqlCursor::insertFieldNameContainsWS() {
QSqlQuery q(db);
tst_Databases::safeDropTable(db, tableName);
- QString query = QString("CREATE TABLE %1 (id int, \"first Name\" varchar(20), "
- "lastName varchar(20))").arg(tableName);
- QVERIFY_SQL(q, exec(query));
+ QString query = "CREATE TABLE %1 (id int, "
+ + db.driver()->escapeIdentifier("first Name", QSqlDriver::FieldName)
+ + " varchar(20), lastName varchar(20))";
+ QVERIFY_SQL(q, exec(query.arg(tableName)));
Q3SqlCursor cur(tableName, true, db);
cur.select();
diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp
index c94ace0..67c9ac9 100644
--- a/tests/auto/qcombobox/tst_qcombobox.cpp
+++ b/tests/auto/qcombobox/tst_qcombobox.cpp
@@ -1973,6 +1973,7 @@ void tst_QComboBox::task190351_layout()
listCombo.showPopup();
QTest::qWait(100);
+#ifdef QT_BUILD_INTERNAL
QFrame *container = qFindChild<QComboBoxPrivateContainer *>(&listCombo);
QVERIFY(container);
QCOMPARE(static_cast<QAbstractItemView *>(list), qFindChild<QAbstractItemView *>(container));
@@ -1980,6 +1981,7 @@ void tst_QComboBox::task190351_layout()
QVERIFY(top);
QVERIFY(top->isVisible());
QCOMPARE(top->mapToGlobal(QPoint(0, top->height())).y(), list->mapToGlobal(QPoint()).y());
+#endif
QApplication::setStyle(oldStyle);
#else
@@ -2045,6 +2047,7 @@ void tst_QComboBox::task191329_size()
tableCombo.showPopup();
QTest::qWait(100);
+#ifdef QT_BUILD_INTERNAL
QFrame *container = qFindChild<QComboBoxPrivateContainer *>(&tableCombo);
QVERIFY(container);
QCOMPARE(static_cast<QAbstractItemView *>(table), qFindChild<QAbstractItemView *>(container));
@@ -2052,6 +2055,7 @@ void tst_QComboBox::task191329_size()
//the popup should be large enough to contains everithing so the top and left button are hidden
QVERIFY(!button->isVisible());
}
+#endif
QApplication::setStyle(oldStyle);
#else
@@ -2107,9 +2111,11 @@ void tst_QComboBox::task248169_popupWithMinimalSize()
comboBox.showPopup();
QTest::qWait(100);
+#ifdef QT_BUILD_INTERNAL
QFrame *container = qFindChild<QComboBoxPrivateContainer *>(&comboBox);
QVERIFY(container);
QVERIFY(desktop.screenGeometry(container).contains(container->geometry()));
+#endif
}
void tst_QComboBox::task247863_keyBoardSelection()
diff --git a/tests/auto/qcssparser/qcssparser.pro b/tests/auto/qcssparser/qcssparser.pro
index 57d6804..723e4d3 100644
--- a/tests/auto/qcssparser/qcssparser.pro
+++ b/tests/auto/qcssparser/qcssparser.pro
@@ -3,6 +3,7 @@ SOURCES += tst_cssparser.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
QT += xml
+requires(contains(QT_CONFIG,private_tests))
wince*: {
addFiles.sources = testdata
diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp
index e4fec1d..50cab0e 100644
--- a/tests/auto/qfiledialog/tst_qfiledialog.cpp
+++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp
@@ -160,6 +160,7 @@ private slots:
void task251321_sideBarHiddenEntries();
void task251341_sideBarRemoveEntries();
void task254490_selectFileMultipleTimes();
+ void task257579_sideBarWithNonCleanUrls();
private:
QByteArray userSettings;
@@ -231,6 +232,7 @@ void tst_QFiledialog::currentChangedSignal()
// only emited from the views, sidebar, or lookin combo
void tst_QFiledialog::directoryEnteredSignal()
{
+#if defined QT_BUILD_INTERNAL
QNonNativeFileDialog fd(0, "", QDir::root().path());
fd.setOptions(QFileDialog::DontUseNativeDialog);
fd.show();
@@ -274,6 +276,7 @@ void tst_QFiledialog::directoryEnteredSignal()
QTest::mouseDClick(listView->viewport(), Qt::LeftButton, 0, listView->visualRect(folder).center());
QTRY_COMPARE(spyDirectoryEntered.count(), 1);
*/
+#endif
}
Q_DECLARE_METATYPE(QFileDialog::FileMode)
@@ -1314,16 +1317,14 @@ void tst_QFiledialog::hooks()
void tst_QFiledialog::listRoot()
{
+#if defined QT_BUILD_INTERNAL
QFileInfoGatherer::fetchedRoot = false;
QString dir(QDir::currentPath());
QNonNativeFileDialog fd(0, QString(), dir);
fd.show();
-#if defined Q_AUTOTEST_EXPORT
QCOMPARE(QFileInfoGatherer::fetchedRoot,false);
-#endif
fd.setDirectory("");
QTest::qWait(500);
-#if defined Q_AUTOTEST_EXPORT
QCOMPARE(QFileInfoGatherer::fetchedRoot,true);
#endif
}
@@ -1347,6 +1348,7 @@ struct FriendlyQFileDialog : public QFileDialog
void tst_QFiledialog::deleteDirAndFiles()
{
+#if defined QT_BUILD_INTERNAL
QString tempPath = QDir::tempPath() + '/' + "QFileDialogTestDir4FullDelete";
QDir dir;
QVERIFY(dir.mkpath(tempPath + "/foo"));
@@ -1373,6 +1375,7 @@ void tst_QFiledialog::deleteDirAndFiles()
QFileInfo info(tempPath);
QTest::qWait(2000);
QVERIFY(!info.exists());
+#endif
}
void tst_QFiledialog::filter()
@@ -1583,6 +1586,7 @@ QString &dir, const QString &filter)
void tst_QFiledialog::task227304_proxyOnFileDialog()
{
+#if defined QT_BUILD_INTERNAL
QNonNativeFileDialog fd(0, "", QDir::currentPath(), 0);
fd.setProxyModel(new FilterDirModel(QDir::currentPath()));
fd.show();
@@ -1616,6 +1620,7 @@ void tst_QFiledialog::task227304_proxyOnFileDialog()
QTest::mouseClick(sidebar->viewport(), Qt::LeftButton, 0, sidebar->visualRect(sidebar->model()->index(1, 0)).center());
QTest::qWait(250);
//We shouldn't crash
+#endif
}
void tst_QFiledialog::task227930_correctNavigationKeyboardBehavior()
@@ -1727,6 +1732,7 @@ void tst_QFiledialog::task235069_hideOnEscape()
void tst_QFiledialog::task236402_dontWatchDeletedDir()
{
+#if defined QT_BUILD_INTERNAL
//THIS TEST SHOULD NOT DISPLAY WARNINGS
QDir current = QDir::currentPath();
//make sure it is the first on the list
@@ -1746,6 +1752,7 @@ void tst_QFiledialog::task236402_dontWatchDeletedDir()
QTest::qWait(200);
fd.d_func()->removeDirectory(current.absolutePath() + "/aaaaaaaaaa/");
QTest::qWait(1000);
+#endif
}
void tst_QFiledialog::task203703_returnProperSeparator()
@@ -1870,6 +1877,7 @@ void tst_QFiledialog::task218353_relativePaths()
void tst_QFiledialog::task251321_sideBarHiddenEntries()
{
+#if defined QT_BUILD_INTERNAL
QNonNativeFileDialog fd;
QDir current = QDir::currentPath();
@@ -1899,8 +1907,10 @@ void tst_QFiledialog::task251321_sideBarHiddenEntries()
hiddenSubDir.rmdir("happy");
hiddenDir.rmdir("subdir");
current.rmdir(".hidden");
+#endif
}
+#if defined QT_BUILD_INTERNAL
class MyQSideBar : public QSidebar
{
public :
@@ -1918,9 +1928,11 @@ public :
model()->removeRow(indexes.at(i).row());
}
};
+#endif
void tst_QFiledialog::task251341_sideBarRemoveEntries()
{
+#if defined QT_BUILD_INTERNAL
QNonNativeFileDialog fd;
QDir current = QDir::currentPath();
@@ -1980,6 +1992,7 @@ void tst_QFiledialog::task251341_sideBarRemoveEntries()
QCOMPARE(mySideBar.urls(), expected);
current.rmdir("testDir");
+#endif
}
void tst_QFiledialog::task254490_selectFileMultipleTimes()
@@ -2014,5 +2027,25 @@ void tst_QFiledialog::task254490_selectFileMultipleTimes()
t->deleteLater();
}
+void tst_QFiledialog::task257579_sideBarWithNonCleanUrls()
+{
+ QDir tempDir = QDir::temp();
+ QLatin1String dirname("autotest_task257579");
+ tempDir.rmdir(dirname); //makes sure it doesn't exist any more
+ QVERIFY(tempDir.mkdir(dirname));
+ QString url = QString::fromLatin1("%1/%2/..").arg(tempDir.absolutePath()).arg(dirname);
+ QNonNativeFileDialog fd;
+ fd.setSidebarUrls(QList<QUrl>() << QUrl::fromLocalFile(url));
+ QSidebar *sidebar = qFindChild<QSidebar*>(&fd, "sidebar");
+ QCOMPARE(sidebar->urls().count(), 1);
+ QVERIFY(sidebar->urls().first().toLocalFile() != url);
+ QCOMPARE(sidebar->urls().first().toLocalFile(), QDir::cleanPath(url));
+ QCOMPARE(sidebar->model()->index(0,0).data().toString(), tempDir.dirName());
+
+ //all tests are finished, we can remove the temporary dir
+ QVERIFY(tempDir.rmdir(dirname));
+}
+
+
QTEST_MAIN(tst_QFiledialog)
#include "tst_qfiledialog.moc"
diff --git a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp
index e415b02..d49083f 100644
--- a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp
+++ b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp
@@ -254,6 +254,7 @@ void tst_QFileSystemModel::naturalCompare_data()
void tst_QFileSystemModel::naturalCompare()
{
+#ifdef QT_BUILD_INTERNAL
QFETCH(QString, s1);
QFETCH(QString, s2);
QFETCH(int, caseSensitive);
@@ -271,6 +272,7 @@ void tst_QFileSystemModel::naturalCompare()
// created. The scheduler takes its time to recognize ended threads.
QTest::qWait(300);
#endif
+#endif
}
void tst_QFileSystemModel::readOnly()
diff --git a/tests/auto/qflags/tst_qflags.cpp b/tests/auto/qflags/tst_qflags.cpp
index a5f68dc..87d8258 100644
--- a/tests/auto/qflags/tst_qflags.cpp
+++ b/tests/auto/qflags/tst_qflags.cpp
@@ -45,6 +45,7 @@ class tst_QFlags: public QObject
Q_OBJECT
private slots:
void testFlag() const;
+ void testFlagZeroFlag() const;
void testFlagMultiBits() const;
};
@@ -59,8 +60,31 @@ void tst_QFlags::testFlag() const
QVERIFY(!btn.testFlag(Qt::LeftButton));
}
+void tst_QFlags::testFlagZeroFlag() const
+{
+ {
+ Qt::MouseButtons btn = Qt::LeftButton | Qt::RightButton;
+ /* Qt::NoButton has the value 0. */
+
+ QVERIFY(!btn.testFlag(Qt::NoButton));
+ }
+
+ {
+ /* A zero enum set should test true with zero. */
+ QVERIFY(Qt::MouseButtons().testFlag(Qt::NoButton));
+ }
+
+ {
+ Qt::MouseButtons btn = Qt::NoButton;
+ QVERIFY(btn.testFlag(Qt::NoButton));
+ }
+}
+
void tst_QFlags::testFlagMultiBits() const
{
+ /* Qt::Window is 0x00000001
+ * Qt::Dialog is 0x00000002 | Window
+ */
{
const Qt::WindowFlags onlyWindow(Qt::Window);
QVERIFY(!onlyWindow.testFlag(Qt::Dialog));
diff --git a/tests/auto/qfontdialog/tst_qfontdialog.cpp b/tests/auto/qfontdialog/tst_qfontdialog.cpp
index 5f1797b..cbdd440 100644
--- a/tests/auto/qfontdialog/tst_qfontdialog.cpp
+++ b/tests/auto/qfontdialog/tst_qfontdialog.cpp
@@ -170,8 +170,12 @@ void tst_QFontDialog::task256466_wrongStyle()
for (int i = 0; i < familyList->model()->rowCount(); ++i) {
QModelIndex currentFamily = familyList->model()->index(i, 0);
familyList->setCurrentIndex(currentFamily);
- QCOMPARE(dialog.currentFont(), fdb.font(currentFamily.data().toString(),
- styleList->currentIndex().data().toString(), sizeList->currentIndex().data().toInt()));
+ const QFont current = dialog.currentFont(),
+ expected = fdb.font(currentFamily.data().toString(),
+ styleList->currentIndex().data().toString(), sizeList->currentIndex().data().toInt());
+ QCOMPARE(current.family(), expected.family());
+ QCOMPARE(current.style(), expected.style());
+ QCOMPARE(current.pointSizeF(), expected.pointSizeF());
}
}
diff --git a/tests/auto/qgl/qgl.pro b/tests/auto/qgl/qgl.pro
index 55e329d..420c4bb 100644
--- a/tests/auto/qgl/qgl.pro
+++ b/tests/auto/qgl/qgl.pro
@@ -3,7 +3,8 @@
############################################################
load(qttest_p4)
-contains(QT_CONFIG, opengl):QT += opengl
+requires(contains(QT_CONFIG,opengl))
+QT += opengl
SOURCES += tst_qgl.cpp
diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp
index 078c559..96f5ddd 100644
--- a/tests/auto/qgl/tst_qgl.cpp
+++ b/tests/auto/qgl/tst_qgl.cpp
@@ -44,9 +44,7 @@
#include <qcoreapplication.h>
#include <qdebug.h>
-#ifndef QT_NO_OPENGL
#include <qgl.h>
-#endif
#include <QGraphicsView>
#include <QGraphicsProxyWidget>
@@ -78,7 +76,6 @@ tst_QGL::~tst_QGL()
{
}
-#ifndef QT_NO_OPENGL
class MyGLContext : public QGLContext
{
public:
@@ -96,13 +93,10 @@ public:
bool autoBufferSwap() const { return QGLWidget::autoBufferSwap(); }
void setAutoBufferSwap(bool on) { QGLWidget::setAutoBufferSwap(on); }
};
-#endif
+
// Testing get/set functions
void tst_QGL::getSetCheck()
{
-#ifdef QT_NO_OPENGL
- QSKIP("QGL not yet supported", SkipAll);
-#else
if (!QGLFormat::hasOpenGL())
QSKIP("QGL not supported on this platform", SkipAll);
@@ -246,10 +240,9 @@ void tst_QGL::getSetCheck()
QCOMPARE(false, obj3.autoBufferSwap());
obj3.setAutoBufferSwap(true);
QCOMPARE(true, obj3.autoBufferSwap());
-#endif
}
-#ifndef QT_NO_OPENGL
+#ifdef QT_BUILD_INTERNAL
QT_BEGIN_NAMESPACE
extern QGLFormat::OpenGLVersionFlags qOpenGLVersionFlagsFromString(const QString &versionString);
QT_END_NAMESPACE
@@ -257,9 +250,7 @@ QT_END_NAMESPACE
void tst_QGL::openGLVersionCheck()
{
-#ifdef QT_NO_OPENGL
- QSKIP("QGL not yet supported", SkipAll);
-#else
+#ifdef QT_BUILD_INTERNAL
if (!QGLFormat::hasOpenGL())
QSKIP("QGL not supported on this platform", SkipAll);
@@ -366,9 +357,6 @@ public:
void tst_QGL::graphicsViewClipping()
{
-#ifdef QT_NO_OPENGL
- QSKIP("QGL not supported", SkipAll);
-#else
const int size = 64;
UnclippedWidget *widget = new UnclippedWidget;
widget->setFixedSize(size, size);
@@ -403,7 +391,6 @@ void tst_QGL::graphicsViewClipping()
p.end();
QCOMPARE(image, expected);
-#endif
}
void tst_QGL::partialGLWidgetUpdates_data()
@@ -420,9 +407,6 @@ void tst_QGL::partialGLWidgetUpdates_data()
void tst_QGL::partialGLWidgetUpdates()
{
-#ifdef QT_NO_OPENGL
- QSKIP("QGL not yet supported", SkipAll);
-#else
if (!QGLFormat::hasOpenGL())
QSKIP("QGL not supported on this platform", SkipAll);
@@ -466,7 +450,6 @@ void tst_QGL::partialGLWidgetUpdates()
QCOMPARE(widget.paintEventRegion, QRegion(50, 50, 50, 50));
else
QCOMPARE(widget.paintEventRegion, QRegion(widget.rect()));
-#endif
}
QTEST_MAIN(tst_QGL)
diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
index 7552f18..96ee070 100644
--- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -231,6 +231,7 @@ private slots:
void sorting_data();
void sorting();
void itemHasNoContents();
+ void hitTestUntransformableItem();
// task specific tests below me
void task141694_textItemEnsureVisible();
@@ -6580,6 +6581,7 @@ public:
void tst_QGraphicsItem::update()
{
QGraphicsScene scene;
+ scene.setSceneRect(-100, -100, 200, 200);
MyGraphicsView view(&scene);
view.show();
@@ -6612,9 +6614,9 @@ void tst_QGraphicsItem::update()
qApp->processEvents();
QCOMPARE(item->repaints, 1);
QCOMPARE(view.repaints, 1);
- const QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform())
- .mapRect(item->boundingRect()).toRect();
- const QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2);
+ QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform())
+ .mapRect(item->boundingRect()).toRect();
+ QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2);
// The entire item's bounding rect (adjusted for antialiasing) should have been painted.
QCOMPARE(view.paintedRegion, expectedRegion);
@@ -6625,6 +6627,90 @@ void tst_QGraphicsItem::update()
qApp->processEvents();
QCOMPARE(item->repaints, 0);
QCOMPARE(view.repaints, 0);
+
+ // Make sure the area occupied by an item is repainted when hiding it.
+ view.reset();
+ item->repaints = 0;
+ item->update(); // Full update; all sub-sequent update requests are discarded.
+ item->hide(); // visible set to 0. ignoreVisible must be set to 1; the item won't be processed otherwise.
+ qApp->processEvents();
+ QCOMPARE(item->repaints, 0);
+ QCOMPARE(view.repaints, 1);
+ // The entire item's bounding rect (adjusted for antialiasing) should have been painted.
+ QCOMPARE(view.paintedRegion, expectedRegion);
+
+ // Make sure item is repainted when shown (after being hidden).
+ view.reset();
+ item->repaints = 0;
+ item->show();
+ qApp->processEvents();
+ QCOMPARE(item->repaints, 1);
+ QCOMPARE(view.repaints, 1);
+ // The entire item's bounding rect (adjusted for antialiasing) should have been painted.
+ QCOMPARE(view.paintedRegion, expectedRegion);
+
+ item->repaints = 0;
+ item->hide();
+ qApp->processEvents();
+ view.reset();
+ const QPointF originalPos = item->pos();
+ item->setPos(5000, 5000);
+ qApp->processEvents();
+ QCOMPARE(item->repaints, 0);
+ QCOMPARE(view.repaints, 0);
+ qApp->processEvents();
+
+ item->setPos(originalPos);
+ qApp->processEvents();
+ QCOMPARE(item->repaints, 0);
+ QCOMPARE(view.repaints, 0);
+ item->show();
+ qApp->processEvents();
+ QCOMPARE(item->repaints, 1);
+ QCOMPARE(view.repaints, 1);
+ // The entire item's bounding rect (adjusted for antialiasing) should have been painted.
+ QCOMPARE(view.paintedRegion, expectedRegion);
+
+ QGraphicsViewPrivate *viewPrivate = static_cast<QGraphicsViewPrivate *>(qt_widget_private(&view));
+ item->setPos(originalPos + QPoint(50, 50));
+ viewPrivate->updateAll();
+ QVERIFY(viewPrivate->fullUpdatePending);
+ QTest::qWait(50);
+ item->repaints = 0;
+ view.reset();
+ item->setPos(originalPos);
+ QTest::qWait(50);
+ qApp->processEvents();
+ QCOMPARE(item->repaints, 1);
+ QCOMPARE(view.repaints, 1);
+ QCOMPARE(view.paintedRegion, expectedRegion + expectedRegion.translated(50, 50));
+
+ // Make sure moving a parent item triggers an update on the children
+ // (even though the parent itself is outside the viewport).
+ QGraphicsRectItem *parent = new QGraphicsRectItem(0, 0, 10, 10);
+ parent->setPos(-400, 0);
+ item->setParentItem(parent);
+ item->setPos(400, 0);
+ scene.addItem(parent);
+ QTest::qWait(50);
+ itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform())
+ .mapRect(item->boundingRect()).toRect();
+ expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2);
+ view.reset();
+ item->repaints = 0;
+ parent->translate(-400, 0);
+ qApp->processEvents();
+ QCOMPARE(item->repaints, 0);
+ QCOMPARE(view.repaints, 1);
+ QCOMPARE(view.paintedRegion, expectedRegion);
+ view.reset();
+ item->repaints = 0;
+ parent->translate(400, 0);
+ qApp->processEvents();
+ QCOMPARE(item->repaints, 1);
+ QCOMPARE(view.repaints, 1);
+ QCOMPARE(view.paintedRegion, expectedRegion);
+ QCOMPARE(view.paintedRegion, expectedRegion);
}
void tst_QGraphicsItem::setTransformProperties_data()
@@ -6837,9 +6923,11 @@ public:
//Doesn't use the extended style option so the exposed rect is the boundingRect
if (!(flags() & QGraphicsItem::ItemUsesExtendedStyleOption)) {
QCOMPARE(option->exposedRect, boundingRect());
+ QCOMPARE(option->matrix, QMatrix());
} else {
QVERIFY(option->exposedRect != QRect());
QVERIFY(option->exposedRect != boundingRect());
+ QCOMPARE(option->matrix, sceneTransform().toAffine());
}
}
QGraphicsRectItem::paint(painter, option, widget);
@@ -6861,6 +6949,8 @@ void tst_QGraphicsItem::itemUsesExtendedStyleOption()
scene.addItem(rect);
rect->setPos(200, 200);
QGraphicsView view(&scene);
+ rect->startTrack = false;
+ view.show();
QTest::qWait(500);
rect->startTrack = true;
rect->update(10, 10, 10, 10);
@@ -7023,7 +7113,7 @@ void tst_QGraphicsItem::sorting()
QGraphicsView view(&scene);
view.setResizeAnchor(QGraphicsView::NoAnchor);
view.setTransformationAnchor(QGraphicsView::NoAnchor);
- view.resize(100, 100);
+ view.resize(120, 100);
view.setFrameStyle(0);
view.show();
#ifdef Q_WS_X11
@@ -7040,6 +7130,7 @@ void tst_QGraphicsItem::sorting()
<< grid[1][0] << grid[1][1] << grid[1][2] << grid[1][3]
<< grid[2][0] << grid[2][1] << grid[2][2] << grid[2][3]
<< grid[3][0] << grid[3][1] << grid[3][2] << grid[3][3]
+ << grid[4][0] << grid[4][1] << grid[4][2] << grid[4][3]
<< item1 << item2);
}
@@ -7069,5 +7160,55 @@ void tst_QGraphicsItem::itemHasNoContents()
QCOMPARE(_paintedItems, QList<QGraphicsItem *>() << item2);
}
+void tst_QGraphicsItem::hitTestUntransformableItem()
+{
+ QGraphicsScene scene;
+ scene.setSceneRect(-100, -100, 200, 200);
+
+ QGraphicsView view(&scene);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(100);
+
+ // Confuse the BSP with dummy items.
+ QGraphicsRectItem *dummy = new QGraphicsRectItem(0, 0, 20, 20);
+ dummy->setPos(-100, -100);
+ scene.addItem(dummy);
+ for (int i = 0; i < 100; ++i) {
+ QGraphicsItem *parent = dummy;
+ dummy = new QGraphicsRectItem(0, 0, 20, 20);
+ dummy->setPos(-100 + i, -100 + i);
+ dummy->setParentItem(parent);
+ }
+
+ QGraphicsRectItem *item1 = new QGraphicsRectItem(0, 0, 20, 20);
+ item1->setPos(-200, -200);
+
+ QGraphicsRectItem *item2 = new QGraphicsRectItem(0, 0, 20, 20);
+ item2->setFlag(QGraphicsItem::ItemIgnoresTransformations);
+ item2->setParentItem(item1);
+ item2->setPos(200, 200);
+
+ QGraphicsRectItem *item3 = new QGraphicsRectItem(0, 0, 20, 20);
+ item3->setParentItem(item2);
+ item3->setPos(80, 80);
+
+ scene.addItem(item1);
+ QTest::qWait(100);
+
+ QList<QGraphicsItem *> items = scene.items(QPointF(80, 80));
+ QCOMPARE(items.size(), 1);
+ QCOMPARE(items.at(0), static_cast<QGraphicsItem*>(item3));
+
+ scene.setItemIndexMethod(QGraphicsScene::NoIndex);
+ QTest::qWait(100);
+
+ items = scene.items(QPointF(80, 80));
+ QCOMPARE(items.size(), 1);
+ QCOMPARE(items.at(0), static_cast<QGraphicsItem*>(item3));
+}
+
QTEST_MAIN(tst_QGraphicsItem)
#include "tst_qgraphicsitem.moc"
diff --git a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp
index 536c750..bca673f 100644
--- a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp
+++ b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp
@@ -687,7 +687,6 @@ void tst_QGraphicsLayout::ownership()
delete top;
//don't crash after that.
}
-
}
QTEST_MAIN(tst_QGraphicsLayout)
diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
index dbc4339..1d0663a 100644
--- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
+++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
@@ -178,6 +178,7 @@ private slots:
void windowFlags_data();
void windowFlags();
void comboboxWindowFlags();
+ void updateAndDelete();
void inputMethod();
};
@@ -3218,6 +3219,44 @@ void tst_QGraphicsProxyWidget::comboboxWindowFlags()
QVERIFY((static_cast<QGraphicsWidget *>(popupProxy)->windowFlags() & Qt::Popup) == Qt::Popup);
}
+void tst_QGraphicsProxyWidget::updateAndDelete()
+{
+ QGraphicsScene scene;
+ QGraphicsProxyWidget *proxy = scene.addWidget(new QPushButton("Hello World"));
+ View view(&scene);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(200);
+
+ const QRect itemDeviceBoundingRect = proxy->deviceTransform(view.viewportTransform())
+ .mapRect(proxy->boundingRect()).toRect();
+ const QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2);
+
+ view.npaints = 0;
+ view.paintEventRegion = QRegion();
+
+ // Update and hide.
+ proxy->update();
+ proxy->hide();
+ QTest::qWait(50);
+ QCOMPARE(view.npaints, 1);
+ QCOMPARE(view.paintEventRegion, expectedRegion);
+
+ proxy->show();
+ QTest::qWait(50);
+ view.npaints = 0;
+ view.paintEventRegion = QRegion();
+
+ // Update and delete.
+ proxy->update();
+ delete proxy;
+ QTest::qWait(50);
+ QCOMPARE(view.npaints, 1);
+ QCOMPARE(view.paintEventRegion, expectedRegion);
+}
+
class InputMethod_LineEdit : public QLineEdit
{
bool event(QEvent *e)
@@ -3252,7 +3291,7 @@ void tst_QGraphicsProxyWidget::inputMethod()
if (i)
lineEdit->setFocus();
-
+
lineEdit->inputMethodEvents = 0;
QInputMethodEvent event;
qApp->sendEvent(proxy, &event);
diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
index d325f0f..e9d6f1d 100644
--- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
+++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
@@ -289,28 +289,46 @@ void tst_QGraphicsScene::construction()
void tst_QGraphicsScene::sceneRect()
{
QGraphicsScene scene;
+ QSignalSpy sceneRectChanged(&scene, SIGNAL(sceneRectChanged(QRectF)));
QCOMPARE(scene.sceneRect(), QRectF());
+ QCOMPARE(sceneRectChanged.count(), 0);
QGraphicsItem *item = scene.addRect(QRectF(0, 0, 10, 10));
- qApp->processEvents();
item->setPos(-5, -5);
- qApp->processEvents();
+ QCOMPARE(sceneRectChanged.count(), 0);
QCOMPARE(scene.itemAt(0, 0), item);
QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0);
+ QCOMPARE(sceneRectChanged.count(), 0);
+ QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 10, 10));
+ QCOMPARE(sceneRectChanged.count(), 1);
+ QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect());
+
+ item->setPos(0, 0);
QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 15, 15));
+ QCOMPARE(sceneRectChanged.count(), 2);
+ QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect());
scene.setSceneRect(-100, -100, 10, 10);
+ QCOMPARE(sceneRectChanged.count(), 3);
+ QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect());
QCOMPARE(scene.itemAt(0, 0), item);
QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0);
QCOMPARE(scene.sceneRect(), QRectF(-100, -100, 10, 10));
+ item->setPos(10, 10);
+ QCOMPARE(scene.sceneRect(), QRectF(-100, -100, 10, 10));
+ QCOMPARE(sceneRectChanged.count(), 3);
+ QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect());
scene.setSceneRect(QRectF());
- QCOMPARE(scene.itemAt(0, 0), item);
- QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0);
- QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 15, 15));
+ QCOMPARE(scene.itemAt(10, 10), item);
+ QCOMPARE(scene.itemAt(20, 20), (QGraphicsItem *)0);
+ QCOMPARE(sceneRectChanged.count(), 4);
+ QCOMPARE(scene.sceneRect(), QRectF(-5, -5, 25, 25));
+ QCOMPARE(sceneRectChanged.count(), 5);
+ QCOMPARE(sceneRectChanged.last().at(0).toRectF(), scene.sceneRect());
}
void tst_QGraphicsScene::itemIndexMethod()
@@ -399,8 +417,7 @@ void tst_QGraphicsScene::items()
for (int x = minX; x < maxX; x += 100)
items << scene.addRect(QRectF(0, 0, 10, 10));
}
-
- QCOMPARE(scene.items(), items);
+ QCOMPARE(scene.items().size(), items.size());
scene.itemAt(0, 0); // trigger indexing
scene.removeItem(items.at(5));
@@ -415,6 +432,9 @@ void tst_QGraphicsScene::items()
QGraphicsLineItem *l2 = scene.addLine(0, -5, 0, 5);
QVERIFY(!l1->sceneBoundingRect().intersects(l2->sceneBoundingRect()));
QVERIFY(!l2->sceneBoundingRect().intersects(l1->sceneBoundingRect()));
+ QList<QGraphicsItem *> items;
+ items<<l1<<l2;
+ QCOMPARE(scene.items().size(), items.size());
QVERIFY(scene.items(-1, -1, 2, 2).contains(l1));
QVERIFY(scene.items(-1, -1, 2, 2).contains(l2));
}
@@ -2742,8 +2762,8 @@ void tst_QGraphicsScene::update()
qRegisterMetaType<QList<QRectF> >("QList<QRectF>");
QSignalSpy spy(&scene, SIGNAL(changed(QList<QRectF>)));
- // When deleted, the item will lazy-remove itself
- delete rect;
+ // We update the scene.
+ scene.update();
// This function forces a purge, which will post an update signal
scene.itemAt(0, 0);
diff --git a/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro b/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro
new file mode 100644
index 0000000..740a23e
--- /dev/null
+++ b/tests/auto/qgraphicssceneindex/qgraphicssceneindex.pro
@@ -0,0 +1,3 @@
+load(qttest_p4)
+SOURCES += tst_qgraphicssceneindex.cpp
+
diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp
new file mode 100644
index 0000000..3ce5b16
--- /dev/null
+++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QtGui/qgraphicsscene.h>
+#include <private/qgraphicsscenebsptreeindex_p.h>
+#include <private/qgraphicssceneindex_p.h>
+#include <private/qgraphicsscenelinearindex_p.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QGraphicsSceneIndex : public QObject
+{
+ Q_OBJECT
+public slots:
+ void initTestCase();
+
+private slots:
+ void customIndex_data();
+ void customIndex();
+ void scatteredItems_data();
+ void scatteredItems();
+ void overlappedItems_data();
+ void overlappedItems();
+ void movingItems_data();
+ void movingItems();
+ void connectedToSceneRectChanged();
+ void items();
+
+private:
+ void common_data();
+ QGraphicsSceneIndex *createIndex(const QString &name);
+};
+
+void tst_QGraphicsSceneIndex::initTestCase()
+{
+}
+
+void tst_QGraphicsSceneIndex::common_data()
+{
+ QTest::addColumn<QString>("indexMethod");
+
+ QTest::newRow("BSP") << QString("bsp");
+ QTest::newRow("Linear") << QString("linear");
+}
+
+QGraphicsSceneIndex *tst_QGraphicsSceneIndex::createIndex(const QString &indexMethod)
+{
+ QGraphicsSceneIndex *index = 0;
+ QGraphicsScene *scene = new QGraphicsScene();
+ if (indexMethod == "bsp")
+ index = new QGraphicsSceneBspTreeIndex(scene);
+
+ if (indexMethod == "linear")
+ index = new QGraphicsSceneLinearIndex(scene);
+
+ return index;
+}
+
+void tst_QGraphicsSceneIndex::customIndex_data()
+{
+ common_data();
+}
+
+void tst_QGraphicsSceneIndex::customIndex()
+{
+#if 0
+ QFETCH(QString, indexMethod);
+ QGraphicsSceneIndex *index = createIndex(indexMethod);
+
+ QGraphicsScene scene;
+ scene.setSceneIndex(index);
+
+ scene.addRect(0, 0, 30, 40);
+ QCOMPARE(scene.items(QRectF(0, 0, 10, 10)).count(), 1);
+#endif
+}
+
+void tst_QGraphicsSceneIndex::scatteredItems_data()
+{
+ common_data();
+}
+
+void tst_QGraphicsSceneIndex::scatteredItems()
+{
+ QFETCH(QString, indexMethod);
+
+ QGraphicsScene scene;
+#if 1
+ scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex);
+#else
+ QGraphicsSceneIndex *index = createIndex(indexMethod);
+ scene.setSceneIndex(index);
+#endif
+
+ for (int i = 0; i < 10; ++i)
+ scene.addRect(i*50, i*50, 40, 35);
+
+ QCOMPARE(scene.items(QPointF(5, 5)).count(), 1);
+ QCOMPARE(scene.items(QPointF(55, 55)).count(), 1);
+ QCOMPARE(scene.items(QPointF(-100, -100)).count(), 0);
+
+ QCOMPARE(scene.items(QRectF(0, 0, 10, 10)).count(), 1);
+ QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 10);
+ QCOMPARE(scene.items(QRectF(-100, -1000, 0, 0)).count(), 0);
+}
+
+void tst_QGraphicsSceneIndex::overlappedItems_data()
+{
+ common_data();
+}
+
+void tst_QGraphicsSceneIndex::overlappedItems()
+{
+ QFETCH(QString, indexMethod);
+
+ QGraphicsScene scene;
+#if 1
+ scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex);
+#else
+ QGraphicsSceneIndex *index = createIndex(indexMethod);
+ scene.setSceneIndex(index);
+#endif
+
+ for (int i = 0; i < 10; ++i)
+ for (int j = 0; j < 10; ++j)
+ scene.addRect(i*50, j*50, 200, 200);
+
+ QCOMPARE(scene.items(QPointF(5, 5)).count(), 1);
+ QCOMPARE(scene.items(QPointF(55, 55)).count(), 4);
+ QCOMPARE(scene.items(QPointF(105, 105)).count(), 9);
+ QCOMPARE(scene.items(QPointF(-100, -100)).count(), 0);
+
+ QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 100);
+ QCOMPARE(scene.items(QRectF(-100, -1000, 0, 0)).count(), 0);
+ QCOMPARE(scene.items(QRectF(0, 0, 200, 200)).count(), 16);
+ QCOMPARE(scene.items(QRectF(0, 0, 100, 100)).count(), 4);
+ QCOMPARE(scene.items(QRectF(0, 0, 1, 100)).count(), 2);
+ QCOMPARE(scene.items(QRectF(0, 0, 1, 1000)).count(), 10);
+}
+
+void tst_QGraphicsSceneIndex::movingItems_data()
+{
+ common_data();
+}
+
+void tst_QGraphicsSceneIndex::movingItems()
+{
+ QFETCH(QString, indexMethod);
+
+ QGraphicsScene scene;
+#if 1
+ scene.setItemIndexMethod(indexMethod == "linear" ? QGraphicsScene::NoIndex : QGraphicsScene::BspTreeIndex);
+#else
+ QGraphicsSceneIndex *index = createIndex(indexMethod);
+ scene.setSceneIndex(index);
+#endif
+
+ for (int i = 0; i < 10; ++i)
+ scene.addRect(i*50, i*50, 40, 35);
+
+ QGraphicsRectItem *box = scene.addRect(0, 0, 10, 10);
+ QCOMPARE(scene.items(QPointF(5, 5)).count(), 2);
+ QCOMPARE(scene.items(QPointF(-1, -1)).count(), 0);
+ QCOMPARE(scene.items(QRectF(0, 0, 5, 5)).count(), 2);
+
+ box->setPos(10, 10);
+ QCOMPARE(scene.items(QPointF(9, 9)).count(), 1);
+ QCOMPARE(scene.items(QPointF(15, 15)).count(), 2);
+ QCOMPARE(scene.items(QRectF(0, 0, 1, 1)).count(), 1);
+
+ box->setPos(-5, -5);
+ QCOMPARE(scene.items(QPointF(-1, -1)).count(), 1);
+ QCOMPARE(scene.items(QRectF(0, 0, 1, 1)).count(), 2);
+
+ QCOMPARE(scene.items(QRectF(0, 0, 1000, 1000)).count(), 11);
+}
+
+void tst_QGraphicsSceneIndex::connectedToSceneRectChanged()
+{
+
+ class MyScene : public QGraphicsScene
+ { public: using QGraphicsScene::receivers; };
+
+ MyScene scene; // Uses QGraphicsSceneBspTreeIndex by default.
+ QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(const QRectF&))), 1);
+
+ scene.setItemIndexMethod(QGraphicsScene::NoIndex); // QGraphicsSceneLinearIndex
+ QCOMPARE(scene.receivers(SIGNAL(sceneRectChanged(const QRectF&))), 1);
+}
+
+void tst_QGraphicsSceneIndex::items()
+{
+ QGraphicsScene scene;
+ QGraphicsItem *item1 = scene.addRect(0, 0, 10, 10);
+ QGraphicsItem *item2 = scene.addRect(10, 10, 10, 10);
+ QCOMPARE(scene.items().size(), 2);
+
+ // Move from unindexed items into bsp tree.
+ QTest::qWait(50);
+ QCOMPARE(scene.items().size(), 2);
+
+ // Add untransformable item.
+ QGraphicsItem *item3 = new QGraphicsRectItem(QRectF(20, 20, 10, 10));
+ item3->setFlag(QGraphicsItem::ItemIgnoresTransformations);
+ scene.addItem(item3);
+ QCOMPARE(scene.items().size(), 3);
+
+ // Move from unindexed items into untransformable items.
+ QTest::qWait(50);
+ QCOMPARE(scene.items().size(), 3);
+
+ // Move from untransformable items into unindexed items.
+ item3->setFlag(QGraphicsItem::ItemIgnoresTransformations, false);
+ QCOMPARE(scene.items().size(), 3);
+ QTest::qWait(50);
+ QCOMPARE(scene.items().size(), 3);
+
+ // Make all items untransformable.
+ item1->setFlag(QGraphicsItem::ItemIgnoresTransformations);
+ item2->setParentItem(item1);
+ item3->setParentItem(item2);
+ QCOMPARE(scene.items().size(), 3);
+
+ // Move from unindexed items into untransformable items.
+ QTest::qWait(50);
+ QCOMPARE(scene.items().size(), 3);
+}
+
+QTEST_MAIN(tst_QGraphicsSceneIndex)
+#include "tst_qgraphicssceneindex.moc"
diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
index 8b4ca4c..9a5089b 100644
--- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
+++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
@@ -64,6 +64,7 @@
#include <QtGui/QStyle>
#include <QtGui/QPushButton>
#include <QtGui/QInputContext>
+#include <private/qgraphicsview_p.h>
//TESTED_CLASS=
//TESTED_FILES=
@@ -176,6 +177,7 @@ private slots:
void transformationAnchor();
void resizeAnchor();
void viewportUpdateMode();
+ void viewportUpdateMode2();
void acceptDrops();
void optimizationFlags();
void optimizationFlags_dontSavePainterState();
@@ -196,6 +198,8 @@ private slots:
void mouseTracking2();
void render();
void exposeRegion();
+ void update_data();
+ void update();
void inputMethodSensitivity();
void inputContextReset();
@@ -374,6 +378,7 @@ void tst_QGraphicsView::interactive()
QCOMPARE(item->events.size(), 0);
QPoint itemPoint = view.mapFromScene(item->scenePos());
+
QVERIFY(view.itemAt(itemPoint));
for (int i = 0; i < 100; ++i) {
@@ -2109,12 +2114,12 @@ void tst_QGraphicsView::resizeAnchor()
view.setResizeAnchor(QGraphicsView::AnchorViewCenter);
}
view.centerOn(0, 0);
- QTest::qWait(100);
+ QTest::qWait(250);
QPointF f = view.mapToScene(50, 50);
QPointF center = view.mapToScene(view.viewport()->rect().center());
- QTest::qWait(100);
+ QTest::qWait(250);
for (int size = 200; size <= 400; size += 25) {
view.resize(size, size);
@@ -2129,7 +2134,7 @@ void tst_QGraphicsView::resizeAnchor()
QVERIFY(qAbs(newCenter.x() - center.x()) < slack);
QVERIFY(qAbs(newCenter.y() - center.y()) < slack);
}
- QTest::qWait(100);
+ QTest::qWait(250);
}
}
}
@@ -2231,6 +2236,52 @@ void tst_QGraphicsView::viewportUpdateMode()
QCOMPARE(view.lastUpdateRegions.size(), 0);
}
+void tst_QGraphicsView::viewportUpdateMode2()
+{
+ // Create a view with viewport rect equal to QRect(0, 0, 200, 200).
+ QGraphicsScene dummyScene;
+ CustomView view;
+ view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
+ view.setScene(&dummyScene);
+ int left, top, right, bottom;
+ view.getContentsMargins(&left, &top, &right, &bottom);
+ view.resize(200 + left + right, 200 + top + bottom);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(300);
+ const QRect viewportRect = view.viewport()->rect();
+ QCOMPARE(viewportRect, QRect(0, 0, 200, 200));
+ QGraphicsViewPrivate *viewPrivate = static_cast<QGraphicsViewPrivate *>(qt_widget_private(&view));
+
+ QRect boundingRect;
+ const QRect rect1(0, 0, 10, 10);
+ QVERIFY(viewPrivate->updateRect(rect1));
+ QVERIFY(!viewPrivate->fullUpdatePending);
+ boundingRect |= rect1;
+ QCOMPARE(viewPrivate->dirtyBoundingRect, boundingRect);
+
+ const QRect rect2(50, 50, 10, 10);
+ QVERIFY(viewPrivate->updateRect(rect2));
+ QVERIFY(!viewPrivate->fullUpdatePending);
+ boundingRect |= rect2;
+ QCOMPARE(viewPrivate->dirtyBoundingRect, boundingRect);
+
+ const QRect rect3(190, 190, 10, 10);
+ QVERIFY(viewPrivate->updateRect(rect3));
+ QVERIFY(viewPrivate->fullUpdatePending);
+ boundingRect |= rect3;
+ QCOMPARE(viewPrivate->dirtyBoundingRect, boundingRect);
+
+ view.lastUpdateRegions.clear();
+ viewPrivate->processPendingUpdates();
+ QTest::qWait(50);
+ QCOMPARE(view.lastUpdateRegions.size(), 1);
+ // Note that we adjust by 2 for antialiasing.
+ QCOMPARE(view.lastUpdateRegions.at(0), QRegion(boundingRect.adjusted(-2, -2, 2, 2) & viewportRect));
+}
+
void tst_QGraphicsView::acceptDrops()
{
QGraphicsView view;
@@ -2991,14 +3042,7 @@ void tst_QGraphicsView::embeddedViews()
v2->QWidget::render(&actual);
QTransform b = item->transform;
-#ifdef Q_WS_MAC
- // We don't use shared painter on the Mac, so the
- // transform should be exactly the same.
QVERIFY(a == b);
-#else
- QVERIFY(a != b);
-#endif
-
delete v1;
}
@@ -3095,7 +3139,7 @@ void tst_QGraphicsView::moveItemWhileScrolling()
#ifdef Q_WS_X11
qt_x11_wait_for_window_manager(&view);
#endif
- QTest::qWait(100);
+ QTest::qWait(200);
view.lastPaintedRegion = QRegion();
view.horizontalScrollBar()->setValue(view.horizontalScrollBar()->value() + 10);
@@ -3267,7 +3311,9 @@ void tst_QGraphicsView::mouseTracking2()
EventSpy spy(&scene, QEvent::GraphicsSceneMouseMove);
QCOMPARE(spy.count(), 0);
- sendMouseMove(view.viewport(), view.viewport()->rect().center());
+ QMouseEvent event(QEvent::MouseMove,view.viewport()->rect().center(), Qt::NoButton,
+ Qt::MouseButtons(Qt::NoButton), 0);
+ QApplication::sendEvent(view.viewport(), &event);
QCOMPARE(spy.count(), 1);
}
@@ -3360,6 +3406,72 @@ void tst_QGraphicsView::exposeRegion()
QCOMPARE(item->paints, 0);
}
+void tst_QGraphicsView::update_data()
+{
+ // In view.viewport() coordinates. (viewport rect: QRect(0, 0, 200, 200))
+ QTest::addColumn<QRect>("updateRect");
+ QTest::newRow("empty") << QRect();
+ QTest::newRow("outside left") << QRect(-200, 0, 100, 100);
+ QTest::newRow("outside right") << QRect(400, 0 ,100, 100);
+ QTest::newRow("outside top") << QRect(0, -200, 100, 100);
+ QTest::newRow("outside bottom") << QRect(0, 400, 100, 100);
+ QTest::newRow("partially inside left") << QRect(-50, 0, 100, 100);
+ QTest::newRow("partially inside right") << QRect(-150, 0, 100, 100);
+ QTest::newRow("partially inside top") << QRect(0, -150, 100, 100);
+ QTest::newRow("partially inside bottom") << QRect(0, 150, 100, 100);
+ QTest::newRow("on topLeft edge") << QRect(-100, -100, 100, 100);
+ QTest::newRow("on topRight edge") << QRect(200, -100, 100, 100);
+ QTest::newRow("on bottomRight edge") << QRect(200, 200, 100, 100);
+ QTest::newRow("on bottomLeft edge") << QRect(-200, 200, 100, 100);
+ QTest::newRow("inside topLeft") << QRect(-99, -99, 100, 100);
+ QTest::newRow("inside topRight") << QRect(199, -99, 100, 100);
+ QTest::newRow("inside bottomRight") << QRect(199, 199, 100, 100);
+ QTest::newRow("inside bottomLeft") << QRect(-199, 199, 100, 100);
+ QTest::newRow("large1") << QRect(50, -100, 100, 400);
+ QTest::newRow("large2") << QRect(-100, 50, 400, 100);
+ QTest::newRow("large3") << QRect(-100, -100, 400, 400);
+ QTest::newRow("viewport rect") << QRect(0, 0, 200, 200);
+}
+
+void tst_QGraphicsView::update()
+{
+ QFETCH(QRect, updateRect);
+
+ // Create a view with viewport rect equal to QRect(0, 0, 200, 200).
+ QGraphicsScene dummyScene;
+ CustomView view;
+ view.setScene(&dummyScene);
+ int left, top, right, bottom;
+ view.getContentsMargins(&left, &top, &right, &bottom);
+ view.resize(200 + left + right, 200 + top + bottom);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(300);
+ const QRect viewportRect = view.viewport()->rect();
+ QCOMPARE(viewportRect, QRect(0, 0, 200, 200));
+
+ const bool intersects = updateRect.intersects(viewportRect);
+ QGraphicsViewPrivate *viewPrivate = static_cast<QGraphicsViewPrivate *>(qt_widget_private(&view));
+ QCOMPARE(viewPrivate->updateRect(updateRect), intersects);
+ QCOMPARE(viewPrivate->updateRegion(updateRect), intersects);
+
+ view.lastUpdateRegions.clear();
+ viewPrivate->processPendingUpdates();
+ QVERIFY(viewPrivate->dirtyRegion.isEmpty());
+ QVERIFY(viewPrivate->dirtyBoundingRect.isEmpty());
+ QTest::qWait(50);
+ if (!intersects) {
+ QVERIFY(view.lastUpdateRegions.isEmpty());
+ } else {
+ QCOMPARE(view.lastUpdateRegions.size(), 1);
+ // Note that we adjust by 2 for antialiasing.
+ QCOMPARE(view.lastUpdateRegions.at(0), QRegion(updateRect.adjusted(-2, -2, 2, 2) & viewportRect));
+ }
+ QVERIFY(!viewPrivate->fullUpdatePending);
+}
+
void tst_QGraphicsView::inputMethodSensitivity()
{
QGraphicsScene scene;
diff --git a/tests/auto/qhttpnetworkconnection/qhttpnetworkconnection.pro b/tests/auto/qhttpnetworkconnection/qhttpnetworkconnection.pro
index 3283873..e19d962 100644
--- a/tests/auto/qhttpnetworkconnection/qhttpnetworkconnection.pro
+++ b/tests/auto/qhttpnetworkconnection/qhttpnetworkconnection.pro
@@ -2,4 +2,6 @@ load(qttest_p4)
SOURCES += tst_qhttpnetworkconnection.cpp
INCLUDEPATH += $$(QTDIR)/src/3rdparty/zlib
+requires(contains(QT_CONFIG,private_tests))
+
QT = core network
diff --git a/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro b/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro
index 2e41fcd..f86250a 100644
--- a/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro
+++ b/tests/auto/qhttpnetworkreply/qhttpnetworkreply.pro
@@ -2,4 +2,6 @@ load(qttest_p4)
SOURCES += tst_qhttpnetworkreply.cpp
INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/zlib
+requires(contains(QT_CONFIG,private_tests))
+
QT = core network
diff --git a/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp b/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp
index d9a7d56..e235ff5 100644
--- a/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp
+++ b/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp
@@ -59,13 +59,13 @@ void tst_QItemEditorFactory::createEditor()
QCOMPARE(w->metaObject()->className(), "QExpandingLineEdit");
}
-void tst_QItemEditorFactory::createCustomEditor()
+//we make it inherit from QObject so that we can use QPointer
+class MyEditor : public QObject, public QStandardItemEditorCreator<QDoubleSpinBox>
{
- //we make it inherit from QObject so that we can use QPointer
- class MyEditor : public QObject, public QStandardItemEditorCreator<QDoubleSpinBox>
- {
- };
+};
+void tst_QItemEditorFactory::createCustomEditor()
+{
QPointer<MyEditor> creator = new MyEditor;
QPointer<MyEditor> creator2 = new MyEditor;
diff --git a/tests/auto/qkeysequence/tst_qkeysequence.cpp b/tests/auto/qkeysequence/tst_qkeysequence.cpp
index aeb57ef..2e4b850 100644
--- a/tests/auto/qkeysequence/tst_qkeysequence.cpp
+++ b/tests/auto/qkeysequence/tst_qkeysequence.cpp
@@ -270,7 +270,7 @@ void tst_QKeySequence::checkMultipleNames()
void tst_QKeySequence::ensureSorted()
{
//### accessing static members from private classes does not work on msvc at the moment
-#ifndef Q_WS_WIN
+#if defined(QT_BUILD_INTERNAL) && !defined(Q_WS_WIN)
uint N = QKeySequencePrivate::numberOfKeyBindings;
uint val = QKeySequencePrivate::keyBindings[0].shortcut;
for ( uint i = 1 ; i < N ; ++i) {
diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp
index 0f636a4..a41eecd 100644
--- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp
+++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp
@@ -104,6 +104,7 @@ private slots:
void recycleServer();
void multiConnect();
+ void writeOnlySocket();
void debug();
@@ -906,6 +907,22 @@ void tst_QLocalSocket::multiConnect()
QVERIFY(server.nextPendingConnection() != 0);
}
+void tst_QLocalSocket::writeOnlySocket()
+{
+ QLocalServer server;
+ QVERIFY(server.listen("writeOnlySocket"));
+
+ QLocalSocket client;
+ client.connectToServer("writeOnlySocket", QIODevice::WriteOnly);
+ QVERIFY(client.waitForConnected());
+
+ QVERIFY(server.waitForNewConnection());
+ QLocalSocket* serverSocket = server.nextPendingConnection();
+
+ QCOMPARE(client.bytesAvailable(), qint64(0));
+ QCOMPARE(client.state(), QLocalSocket::ConnectedState);
+}
+
void tst_QLocalSocket::debug()
{
// Make sure this compiles
diff --git a/tests/auto/qmainwindow/tst_qmainwindow.cpp b/tests/auto/qmainwindow/tst_qmainwindow.cpp
index e46c2e1..6ae7a3e 100644
--- a/tests/auto/qmainwindow/tst_qmainwindow.cpp
+++ b/tests/auto/qmainwindow/tst_qmainwindow.cpp
@@ -1400,6 +1400,7 @@ void AddDockWidget::apply(QMainWindow *mw) const
}
}
+#ifdef QT_BUILD_INTERNAL
struct MoveSeparator
{
MoveSeparator() {}
@@ -1436,6 +1437,7 @@ void MoveSeparator::apply(QMainWindow *mw) const
l->layoutState.dockAreaLayout.separatorMove(path, QPoint(0, 0), QPoint(delta, delta));
}
+#endif
QMap<QString, QRect> dockWidgetGeometries(QMainWindow *mw)
{
@@ -1463,6 +1465,7 @@ QMap<QString, QRect> dockWidgetGeometries(QMainWindow *mw)
void tst_QMainWindow::saveRestore_data()
{
+#ifdef QT_BUILD_INTERNAL
QTest::addColumn<AddList >("addList");
QTest::addColumn<MoveList >("moveList");
@@ -1497,10 +1500,12 @@ void tst_QMainWindow::saveRestore_data()
<< MoveSeparator(-30, "right1")
<< MoveSeparator(30, "right2a")
);
+#endif
}
void tst_QMainWindow::saveRestore()
{
+#ifdef QT_BUILD_INTERNAL
QFETCH(AddList, addList);
QFETCH(MoveList, moveList);
@@ -1570,6 +1575,7 @@ void tst_QMainWindow::saveRestore()
mainWindow.show();
COMPARE_DOCK_WIDGET_GEOS(dockWidgetGeos, dockWidgetGeometries(&mainWindow));
}
+#endif
}
void tst_QMainWindow::iconSizeChanged()
diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp
index 500465c..1245de1 100644
--- a/tests/auto/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/qmenubar/tst_qmenubar.cpp
@@ -1576,8 +1576,9 @@ void tst_QMenuBar::menubarSizeHint()
return 11;
case PM_MenuBarPanelWidth:
return 1;
+ default:
+ return QWindowsStyle::pixelMetric(metric, option, widget);
}
- return QWindowsStyle::pixelMetric(metric, option, widget);
}
} style;
diff --git a/tests/auto/qnativesocketengine/qnativesocketengine.pro b/tests/auto/qnativesocketengine/qnativesocketengine.pro
index 320f24c..ad40d53 100644
--- a/tests/auto/qnativesocketengine/qnativesocketengine.pro
+++ b/tests/auto/qnativesocketengine/qnativesocketengine.pro
@@ -3,6 +3,8 @@ SOURCES += tst_qnativesocketengine.cpp
include(../qnativesocketengine/qsocketengine.pri)
+requires(contains(QT_CONFIG,private_tests))
+
MOC_DIR=tmp
QT = core network
diff --git a/tests/auto/qnetworkreply/qnetworkreply.pro b/tests/auto/qnetworkreply/qnetworkreply.pro
index 0bcf067..fd8454c 100644
--- a/tests/auto/qnetworkreply/qnetworkreply.pro
+++ b/tests/auto/qnetworkreply/qnetworkreply.pro
@@ -1,4 +1,6 @@
TEMPLATE = subdirs
SUBDIRS = test
+requires(contains(QT_CONFIG,private_tests))
+
!wince*:SUBDIRS += echo
diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
index 89e850c..8318b60 100644
--- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
@@ -245,6 +245,8 @@ private Q_SLOTS:
void authorizationError();
void httpConnectionCount();
+ void httpDownloadPerformance_data();
+ void httpDownloadPerformance();
};
QT_BEGIN_NAMESPACE
@@ -3696,5 +3698,128 @@ void tst_QNetworkReply::httpConnectionCount()
QCOMPARE(pendingConnectionCount, 6);
}
+class HttpDownloadPerformanceClient : QObject {
+ Q_OBJECT;
+ QIODevice *device;
+ public:
+ HttpDownloadPerformanceClient (QIODevice *dev) : device(dev){
+ connect(dev, SIGNAL(readyRead()), this, SLOT(readyReadSlot()));
+ }
+
+ public slots:
+ void readyReadSlot() {
+ device->readAll();
+ }
+
+};
+
+class HttpDownloadPerformanceServer : QObject {
+ Q_OBJECT;
+ qint64 dataSize;
+ qint64 dataSent;
+ QTcpServer server;
+ QTcpSocket *client;
+ bool serverSendsContentLength;
+ bool chunkedEncoding;
+
+public:
+ HttpDownloadPerformanceServer (qint64 ds, bool sscl, bool ce) : dataSize(ds), dataSent(0),
+ client(0), serverSendsContentLength(sscl), chunkedEncoding(ce) {
+ server.listen();
+ connect(&server, SIGNAL(newConnection()), this, SLOT(newConnectionSlot()));
+ }
+
+ int serverPort() {
+ return server.serverPort();
+ }
+
+public slots:
+
+ void newConnectionSlot() {
+ client = server.nextPendingConnection();
+ client->setParent(this);
+ connect(client, SIGNAL(readyRead()), this, SLOT(readyReadSlot()));
+ connect(client, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWrittenSlot(qint64)));
+ }
+
+ void readyReadSlot() {
+ client->readAll();
+ client->write("HTTP/1.0 200 OK\n");
+ if (serverSendsContentLength)
+ client->write(QString("Content-Length: " + QString::number(dataSize) + "\n").toAscii());
+ if (chunkedEncoding)
+ client->write(QString("Transfer-Encoding: chunked\n").toAscii());
+ client->write("Connection: close\n\n");
+ }
+
+ void bytesWrittenSlot(qint64 amount) {
+ if (dataSent == dataSize && client) {
+ // close eventually
+
+ // chunked encoding: we have to send a last "empty" chunk
+ if (chunkedEncoding)
+ client->write(QString("0\r\n\r\n").toAscii());
+
+ client->disconnectFromHost();
+ server.close();
+ client = 0;
+ return;
+ }
+
+ // send data
+ if (client && client->bytesToWrite() < 100*1024 && dataSent < dataSize) {
+ qint64 amount = qMin(qint64(16*1024), dataSize - dataSent);
+ QByteArray data(amount, '@');
+
+ if (chunkedEncoding) {
+ client->write(QString(QString("%1").arg(amount,0,16).toUpper() + "\r\n").toAscii());
+ client->write(data.constData(), amount);
+ client->write(QString("\r\n").toAscii());
+ } else {
+ client->write(data.constData(), amount);
+ }
+
+ dataSent += amount;
+ }
+ }
+};
+
+void tst_QNetworkReply::httpDownloadPerformance_data()
+{
+ QTest::addColumn<bool>("serverSendsContentLength");
+ QTest::addColumn<bool>("chunkedEncoding");
+
+ QTest::newRow("Server sends no Content-Length") << false << false;
+ QTest::newRow("Server sends Content-Length") << true << false;
+ QTest::newRow("Server uses chunked encoding") << false << true;
+
+}
+
+void tst_QNetworkReply::httpDownloadPerformance()
+{
+ QFETCH(bool, serverSendsContentLength);
+ QFETCH(bool, chunkedEncoding);
+
+ enum {UploadSize = 1000*1024*1024}; // 1000 MB
+ HttpDownloadPerformanceServer server(UploadSize, serverSendsContentLength, chunkedEncoding);
+
+ QNetworkRequest request(QUrl("http://127.0.0.1:" + QString::number(server.serverPort()) + "/?bare=1"));
+ QNetworkReply* reply = manager.get(request);
+
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection);
+ HttpDownloadPerformanceClient client(reply);
+
+ QTime time;
+ time.start();
+ QTestEventLoop::instance().enterLoop(40);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ qint64 elapsed = time.elapsed();
+ qWarning() << "tst_QNetworkReply::httpDownloadPerformance" << elapsed << "msec, "
+ << ((UploadSize/1024.0)/(elapsed/1000.0)) << " kB/sec";
+
+ delete reply;
+}
+
QTEST_MAIN(tst_QNetworkReply)
#include "tst_qnetworkreply.moc"
diff --git a/tests/auto/qpathclipper/qpathclipper.pro b/tests/auto/qpathclipper/qpathclipper.pro
index 675e463..dc9d60f 100644
--- a/tests/auto/qpathclipper/qpathclipper.pro
+++ b/tests/auto/qpathclipper/qpathclipper.pro
@@ -3,6 +3,8 @@ INCLUDEPATH += .
HEADERS += paths.h
SOURCES += tst_qpathclipper.cpp paths.cpp
+requires(contains(QT_CONFIG,private_tests))
+
unix:!mac:LIBS+=-lm
diff --git a/tests/auto/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/qplaintextedit/tst_qplaintextedit.cpp
index fceefd2..40ad539 100644
--- a/tests/auto/qplaintextedit/tst_qplaintextedit.cpp
+++ b/tests/auto/qplaintextedit/tst_qplaintextedit.cpp
@@ -1106,6 +1106,7 @@ void tst_QPlainTextEdit::mimeDataReimplementations()
QCOMPARE(ed.canInsertCallCount, 0);
QCOMPARE(ed.insertCallCount, 0);
+#ifdef QT_BUILD_INTERNAL
QTextControl *control = qFindChild<QTextControl *>(&ed);
QVERIFY(control);
@@ -1120,6 +1121,7 @@ void tst_QPlainTextEdit::mimeDataReimplementations()
QCOMPARE(ed.createMimeDataCallCount, 1);
QCOMPARE(ed.canInsertCallCount, 1);
QCOMPARE(ed.insertCallCount, 1);
+#endif
}
void tst_QPlainTextEdit::shiftEnterShouldInsertLineSeparator()
diff --git a/tests/auto/qregion/tst_qregion.cpp b/tests/auto/qregion/tst_qregion.cpp
index 3ffa87e..2ad202d 100644
--- a/tests/auto/qregion/tst_qregion.cpp
+++ b/tests/auto/qregion/tst_qregion.cpp
@@ -96,7 +96,7 @@ private slots:
#ifdef Q_OS_WIN
void handle();
#endif
-#ifdef Q_WS_X11
+#if defined(Q_WS_X11) && defined(QT_BUILD_INTERNAL)
void clipRectangles();
#endif
@@ -865,7 +865,7 @@ void tst_QRegion::handle()
}
#endif
-#ifdef Q_WS_X11
+#if defined(Q_WS_X11) && defined(QT_BUILD_INTERNAL)
void tst_QRegion::clipRectangles()
{
QRegion region(30, 30, 30, 30);
@@ -967,6 +967,7 @@ void tst_QRegion::regionToPath_data()
void tst_QRegion::regionToPath()
{
+#ifdef QT_BUILD_INTERNAL
extern QPainterPath qt_regionToPath(const QRegion &region);
QFETCH(QPainterPath, path);
@@ -1002,6 +1003,7 @@ void tst_QRegion::regionToPath()
QCOMPARE(ia, ib);
QCOMPARE(a.boundingRect(), b.boundingRect());
}
+#endif
}
QTEST_MAIN(tst_QRegion)
diff --git a/tests/auto/qsettings/tst_qsettings.cpp b/tests/auto/qsettings/tst_qsettings.cpp
index f0f446d..77fef1f 100644
--- a/tests/auto/qsettings/tst_qsettings.cpp
+++ b/tests/auto/qsettings/tst_qsettings.cpp
@@ -713,6 +713,7 @@ void tst_QSettings::testErrorHandling_data()
void tst_QSettings::testErrorHandling()
{
+#ifdef QT_BUILD_INTERNAL
#ifdef Q_OS_WIN
QSKIP("Windows doesn't support most file modes, including read-only directories, so this test is moot.", SkipAll);
#else
@@ -776,6 +777,7 @@ void tst_QSettings::testErrorHandling()
QCOMPARE((int)settings.status(), statusAfterSetAndSync);
}
#endif // !Q_OS_WIN
+#endif
}
Q_DECLARE_METATYPE(QVariant)
@@ -821,6 +823,7 @@ void tst_QSettings::testIniParsing_data()
void tst_QSettings::testIniParsing()
{
+#ifdef QT_BUILD_INTERNAL
qRegisterMetaType<QVariant>("QVariant");
qRegisterMetaType<QSettings::Status>("QSettings::Status");
@@ -854,6 +857,7 @@ void tst_QSettings::testIniParsing()
}
QCOMPARE(settings.status(), status);
+#endif
}
/*
@@ -1058,6 +1062,7 @@ void tst_QSettings::testVariantTypes_data()
void tst_QSettings::testVariantTypes()
{
+#ifdef QT_BUILD_INTERNAL
#define testVal(key, val, tp, rtype) \
{ \
QSettings settings1(format, QSettings::UserScope, "software.org", "KillerAPP"); \
@@ -1141,6 +1146,7 @@ void tst_QSettings::testVariantTypes()
}
#undef testVal
+#endif
}
void tst_QSettings::remove()
@@ -1801,9 +1807,7 @@ void tst_QSettings::testNormalizedKey_data()
void tst_QSettings::testNormalizedKey()
{
-#ifdef QTEST_REDUCED_EXPORTS
- QSKIP("We can't test QSettingsPrivate on Windows", SkipAll);
-#else
+#ifdef QT_BUILD_INTERNAL
QFETCH(QString, inKey);
QFETCH(QString, outKey);
@@ -1981,6 +1985,7 @@ void tst_QSettings::fromFile()
void tst_QSettings::setIniCodec()
{
+#ifdef QT_BUILD_INTERNAL
QByteArray expeContents4, expeContents5;
QByteArray actualContents4, actualContents5;
@@ -2040,6 +2045,7 @@ void tst_QSettings::setIniCodec()
QCOMPARE(settings4.allKeys().first(), settings5.allKeys().first());
QCOMPARE(settings4.value(settings4.allKeys().first()).toString(),
settings5.value(settings5.allKeys().first()).toString());
+#endif
}
static bool containsSubList(QStringList mom, QStringList son)
@@ -2316,6 +2322,7 @@ void tst_QSettings::testArrays()
settings1.endArray();
}
+#ifdef QT_BUILD_INTERNAL
static QByteArray iniEscapedKey(const QString &str)
{
QByteArray result;
@@ -2360,6 +2367,7 @@ static QStringList iniUnescapedStringList(const QByteArray &ba)
#endif
return result;
}
+#endif
QString escapeWeirdChars(const QString &s)
{
@@ -2383,6 +2391,7 @@ QString escapeWeirdChars(const QString &s)
void tst_QSettings::testEscapes()
{
+#ifdef QT_BUILD_INTERNAL
QSettings settings(QSettings::UserScope, "software.org", "KillerAPP");
#define testEscapedKey(plainKey, escKey) \
@@ -2505,6 +2514,7 @@ void tst_QSettings::testEscapes()
testBadEscape("@Rect)", "@Rect)");
testBadEscape("@Rect(1 2 3)", "@Rect(1 2 3)");
testBadEscape("@@Rect(1 2 3)", "@Rect(1 2 3)");
+#endif
}
void tst_QSettings::testCompatFunctions()
@@ -3355,6 +3365,7 @@ void tst_QSettings::childGroups_data()
void tst_QSettings::childGroups()
{
+#ifdef QT_BUILD_INTERNAL
QFETCH(QSettings::Format, format);
{
@@ -3408,6 +3419,7 @@ void tst_QSettings::childGroups()
QCOMPARE(settings.childGroups(), QStringList() << "alpha" << "gamma" << "omicron" << "zeta");
}
+#endif
}
void tst_QSettings::childKeys_data()
@@ -3417,6 +3429,7 @@ void tst_QSettings::childKeys_data()
void tst_QSettings::childKeys()
{
+#ifdef QT_BUILD_INTERNAL
QFETCH(QSettings::Format, format);
{
@@ -3470,6 +3483,7 @@ void tst_QSettings::childKeys()
QCOMPARE(settings.childKeys(), QStringList() << "alpha" << "beta" << "gamma");
}
+#endif
}
void tst_QSettings::allKeys_data()
@@ -3479,6 +3493,7 @@ void tst_QSettings::allKeys_data()
void tst_QSettings::allKeys()
{
+#ifdef QT_BUILD_INTERNAL
QFETCH(QSettings::Format, format);
QStringList allKeys;
@@ -3527,6 +3542,7 @@ void tst_QSettings::allKeys()
QCOMPARE(settings.allKeys(), allKeys);
}
+#endif
}
void tst_QSettings::registerFormat()
diff --git a/tests/auto/qsharedpointer/qsharedpointer.pro b/tests/auto/qsharedpointer/qsharedpointer.pro
index 30c81cb..90fde06 100644
--- a/tests/auto/qsharedpointer/qsharedpointer.pro
+++ b/tests/auto/qsharedpointer/qsharedpointer.pro
@@ -4,5 +4,6 @@ SOURCES += tst_qsharedpointer.cpp \
forwarddeclared.cpp
QT = core
DEFINES += SRCDIR=\\\"$$PWD/\\\"
+requires(contains(QT_CONFIG,private_tests))
include(externaltests.pri)
HEADERS += forwarddeclared.h
diff --git a/tests/auto/qsocketnotifier/qsocketnotifier.pro b/tests/auto/qsocketnotifier/qsocketnotifier.pro
index 10ed3a5..ec924c1 100644
--- a/tests/auto/qsocketnotifier/qsocketnotifier.pro
+++ b/tests/auto/qsocketnotifier/qsocketnotifier.pro
@@ -2,6 +2,8 @@ load(qttest_p4)
SOURCES += tst_qsocketnotifier.cpp
QT = core network
+requires(contains(QT_CONFIG,private_tests))
+
include(../qnativesocketengine/qsocketengine.pri)
diff --git a/tests/auto/qsocks5socketengine/qsocks5socketengine.pro b/tests/auto/qsocks5socketengine/qsocks5socketengine.pro
index 2949ee2..d19b732 100644
--- a/tests/auto/qsocks5socketengine/qsocks5socketengine.pro
+++ b/tests/auto/qsocks5socketengine/qsocks5socketengine.pro
@@ -11,3 +11,4 @@ QT = core network
+requires(contains(QT_CONFIG,private_tests))
diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h
index c6b65a4..9c8c313 100644
--- a/tests/auto/qsqldatabase/tst_databases.h
+++ b/tests/auto/qsqldatabase/tst_databases.h
@@ -105,7 +105,11 @@ inline static QString qTableName( const QString& prefix, QSqlDriver* driver = 0
inline static bool testWhiteSpaceNames( const QString &name )
{
- return name != QLatin1String("QTDS7");
+/* return name.startsWith( "QPSQL" )
+ || name.startsWith( "QODBC" )
+ || name.startsWith( "QSQLITE" )
+ || name.startsWith( "QMYSQL" );*/
+ return name != QLatin1String("QSQLITE2");
}
inline static QString toHex( const QString& binary )
@@ -245,10 +249,11 @@ public:
// addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.nokia.troll.no\\SQLEXPRESS", "troll", "trond", "" );
// addDb( "QODBC", "DRIVER={MySQL ODBC 3.51 Driver};SERVER=mysql5-nokia.trolltech.com.au;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
-// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk;TDS_Version=8.0", "troll", "trondk", "" );
-// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.nokia.troll.no;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond;TDS_Version=8.0", "troll", "trond", "" );
-// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "testuser", "Ee4Gabf6_", "" );
-// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "testuser", "Ee4Gabf6_", "" );
+// addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=mysql4-nokia.trolltech.com.au;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
+// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk", "troll", "trondk", "" );
+// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.nokia.troll.no;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond", "troll", "trond", "" );
+// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" );
+// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" );
// addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2003" );
// addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2008" );
// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" );
@@ -469,6 +474,16 @@ public:
return db.databaseName().contains( "Access Driver", Qt::CaseInsensitive );
}
+ static bool isPostgreSQL( QSqlDatabase db )
+ {
+ return db.driverName().startsWith("QPSQL") || (db.driverName().startsWith("QODBC") && db.databaseName().contains("PostgreSQL") );
+ }
+
+ static bool isMySQL( QSqlDatabase db )
+ {
+ return db.driverName().startsWith("QMYSQL") || (db.driverName().startsWith("QODBC") && db.databaseName().contains("MySQL") );
+ }
+
// -1 on fail, else Oracle version
static int getOraVersion( QSqlDatabase db )
{
diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp
index a5095f1..994a3d7 100644
--- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp
+++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp
@@ -188,7 +188,7 @@ private slots:
void oci_fieldLength_data() { generic_data("QOCI"); }
void oci_fieldLength();
- void sqlite_bindAndFetchUInt_data() { generic_data("QSQLITE3"); }
+ void sqlite_bindAndFetchUInt_data() { generic_data("QSQLITE"); }
void sqlite_bindAndFetchUInt();
void sqlStatementUseIsNull_189093_data() { generic_data(); }
@@ -256,6 +256,8 @@ static int createFieldTable(const FieldDef fieldDefs[], QSqlDatabase db)
QString autoName = tst_Databases::autoFieldName(db);
if (tst_Databases::isMSAccess(db))
qs.append(" (id int not null");
+ else if (tst_Databases::isPostgreSQL(db))
+ qs.append(" (id serial not null");
else
qs.append(QString("(id integer not null %1 primary key").arg(autoName));
@@ -916,7 +918,7 @@ void tst_QSqlDatabase::recordOCI()
FieldDef("varchar(20)", QVariant::String, QString("blah2")),
FieldDef("nchar(20)", QVariant::String, QString("blah3")),
FieldDef("nvarchar2(20)", QVariant::String, QString("blah4")),
- FieldDef("number(10,5)", QVariant::String, 1.1234567),
+ FieldDef("number(10,5)", QVariant::Double, 1.1234567),
FieldDef("date", QVariant::DateTime, dt),
#ifdef QT3_SUPPORT
//X? FieldDef("long raw", QVariant::ByteArray, QByteArray(Q3CString("blah5"))),
@@ -1345,6 +1347,8 @@ void tst_QSqlDatabase::transaction()
}
QVERIFY_SQL(q, exec("select * from " + qTableName("qtest") + " where id = 41"));
+ if(db.driverName().startsWith("QODBC") && dbName.contains("MySQL"))
+ QEXPECT_FAIL("", "Some odbc drivers don't actually roll back despite telling us they do, especially the mysql driver", Continue);
QVERIFY(!q.next());
populateTestTables(db);
@@ -1422,7 +1426,8 @@ void tst_QSqlDatabase::caseSensivity()
bool cs = false;
if (db.driverName().startsWith("QMYSQL")
|| db.driverName().startsWith("QSQLITE")
- || db.driverName().startsWith("QTDS"))
+ || db.driverName().startsWith("QTDS")
+ || db.driverName().startsWith("QODBC"))
cs = true;
QSqlRecord rec = db.record(qTableName("qtest"));
@@ -1521,6 +1526,7 @@ void tst_QSqlDatabase::psql_escapedIdentifiers()
QString field1Name = QString("fIeLdNaMe");
QString field2Name = QString("ZuLu");
+ q.exec(QString("DROP SCHEMA \"%1\" CASCADE").arg(schemaName));
QString createSchema = QString("CREATE SCHEMA \"%1\"").arg(schemaName);
QVERIFY_SQL(q, exec(createSchema));
QString createTable = QString("CREATE TABLE \"%1\".\"%2\" (\"%3\" int PRIMARY KEY, \"%4\" varchar(20))").arg(schemaName).arg(tableName).arg(field1Name).arg(field2Name);
@@ -1652,6 +1658,8 @@ void tst_QSqlDatabase::precisionPolicy()
q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt32);
QVERIFY_SQL(q, exec(query));
+ if(db.driverName().startsWith("QOCI"))
+ QEXPECT_FAIL("", "Oracle fails to move to next when data columns are oversize", Abort);
QVERIFY_SQL(q, next());
if(db.driverName().startsWith("QSQLITE"))
QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue);
@@ -2279,6 +2287,10 @@ void tst_QSqlDatabase::sqlite_bindAndFetchUInt()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
+ if (db.driverName().startsWith("QSQLITE2")) {
+ QSKIP("SQLite3 specific test", SkipSingle);
+ return;
+ }
QSqlQuery q(db);
QString tableName = qTableName("uint_test");
diff --git a/tests/auto/qsqldriver/tst_qsqldriver.cpp b/tests/auto/qsqldriver/tst_qsqldriver.cpp
index 6d428df..b79c093 100644
--- a/tests/auto/qsqldriver/tst_qsqldriver.cpp
+++ b/tests/auto/qsqldriver/tst_qsqldriver.cpp
@@ -158,7 +158,7 @@ void tst_QSqlDriver::record()
//check that we can't get records using incorrect tablename casing that's been quoted
rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName));
- if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS"))
+ if (tst_Databases::isMySQL(db) || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS"))
QCOMPARE(rec.count(), 4); //mysql, sqlite and tds will match
else
QCOMPARE(rec.count(), 0);
@@ -204,7 +204,7 @@ void tst_QSqlDriver::primaryIndex()
tablename = tablename.toUpper();
index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName));
- if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS"))
+ if (tst_Databases::isMySQL(db) || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS"))
QCOMPARE(index.count(), 1); //mysql will always find the table name regardless of casing
else
QCOMPARE(index.count(), 0);
diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp
index ab7f0c9..f3dd920 100644
--- a/tests/auto/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp
@@ -188,6 +188,9 @@ private slots:
void task_205701_data() { generic_data("QMYSQL"); }
void task_205701();
+ void task_233829_data() { generic_data("QPSQL"); }
+ void task_233829();
+
private:
// returns all database connections
@@ -293,6 +296,9 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db )
<< qTableName( "oraRowId" )
<< qTableName( "qtest_batch" );
+ if ( db.driverName().startsWith("QPSQL") )
+ tablenames << qTableName("task_233829");
+
if ( db.driverName().startsWith("QSQLITE") )
tablenames << qTableName( "record_sqlite" );
@@ -302,7 +308,7 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db )
tablenames << qTableName( "qtest_lockedtable" );
tablenames << qTableName( "Planet" );
-
+
tablenames << qTableName( "task_250026" );
tablenames << qTableName( "task_234422" );
@@ -318,7 +324,10 @@ void tst_QSqlQuery::createTestTables( QSqlDatabase db )
// in the MySQL server startup script
q.exec( "set table_type=innodb" );
- QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest" ) + " (id int "+tst_Databases::autoFieldName(db) +" NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id))" ) );
+ if(tst_Databases::isPostgreSQL(db))
+ QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest" ) + " (id serial NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id)) WITH OIDS" ) );
+ else
+ QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest" ) + " (id int "+tst_Databases::autoFieldName(db) +" NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id))" ) );
if ( tst_Databases::isSqlServer( db ) || db.driverName().startsWith( "QTDS" ) )
QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_null" ) + " (id int null, t_varchar varchar(20) null)" ) );
@@ -486,7 +495,9 @@ void tst_QSqlQuery::mysqlOutValues()
QVERIFY_SQL( q, exec( "create procedure " + qTableName( "qtestproc" ) + " () "
"BEGIN select * from " + qTableName( "qtest" ) + " order by id; END" ) );
QVERIFY_SQL( q, exec( "call " + qTableName( "qtestproc" ) + "()" ) );
+ QEXPECT_FAIL("", "There's a mysql bug that means only selects think they return data when running in prepared mode", Continue);
QVERIFY_SQL( q, next() );
+ QEXPECT_FAIL("", "There's a mysql bug that means only selects think they return data when running in prepared mode", Continue);
QCOMPARE( q.value( 1 ).toString(), QString( "VarChar1" ) );
QVERIFY_SQL( q, exec( "drop procedure " + qTableName( "qtestproc" ) ) );
@@ -1870,7 +1881,7 @@ void tst_QSqlQuery::invalidQuery()
QVERIFY( !q.next() );
QVERIFY( !q.isActive() );
- if ( !db.driverName().startsWith( "QOCI" ) && !db.driverName().startsWith( "QDB2" ) ) {
+ if ( !db.driverName().startsWith( "QOCI" ) && !db.driverName().startsWith( "QDB2" ) && !db.driverName().startsWith( "QODBC" ) ) {
// oracle and db2 just prepares everything without complaining
if ( db.driver()->hasFeature( QSqlDriver::PreparedQueries ) )
QVERIFY( !q.prepare( "blahfasel" ) );
@@ -2007,7 +2018,7 @@ void tst_QSqlQuery::oraArrayBind()
q.bindValue( 0, list, QSql::In );
- QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsRows ) );
+ QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsColumns ) );
QVERIFY_SQL( q, prepare( "BEGIN "
"ora_array_test.get_table(?); "
@@ -2019,7 +2030,7 @@ void tst_QSqlQuery::oraArrayBind()
q.bindValue( 0, list, QSql::Out );
- QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsRows ) );
+ QVERIFY_SQL( q, execBatch( QSqlQuery::ValuesAsColumns ) );
QVariantList out_list = q.boundValue( 0 ).toList();
@@ -2565,7 +2576,7 @@ void tst_QSqlQuery::blobsPreparedQuery()
QString typeName( "BLOB" );
if ( db.driverName().startsWith( "QPSQL" ) )
typeName = "BYTEA";
- else if ( db.driverName().startsWith( "QODBC" ) )
+ else if ( db.driverName().startsWith( "QODBC" ) && tst_Databases::isSqlServer( db ))
typeName = "IMAGE";
QVERIFY_SQL( q, exec( QString( "CREATE TABLE %1(id INTEGER, data %2)" ).arg( tableName ).arg( typeName ) ) );
@@ -2771,5 +2782,24 @@ void tst_QSqlQuery::task_234422()
#endif
+void tst_QSqlQuery::task_233829()
+{
+ QFETCH( QString, dbName );
+ QSqlDatabase db = QSqlDatabase::database( dbName );
+ CHECK_DATABASE( db );
+
+ QSqlQuery q( db );
+ QString tableName = qTableName("task_233829");
+ QVERIFY_SQL(q,exec("CREATE TABLE " + tableName + "(dbl1 double precision,dbl2 double precision) without oids;"));
+
+ QString queryString("INSERT INTO " + tableName +"(dbl1, dbl2) VALUES(?,?)");
+
+ double k = 0.0;
+ QVERIFY_SQL(q,prepare(queryString));
+ q.bindValue(0,0.0 / k); // nan
+ q.bindValue(1,0.0 / k); // nan
+ QVERIFY_SQL(q,exec());
+}
+
QTEST_MAIN( tst_QSqlQuery )
#include "tst_qsqlquery.moc"
diff --git a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
index d934b35..1e23d3d 100644
--- a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
+++ b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
@@ -145,8 +145,17 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db)
void tst_QSqlRelationalTableModel::initTestCase()
{
- foreach (const QString &dbname, dbs.dbNames)
- recreateTestTables(QSqlDatabase::database(dbname));
+ foreach (const QString &dbname, dbs.dbNames) {
+ QSqlDatabase db=QSqlDatabase::database(dbname);
+ if (db.driverName().startsWith("QIBASE"))
+ db.exec("SET DIALECT 3");
+ else if (tst_Databases::isSqlServer(db)) {
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec("SET ANSI_DEFAULTS ON"));
+ QVERIFY_SQL(q, exec("SET IMPLICIT_TRANSACTIONS OFF"));
+ }
+ recreateTestTables(db);
+ }
}
void tst_QSqlRelationalTableModel::cleanupTestCase()
@@ -490,6 +499,7 @@ void tst_QSqlRelationalTableModel::insertWithStrategies()
model.setTable(qTableName("reltest1"));
model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title"));
+ model.setSort(0, Qt::AscendingOrder);
if (!db.driverName().startsWith("QTDS"))
model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title"));
@@ -914,8 +924,8 @@ void tst_QSqlRelationalTableModel::casing()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- if (db.driverName().startsWith("QSQLITE"))
- QSKIP("The casing test for SQLITE is irrelevant since SQLITE is case insensitive", SkipAll);
+ if (db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QIBASE") || tst_Databases::isSqlServer(db))
+ QSKIP("The casing test for this database is irrelevant since this database does not treat different cases as separate entities", SkipAll);
QSqlQuery q(db);
QVERIFY_SQL( q, exec("create table " + qTableName("CASETEST1", db.driver()).toUpper() +
diff --git a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp
index 1445f34..576c190 100644
--- a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp
+++ b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp
@@ -116,6 +116,8 @@ private slots:
void insertRecordsInLoop();
void sqlite_attachedDatabase_data() { generic_data("QSQLITE"); }
void sqlite_attachedDatabase(); // For task 130799
+ void tableModifyWithBlank_data() { generic_data(); }
+ void tableModifyWithBlank(); // For mail task
private:
void generic_data(const QString& engine=QString());
@@ -141,6 +143,7 @@ void tst_QSqlTableModel::dropTestTables()
tableNames << qTableName("test")
<< qTableName("test2")
<< qTableName("test3")
+ << qTableName("test4")
<< qTableName("emptytable")
<< qTableName("bigtable")
<< qTableName("foo");
@@ -167,6 +170,8 @@ void tst_QSqlTableModel::createTestTables()
QVERIFY_SQL( q, exec("create table " + qTableName("test3") + "(id int, random varchar(20), randomtwo varchar(20))"));
+ QVERIFY_SQL( q, exec("create table " + qTableName("test4") + "(column1 varchar(50), column2 varchar(50), column3 varchar(50))"));
+
QVERIFY_SQL( q, exec("create table " + qTableName("emptytable") + "(id int)"));
if (testWhiteSpaceNames(db.driverName())) {
@@ -927,5 +932,62 @@ void tst_QSqlTableModel::sqlite_attachedDatabase()
QCOMPARE(model.data(model.index(0, 1), Qt::DisplayRole).toString(), QLatin1String("main"));
}
+
+void tst_QSqlTableModel::tableModifyWithBlank()
+{
+ QFETCH(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QSqlTableModel model(0, db);
+ model.setTable(qTableName("test4"));
+ model.select();
+
+ //generate a time stamp for the test. Add one second to the current time to make sure
+ //it is different than the QSqlQuery test.
+ QString timeString=QDateTime::currentDateTime().addSecs(1).toString(Qt::ISODate);
+
+ //insert a new row, with column0 being the timestamp.
+ //Should be equivalent to QSqlQuery INSERT INTO... command)
+ QVERIFY_SQL(model, insertRow(0));
+ QVERIFY_SQL(model, setData(model.index(0,0),timeString));
+ QVERIFY_SQL(model, submitAll());
+
+ //set a filter on the table so the only record we get is the one we just made
+ //I could just do another setData command, but I want to make sure the TableModel
+ //matches exactly what is stored in the database
+ model.setFilter("column1='"+timeString+"'"); //filter to get just the newly entered row
+ QVERIFY_SQL(model, select());
+
+ //Make sure we only get one record, and that it is the one we just made
+ QCOMPARE(model.rowCount(), 1); //verify only one entry
+ QCOMPARE(model.record(0).value(0).toString(), timeString); //verify correct record
+
+ //At this point we know that the intial value (timestamp) was succsefully stored in the database
+ //Attempt to modify the data in the new record
+ //equivalent to query.exec("update test set column3="... command in direct test
+ //set the data in the first column to "col1ModelData"
+ QVERIFY_SQL(model, setData(model.index(0,1), "col1ModelData"));
+
+ //do a quick check to make sure that the setData command properly set the value in the model
+ QCOMPARE(model.record(0).value(1).toString(), QLatin1String("col1ModelData"));
+
+ //submit the changed data to the database
+ //This is where I have been getting errors.
+ QVERIFY_SQL(model, submitAll());
+
+ //make sure the model has the most current data for our record
+ QVERIFY_SQL(model, select());
+
+ //verify that our new record was the only record returned
+ QCOMPARE(model.rowCount(), 1);
+
+ //And that the record returned is, in fact, our test record.
+ QCOMPARE(model.record(0).value(0).toString(), timeString);
+
+ //Make sure the value of the first column matches what we set it to previously.
+ QCOMPARE(model.record(0).value(1).toString(), QLatin1String("col1ModelData"));
+}
+
QTEST_MAIN(tst_QSqlTableModel)
#include "tst_qsqltablemodel.moc"
diff --git a/tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp b/tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp
index fa44034..fba7b1b 100644
--- a/tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp
+++ b/tests/auto/qstandarditemmodel/tst_qstandarditemmodel.cpp
@@ -1454,6 +1454,7 @@ static QStandardItem *itemFromText(QStandardItem *parent, const QString &text)
return item;
}
+#ifdef QT_BUILD_INTERNAL
static QModelIndex indexFromText(QStandardItemModel *model, const QString &text)
{
QStandardItem *item = itemFromText(model->invisibleRootItem(), text);
@@ -1467,9 +1468,11 @@ struct FriendlyTreeView : public QTreeView
friend class tst_QStandardItemModel;
Q_DECLARE_PRIVATE(QTreeView)
};
+#endif
void tst_QStandardItemModel::treeDragAndDrop()
{
+#ifdef QT_BUILD_INTERNAL
const int nRow = 5;
const int nCol = 3;
@@ -1605,6 +1608,7 @@ void tst_QStandardItemModel::treeDragAndDrop()
QVERIFY(compareModels(&model, &checkModel));
}
+#endif
}
void tst_QStandardItemModel::removeRowsAndColumns()
diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp
index a859866..efcb983 100644
--- a/tests/auto/qstatemachine/tst_qstatemachine.cpp
+++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp
@@ -1015,6 +1015,7 @@ void tst_QStateMachine::rootState()
void tst_QStateMachine::addAndRemoveState()
{
+#ifdef QT_BUILD_INTERNAL
QStateMachine machine;
QStatePrivate *root_d = QStatePrivate::get(machine.rootState());
QCOMPARE(root_d->childStates().size(), 0);
@@ -1075,6 +1076,7 @@ void tst_QStateMachine::addAndRemoveState()
delete s2;
// ### how to deal with this?
// machine.removeState(machine.errorState());
+#endif
}
void tst_QStateMachine::stateEntryAndExit()
diff --git a/tests/auto/qstringbuilder/tst_qstringbuilder.cpp b/tests/auto/qstringbuilder/tst_qstringbuilder.cpp
index fdbaf21..72889bc 100644
--- a/tests/auto/qstringbuilder/tst_qstringbuilder.cpp
+++ b/tests/auto/qstringbuilder/tst_qstringbuilder.cpp
@@ -85,28 +85,18 @@
#undef QT_NO_CAST_TO_ASCII
#endif
-
#include <QtTest/QtTest>
//TESTED_CLASS=QStringBuilder
//TESTED_FILES=qstringbuilder.cpp
-#include <qtest.h>
-
#define LITERAL "some literal"
class tst_QStringBuilder : public QObject
{
Q_OBJECT
-public:
- tst_QStringBuilder() {}
- ~tst_QStringBuilder() {}
-
-public slots:
- void init() {}
- void cleanup() {}
-
+private slots:
void scenario();
};
@@ -119,6 +109,7 @@ void tst_QStringBuilder::scenario()
QLatin1Char achar('c');
QString r2(QLatin1String(LITERAL LITERAL));
QString r;
+ QByteArray ba(LITERAL);
r = l1literal P l1literal;
QCOMPARE(r, r2);
@@ -139,6 +130,10 @@ void tst_QStringBuilder::scenario()
QCOMPARE(r, r2);
r = LITERAL P string;
QCOMPARE(r, r2);
+ r = ba P string;
+ QCOMPARE(r, r2);
+ r = string P ba;
+ QCOMPARE(r, r2);
#endif
}
diff --git a/tests/auto/qstylesheetstyle/qstylesheetstyle.pro b/tests/auto/qstylesheetstyle/qstylesheetstyle.pro
index 6acb0b4..f6101f4 100644
--- a/tests/auto/qstylesheetstyle/qstylesheetstyle.pro
+++ b/tests/auto/qstylesheetstyle/qstylesheetstyle.pro
@@ -13,3 +13,4 @@ contains(QT_CONFIG, qt3support): QT += qt3support
# Input
SOURCES += tst_qstylesheetstyle.cpp
RESOURCES += resources.qrc
+requires(contains(QT_CONFIG,private_tests))
diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
index 7b62eae..2bbe897 100644
--- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
@@ -81,6 +81,8 @@ private slots:
void paths();
void displayMode();
void strokeInherit();
+ void testFillInheritance();
+ void testStopOffsetOpacity();
#ifndef QT_NO_COMPRESS
void testGzLoading();
@@ -625,9 +627,11 @@ void tst_QSvgRenderer::testGzLoading()
QVERIFY(autoDetectGzData.isValid());
}
+#ifdef QT_BUILD_INTERNAL
QT_BEGIN_NAMESPACE
QByteArray qt_inflateGZipDataFrom(QIODevice *device);
QT_END_NAMESPACE
+#endif
void tst_QSvgRenderer::testGzHelper_data()
{
@@ -660,6 +664,7 @@ void tst_QSvgRenderer::testGzHelper_data()
void tst_QSvgRenderer::testGzHelper()
{
+#ifdef QT_BUILD_INTERNAL
QFETCH(QByteArray, in);
QFETCH(QByteArray, out);
@@ -668,6 +673,7 @@ void tst_QSvgRenderer::testGzHelper()
QVERIFY(buffer.isReadable());
QByteArray result = qt_inflateGZipDataFrom(&buffer);
QCOMPARE(result, out);
+#endif
}
#endif
@@ -1049,5 +1055,155 @@ void tst_QSvgRenderer::strokeInherit()
}
}
+void tst_QSvgRenderer::testFillInheritance()
+{
+ static const char *svgs[] = {
+ //reference
+ "<svg viewBox = \"0 0 200 200\">"
+ " <polygon points=\"20,20 50,120 100,10 40,80 50,80\" fill= \"red\" stroke = \"blue\" fill-opacity = \"0.5\" fill-rule = \"evenodd\"/>"
+ "</svg>",
+ "<svg viewBox = \"0 0 200 200\">"
+ " <polygon points=\"20,20 50,120 100,10 40,80 50,80\" fill= \"red\" stroke = \"blue\" fill-opacity = \"0.5\" fill-rule = \"evenodd\"/>"
+ " <rect x = \"40\" y = \"40\" width = \"70\" height =\"20\" fill = \"green\" fill-opacity = \"0\"/>"
+ "</svg>",
+ "<svg viewBox = \"0 0 200 200\">"
+ " <g fill = \"red\" fill-opacity = \"0.5\" fill-rule = \"evenodd\">"
+ " <polygon points=\"20,20 50,120 100,10 40,80 50,80\" stroke = \"blue\"/>"
+ " </g>"
+ " <rect x = \"40\" y = \"40\" width = \"70\" height =\"20\" fill = \"green\" fill-opacity = \"0\"/>"
+ "</svg>",
+ "<svg viewBox = \"0 0 200 200\">"
+ " <g fill = \"green\" fill-rule = \"nonzero\">"
+ " <polygon points=\"20,20 50,120 100,10 40,80 50,80\" stroke = \"blue\" fill = \"red\" fill-opacity = \"0.5\" fill-rule = \"evenodd\"/>"
+ " </g>"
+ " <g fill-opacity = \"0.8\" fill = \"red\">"
+ " <rect x = \"40\" y = \"40\" width = \"70\" height =\"20\" fill = \"green\" fill-opacity = \"0\"/>"
+ " </g>"
+ "</svg>",
+ "<svg viewBox = \"0 0 200 200\">"
+ " <g fill = \"red\" >"
+ " <g fill-opacity = \"0.5\">"
+ " <g fill-rule = \"evenodd\">"
+ " <g>"
+ " <polygon points=\"20,20 50,120 100,10 40,80 50,80\" stroke = \"blue\"/>"
+ " </g>"
+ " </g>"
+ " </g>"
+ " </g>"
+ " <g fill-opacity = \"0.8\" >"
+ " <rect x = \"40\" y = \"40\" width = \"70\" height =\"20\" fill = \"none\"/>"
+ " </g>"
+ "</svg>",
+ "<svg viewBox = \"0 0 200 200\">"
+ " <g fill = \"none\" fill-opacity = \"0\">"
+ " <polygon points=\"20,20 50,120 100,10 40,80 50,80\" stroke = \"blue\" fill = \"red\" fill-opacity = \"0.5\" fill-rule = \"evenodd\"/>"
+ " </g>"
+ " <g fill-opacity = \"0\" >"
+ " <rect x = \"40\" y = \"40\" width = \"70\" height =\"20\" fill = \"green\"/>"
+ " </g>"
+ "</svg>"
+ };
+
+ const int COUNT = sizeof(svgs) / sizeof(svgs[0]);
+ QImage images[COUNT];
+ QPainter p;
+
+ for (int i = 0; i < COUNT; ++i) {
+ QByteArray data(svgs[i]);
+ QSvgRenderer renderer(data);
+ QVERIFY(renderer.isValid());
+ images[i] = QImage(200, 200, QImage::Format_ARGB32_Premultiplied);
+ images[i].fill(-1);
+ p.begin(&images[i]);
+ renderer.render(&p);
+ p.end();
+ if (i != 0) {
+ QCOMPARE(images[0], images[i]);
+ }
+ }
+}
+void tst_QSvgRenderer::testStopOffsetOpacity()
+{
+ static const char *svgs[] = {
+ //reference
+ "<svg viewBox=\"0 0 64 64\">"
+ "<radialGradient id=\"MyGradient1\" gradientUnits=\"userSpaceOnUse\" cx=\"50\" cy=\"50\" r=\"30\" fx=\"20\" fy=\"20\">"
+ "<stop offset=\"0.0\" style=\"stop-color:red\" stop-opacity=\"0.3\"/>"
+ "<stop offset=\"0.5\" style=\"stop-color:green\" stop-opacity=\"1\"/>"
+ "<stop offset=\"1\" style=\"stop-color:yellow\" stop-opacity=\"1\"/>"
+ "</radialGradient>"
+ "<radialGradient id=\"MyGradient2\" gradientUnits=\"userSpaceOnUse\" cx=\"50\" cy=\"70\" r=\"70\" fx=\"20\" fy=\"20\">"
+ "<stop offset=\"0.0\" style=\"stop-color:blue\" stop-opacity=\"0.3\"/>"
+ "<stop offset=\"0.5\" style=\"stop-color:violet\" stop-opacity=\"1\"/>"
+ "<stop offset=\"1\" style=\"stop-color:orange\" stop-opacity=\"1\"/>"
+ "</radialGradient>"
+ "<rect x=\"5\" y=\"5\" width=\"55\" height=\"55\" fill=\"url(#MyGradient1)\" stroke=\"black\" />"
+ "<rect x=\"20\" y=\"20\" width=\"35\" height=\"35\" fill=\"url(#MyGradient2)\"/>"
+ "</svg>",
+ //Stop Offset
+ "<svg viewBox=\"0 0 64 64\">"
+ "<radialGradient id=\"MyGradient1\" gradientUnits=\"userSpaceOnUse\" cx=\"50\" cy=\"50\" r=\"30\" fx=\"20\" fy=\"20\">"
+ "<stop offset=\"abc\" style=\"stop-color:red\" stop-opacity=\"0.3\"/>"
+ "<stop offset=\"0.5\" style=\"stop-color:green\" stop-opacity=\"1\"/>"
+ "<stop offset=\"1\" style=\"stop-color:yellow\" stop-opacity=\"1\"/>"
+ "</radialGradient>"
+ "<radialGradient id=\"MyGradient2\" gradientUnits=\"userSpaceOnUse\" cx=\"50\" cy=\"70\" r=\"70\" fx=\"20\" fy=\"20\">"
+ "<stop offset=\"-3.bc\" style=\"stop-color:blue\" stop-opacity=\"0.3\"/>"
+ "<stop offset=\"0.5\" style=\"stop-color:violet\" stop-opacity=\"1\"/>"
+ "<stop offset=\"1\" style=\"stop-color:orange\" stop-opacity=\"1\"/>"
+ "</radialGradient>"
+ "<rect x=\"5\" y=\"5\" width=\"55\" height=\"55\" fill=\"url(#MyGradient1)\" stroke=\"black\" />"
+ "<rect x=\"20\" y=\"20\" width=\"35\" height=\"35\" fill=\"url(#MyGradient2)\"/>"
+ "</svg>",
+ //Stop Opacity
+ "<svg viewBox=\"0 0 64 64\">"
+ "<radialGradient id=\"MyGradient1\" gradientUnits=\"userSpaceOnUse\" cx=\"50\" cy=\"50\" r=\"30\" fx=\"20\" fy=\"20\">"
+ "<stop offset=\"0.0\" style=\"stop-color:red\" stop-opacity=\"0.3\"/>"
+ "<stop offset=\"0.5\" style=\"stop-color:green\" stop-opacity=\"x.45\"/>"
+ "<stop offset=\"1\" style=\"stop-color:yellow\" stop-opacity=\"-3.abc\"/>"
+ "</radialGradient>"
+ "<radialGradient id=\"MyGradient2\" gradientUnits=\"userSpaceOnUse\" cx=\"50\" cy=\"70\" r=\"70\" fx=\"20\" fy=\"20\">"
+ "<stop offset=\"0.0\" style=\"stop-color:blue\" stop-opacity=\"0.3\"/>"
+ "<stop offset=\"0.5\" style=\"stop-color:violet\" stop-opacity=\"-0.xy\"/>"
+ "<stop offset=\"1\" style=\"stop-color:orange\" stop-opacity=\"z.5\"/>"
+ "</radialGradient>"
+ "<rect x=\"5\" y=\"5\" width=\"55\" height=\"55\" fill=\"url(#MyGradient1)\" stroke=\"black\" />"
+ "<rect x=\"20\" y=\"20\" width=\"35\" height=\"35\" fill=\"url(#MyGradient2)\"/>"
+ "</svg>",
+ //Stop offset and Stop opacity
+ "<svg viewBox=\"0 0 64 64\">"
+ "<radialGradient id=\"MyGradient1\" gradientUnits=\"userSpaceOnUse\" cx=\"50\" cy=\"50\" r=\"30\" fx=\"20\" fy=\"20\">"
+ "<stop offset=\"abc\" style=\"stop-color:red\" stop-opacity=\"0.3\"/>"
+ "<stop offset=\"0.5\" style=\"stop-color:green\" stop-opacity=\"x.45\"/>"
+ "<stop offset=\"1\" style=\"stop-color:yellow\" stop-opacity=\"-3.abc\"/>"
+ "</radialGradient>"
+ "<radialGradient id=\"MyGradient2\" gradientUnits=\"userSpaceOnUse\" cx=\"50\" cy=\"70\" r=\"70\" fx=\"20\" fy=\"20\">"
+ "<stop offset=\"-3.bc\" style=\"stop-color:blue\" stop-opacity=\"0.3\"/>"
+ "<stop offset=\"0.5\" style=\"stop-color:violet\" stop-opacity=\"-0.xy\"/>"
+ "<stop offset=\"1\" style=\"stop-color:orange\" stop-opacity=\"z.5\"/>"
+ "</radialGradient>"
+ "<rect x=\"5\" y=\"5\" width=\"55\" height=\"55\" fill=\"url(#MyGradient1)\" stroke=\"black\" />"
+ "<rect x=\"20\" y=\"20\" width=\"35\" height=\"35\" fill=\"url(#MyGradient2)\"/>"
+ "</svg>"
+ };
+
+ QImage images[4];
+ QPainter p;
+
+ for (int i = 0; i < 4; ++i) {
+ QByteArray data(svgs[i]);
+ QSvgRenderer renderer(data);
+ QVERIFY(renderer.isValid());
+ images[i] = QImage(64, 64, QImage::Format_ARGB32_Premultiplied);
+ images[i].fill(-1);
+ p.begin(&images[i]);
+ renderer.render(&p);
+ p.end();
+ }
+ QCOMPARE(images[0], images[1]);
+ QCOMPARE(images[0], images[2]);
+ QCOMPARE(images[0], images[3]);
+}
+
QTEST_MAIN(tst_QSvgRenderer)
#include "tst_qsvgrenderer.moc"
diff --git a/tests/auto/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp b/tests/auto/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp
index 22e9455..1699e72 100644
--- a/tests/auto/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp
+++ b/tests/auto/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp
@@ -99,7 +99,8 @@ private slots:
void avoidUnnecessaryRehighlight();
void noContentsChangedDuringHighlight();
void rehighlight();
-
+ void rehighlightBlock();
+
private:
QTextDocument *doc;
QTestDocumentLayout *lout;
@@ -517,6 +518,32 @@ void tst_QSyntaxHighlighter::rehighlight()
QCOMPARE(hl->callCount, 1);
}
+void tst_QSyntaxHighlighter::rehighlightBlock()
+{
+ TestHighlighter *hl = new TestHighlighter(doc);
+
+ cursor.movePosition(QTextCursor::Start);
+ cursor.beginEditBlock();
+ cursor.insertText("Hello");
+ cursor.insertBlock();
+ cursor.insertText("World");
+ cursor.endEditBlock();
+
+ hl->callCount = 0;
+ hl->highlightedText.clear();
+ QTextBlock block = doc->begin();
+ hl->rehighlightBlock(block);
+
+ QCOMPARE(hl->highlightedText, QString("Hello"));
+ QCOMPARE(hl->callCount, 1);
+
+ hl->callCount = 0;
+ hl->highlightedText.clear();
+ hl->rehighlightBlock(block.next());
+
+ QCOMPARE(hl->highlightedText, QString("World"));
+ QCOMPARE(hl->callCount, 1);
+}
QTEST_MAIN(tst_QSyntaxHighlighter)
#include "tst_qsyntaxhighlighter.moc"
diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp
index ae023ba..6fa57f0 100644
--- a/tests/auto/qtableview/tst_qtableview.cpp
+++ b/tests/auto/qtableview/tst_qtableview.cpp
@@ -175,6 +175,8 @@ private slots:
// task-specific tests:
void task173773_updateVerticalHeader();
void task227953_setRootIndex();
+ void task240266_veryBigColumn();
+ void task248688_autoScrollNavigation();
void mouseWheel_data();
void mouseWheel();
@@ -586,7 +588,7 @@ void tst_QTableView::keyboardNavigation()
QModelIndex index = model.index(rowCount - 1, columnCount - 1);
view.setCurrentIndex(index);
- QApplication::instance()->processEvents();
+ QApplication::processEvents();
int row = rowCount - 1;
int column = columnCount - 1;
@@ -618,7 +620,7 @@ void tst_QTableView::keyboardNavigation()
}
QTest::keyClick(&view, key);
- QApplication::instance()->processEvents();
+ QApplication::processEvents();
QModelIndex index = model.index(row, column);
QCOMPARE(view.currentIndex(), index);
@@ -3127,6 +3129,56 @@ void tst_QTableView::task227953_setRootIndex()
QVERIFY(!tableView.verticalHeader()->isHidden());
}
+void tst_QTableView::task240266_veryBigColumn()
+{
+ QTableView table;
+ table.setFixedSize(500, 300); //just to make sure we have the 2 first columns visible
+ QStandardItemModel model(1, 3);
+ table.setModel(&model);
+ table.setColumnWidth(0, 100); //normal column
+ table.setColumnWidth(1, 100); //normal column
+ table.setColumnWidth(2, 9000); //very big column
+ table.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(100);
+
+ QScrollBar *scroll = table.horizontalScrollBar();
+ QCOMPARE(scroll->minimum(), 0);
+ QCOMPARE(scroll->maximum(), model.columnCount() - 1);
+ QCOMPARE(scroll->singleStep(), 1);
+
+ //1 is not always a very correct value for pageStep. Ideally this should be dynamic.
+ //Maybe something for Qt 5 ;-)
+ QCOMPARE(scroll->pageStep(), 1);
+
+}
+
+void tst_QTableView::task248688_autoScrollNavigation()
+{
+ //we make sure that when navigating with the keyboard the view is correctly scrolled
+ //to the current item
+ QStandardItemModel model(16, 16);
+ QTableView view;
+ view.setModel(&model);
+
+ view.hideColumn(8);
+ view.hideRow(8);
+ view.show();
+ for (int r = 0; r < model.rowCount(); ++r) {
+ if (view.isRowHidden(r))
+ continue;
+ for (int c = 0; c < model.columnCount(); ++c) {
+ if (view.isColumnHidden(c))
+ continue;
+ QModelIndex index = model.index(r, c);
+ view.setCurrentIndex(index);
+ QVERIFY(view.viewport()->rect().contains(view.visualRect(index)));
+ }
+ }
+}
+
void tst_QTableView::mouseWheel_data()
{
diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp
index 3bc1517..d54645c 100644
--- a/tests/auto/qtextedit/tst_qtextedit.cpp
+++ b/tests/auto/qtextedit/tst_qtextedit.cpp
@@ -1460,6 +1460,7 @@ void tst_QTextEdit::mimeDataReimplementations()
QCOMPARE(ed.canInsertCallCount, 0);
QCOMPARE(ed.insertCallCount, 0);
+#ifdef QT_BUILD_INTERNAL
QTextControl *control = qFindChild<QTextControl *>(&ed);
QVERIFY(control);
@@ -1474,6 +1475,7 @@ void tst_QTextEdit::mimeDataReimplementations()
QCOMPARE(ed.createMimeDataCallCount, 1);
QCOMPARE(ed.canInsertCallCount, 1);
QCOMPARE(ed.insertCallCount, 1);
+#endif
}
void tst_QTextEdit::ctrlEnterShouldInsertLineSeparator_NOT()
@@ -2066,6 +2068,7 @@ void tst_QTextEdit::cursorRect()
void tst_QTextEdit::setDocumentPreservesPalette()
{
+#ifdef QT_BUILD_INTERNAL
QTextControl *control = qFindChild<QTextControl *>(ed);
QVERIFY(control);
@@ -2085,6 +2088,7 @@ void tst_QTextEdit::setDocumentPreservesPalette()
QVERIFY(control->document() == newDoc);
QVERIFY(whitePal.color(QPalette::Active, QPalette::Text)
== control->palette().color(QPalette::Active, QPalette::Text));
+#endif
}
class PublicTextEdit : public QTextEdit
diff --git a/tests/auto/qtextpiecetable/qtextpiecetable.pro b/tests/auto/qtextpiecetable/qtextpiecetable.pro
index 318a8c7..0926b83 100644
--- a/tests/auto/qtextpiecetable/qtextpiecetable.pro
+++ b/tests/auto/qtextpiecetable/qtextpiecetable.pro
@@ -2,7 +2,6 @@ load(qttest_p4)
SOURCES += tst_qtextpiecetable.cpp
HEADERS += ../qtextdocument/common.h
-!win32:DEFINES += QTEST_REDUCED_EXPORTS
-
-
+requires(!win32)
+requires(contains(QT_CONFIG,private_tests))
diff --git a/tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp b/tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp
index accbabb..0e60c16 100644
--- a/tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp
+++ b/tests/auto/qtextpiecetable/tst_qtextpiecetable.cpp
@@ -42,9 +42,7 @@
#include <QtTest/QtTest>
-#ifdef QTEST_REDUCED_EXPORTS
#define private public
-#endif
#include <qtextdocument.h>
#include <private/qtextdocument_p.h>
@@ -65,7 +63,6 @@ public:
tst_QTextPieceTable();
-#ifdef QTEST_REDUCED_EXPORTS
public slots:
void init();
void cleanup();
@@ -112,13 +109,7 @@ private slots:
void removeFrameDirect();
void removeWithChildFrame();
void clearWithFrames();
-#else
-public slots:
- void init();
- void cleanup();
-private slots:
- void skip();
-#endif
+
private:
QTextDocument *doc;
QTextDocumentPrivate *table;
@@ -130,8 +121,6 @@ tst_QTextPieceTable::tst_QTextPieceTable()
{ doc = 0; table = 0; }
-#ifdef QTEST_REDUCED_EXPORTS
-
void tst_QTextPieceTable::init()
{
doc = new QTextDocument(0);
@@ -1148,25 +1137,6 @@ void tst_QTextPieceTable::clearWithFrames()
QVERIFY(true);
}
-#else // QTEST_REDUCED_EXPORTS
-
-void tst_QTextPieceTable::init()
-{
-}
-
-void tst_QTextPieceTable::cleanup()
-{
-}
-
-void tst_QTextPieceTable::skip()
-{
- QSKIP( "Not tested on win32", SkipAll );
-}
-
-
-#endif // QTEST_REDUCED_EXPORTS
-
-
QTEST_MAIN(tst_QTextPieceTable)
diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp
index ea551da..723f882 100644
--- a/tests/auto/qurl/tst_qurl.cpp
+++ b/tests/auto/qurl/tst_qurl.cpp
@@ -3057,12 +3057,15 @@ void tst_QUrl::nameprep_testsuite_data()
<< QString() << 0 << 0;
}
+#ifdef QT_BUILD_INTERNAL
QT_BEGIN_NAMESPACE
extern QString qt_nameprep(const QString &source);
QT_END_NAMESPACE
+#endif
void tst_QUrl::nameprep_testsuite()
{
+#ifdef QT_BUILD_INTERNAL
QFETCH(QString, in);
QFETCH(QString, out);
QFETCH(QString, profile);
@@ -3082,6 +3085,7 @@ void tst_QUrl::nameprep_testsuite()
QEXPECT_FAIL("Larger test (expanding)",
"Investigate further", Continue);
QCOMPARE(qt_nameprep(in), out);
+#endif
}
void tst_QUrl::ace_testsuite_data()
diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp
index fa36496..0f0a1af 100644
--- a/tests/auto/qwidget/tst_qwidget.cpp
+++ b/tests/auto/qwidget/tst_qwidget.cpp
@@ -351,6 +351,7 @@ private slots:
#endif
void updateOnDestroyedSignal();
void toplevelLineEditFocus();
+ void inputFocus_task257832();
void focusWidget_task254563();
void rectOutsideCoordinatesLimit_task144779();
@@ -9152,5 +9153,19 @@ void tst_QWidget::rectOutsideCoordinatesLimit_task144779()
QCOMPARE(pixmap.toImage().copy(center), correct.toImage().copy(center));
}
+void tst_QWidget::inputFocus_task257832()
+{
+ QLineEdit *widget = new QLineEdit;
+ QInputContext *context = widget->inputContext();
+ if (!context)
+ QSKIP("No input context", SkipSingle);
+ widget->setFocus();
+ context->setFocusWidget(widget);
+ QCOMPARE(context->focusWidget(), widget);
+ widget->setReadOnly(true);
+ QVERIFY(!context->focusWidget());
+ delete widget;
+}
+
QTEST_MAIN(tst_QWidget)
#include "tst_qwidget.moc"
diff --git a/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro b/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro
index e90b335..3d82eaf 100644
--- a/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro
+++ b/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro
@@ -2,3 +2,4 @@ TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = ../xmlpatternsxqts test
+requires(contains(QT_CONFIG,private_tests))
diff --git a/tests/auto/xmlpatternsview/xmlpatternsview.pro b/tests/auto/xmlpatternsview/xmlpatternsview.pro
index 3544264..04ee4d0 100644
--- a/tests/auto/xmlpatternsview/xmlpatternsview.pro
+++ b/tests/auto/xmlpatternsview/xmlpatternsview.pro
@@ -6,3 +6,4 @@ SUBDIRS = ../xmlpatternsxqts test
contains(QT_CONFIG,xmlpatterns) {
SUBDIRS += view
}
+requires(contains(QT_CONFIG,private_tests))
diff --git a/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro b/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro
index 368a028..a3b13da 100644
--- a/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro
+++ b/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro
@@ -9,3 +9,6 @@ contains(QT_CONFIG,xmlpatterns) {
# Needed on the win32-g++ setup and on the test machine arsia.
INCLUDEPATH += $$QT_BUILD_TREE/include/QtXmlPatterns/private \
../../../include/QtXmlPatterns/private
+
+requires(contains(QT_CONFIG,private_tests))
+
diff --git a/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro b/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro
index 4a688c4..9b63a52 100644
--- a/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro
+++ b/tests/auto/xmlpatternsxslts/xmlpatternsxslts.pro
@@ -23,3 +23,4 @@ wince*: {
DEPLOYMENT += testdata
}
+requires(contains(QT_CONFIG,private_tests))
diff --git a/tools/assistant/lib/qhelpsearchengine.cpp b/tools/assistant/lib/qhelpsearchengine.cpp
index 9faafe0..2a41d04 100644
--- a/tools/assistant/lib/qhelpsearchengine.cpp
+++ b/tools/assistant/lib/qhelpsearchengine.cpp
@@ -84,18 +84,17 @@ private:
, resultWidget(0)
, helpEngine(helpEngine)
{
- hitList.clear();
indexReader = 0;
indexWriter = 0;
}
~QHelpSearchEnginePrivate()
{
- hitList.clear();
delete indexReader;
delete indexWriter;
}
+
int hitsCount() const
{
int count = 0;
@@ -107,12 +106,9 @@ private:
QList<QHelpSearchEngine::SearchHit> hits(int start, int end) const
{
- QList<QHelpSearchEngine::SearchHit> returnValue;
- if (indexReader) {
- for (int i = start; i < end && i < hitsCount(); ++i)
- returnValue.append(indexReader->hit(i));
- }
- return returnValue;
+ return indexReader ?
+ indexReader->hits(start, end) :
+ QList<QHelpSearchEngine::SearchHit>();
}
void updateIndex(bool reindex = false)
@@ -131,11 +127,9 @@ private:
connect(indexWriter, SIGNAL(indexingFinished()), this, SLOT(optimizeIndex()));
}
- if (indexWriter) {
- indexWriter->cancelIndexing();
- indexWriter->updateIndex(helpEngine->collectionFile(),
- indexFilesFolder(), reindex);
- }
+ indexWriter->cancelIndexing();
+ indexWriter->updateIndex(helpEngine->collectionFile(),
+ indexFilesFolder(), reindex);
}
void cancelIndexing()
@@ -159,11 +153,9 @@ private:
connect(indexReader, SIGNAL(searchingFinished(int)), this, SIGNAL(searchingFinished(int)));
}
- if (indexReader) {
- m_queryList = queryList;
- indexReader->cancelSearching();
- indexReader->search(helpEngine->collectionFile(), indexFilesFolder(), queryList);
- }
+ m_queryList = queryList;
+ indexReader->cancelSearching();
+ indexReader->search(helpEngine->collectionFile(), indexFilesFolder(), queryList);
}
void cancelSearching()
@@ -204,7 +196,6 @@ private:
QHelpSearchIndexWriter *indexWriter;
QPointer<QHelpEngineCore> helpEngine;
- QList<QHelpSearchEngine::SearchHit> hitList;
QList<QHelpSearchQuery> m_queryList;
};
diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp
index 227e558..89d6040 100644
--- a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp
+++ b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp
@@ -70,7 +70,6 @@ QHelpSearchIndexReader::~QHelpSearchIndexReader()
{
mutex.lock();
this->m_cancel = true;
- waitCondition.wakeOne();
mutex.unlock();
wait();
@@ -86,8 +85,8 @@ void QHelpSearchIndexReader::cancelSearching()
void QHelpSearchIndexReader::search(const QString &collectionFile, const QString &indexFilesFolder,
const QList<QHelpSearchQuery> &queryList)
{
- QMutexLocker lock(&mutex);
-
+ wait();
+
this->hitList.clear();
this->m_cancel = false;
this->m_query = queryList;
@@ -99,12 +98,18 @@ void QHelpSearchIndexReader::search(const QString &collectionFile, const QString
int QHelpSearchIndexReader::hitsCount() const
{
+ QMutexLocker lock(&mutex);
return hitList.count();
}
-QHelpSearchEngine::SearchHit QHelpSearchIndexReader::hit(int index) const
+QList<QHelpSearchEngine::SearchHit> QHelpSearchIndexReader::hits(int start,
+ int end) const
{
- return hitList.at(index);
+ QList<QHelpSearchEngine::SearchHit> hits;
+ QMutexLocker lock(&mutex);
+ for (int i = start; i < end && i < hitList.count(); ++i)
+ hits.append(hitList.at(i));
+ return hits;
}
void QHelpSearchIndexReader::run()
@@ -135,7 +140,7 @@ void QHelpSearchIndexReader::run()
if(QCLuceneIndexReader::indexExists(indexPath)) {
mutex.lock();
if (m_cancel) {
- mutex.unlock();
+ mutex.unlock();
return;
}
mutex.unlock();
@@ -213,7 +218,9 @@ void QHelpSearchIndexReader::run()
#if !defined(QT_NO_EXCEPTIONS)
} catch(...) {
+ mutex.lock();
hitList.clear();
+ mutex.unlock();
emit searchingFinished(0);
}
#endif
@@ -416,8 +423,9 @@ void QHelpSearchIndexReader::boostSearchHits(const QHelpEngineCore &engine,
boostedList.append(it.value());
} while (it != hitMap.constBegin());
boostedList += hitList.mid(count, hitList.count());
-
+ mutex.lock();
hitList = boostedList;
+ mutex.unlock();
}
}
diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h
index 47af43f..8876d80 100644
--- a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h
+++ b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h
@@ -85,9 +85,8 @@ public:
void search(const QString &collectionFile,
const QString &indexFilesFolder,
const QList<QHelpSearchQuery> &queryList);
-
int hitsCount() const;
- QHelpSearchEngine::SearchHit hit(int index) const;
+ QList<QHelpSearchEngine::SearchHit> hits(int start, int end) const;
signals:
void searchingStarted();
@@ -105,10 +104,8 @@ private:
const QList<QHelpSearchQuery> &queryList);
private:
- QMutex mutex;
+ mutable QMutex mutex;
QList<QHelpSearchEngine::SearchHit> hitList;
- QWaitCondition waitCondition;
-
bool m_cancel;
QString m_collectionFile;
QList<QHelpSearchQuery> m_query;
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index 509444b..80cfc64 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -1135,6 +1135,10 @@ void Configure::parseCmdLine()
useUnixSeparators = (dictionary["QMAKESPEC"] == "win32-g++");
+ // Allow tests for private classes to be compiled against internal builds
+ if (dictionary["BUILDDEV"] == "yes")
+ qtConfig += "private_tests";
+
#if !defined(EVAL)
for( QStringList::Iterator dis = disabledModules.begin(); dis != disabledModules.end(); ++dis ) {
@@ -1521,7 +1525,7 @@ bool Configure::displayHelp()
desc( "-graphicssystem <sys>", "Specify which graphicssystem should be used.\n"
"Available values for <sys>:");
desc("GRAPHICS_SYSTEM", "raster", "", " raster - Software rasterizer", ' ');
- desc("GRAPHICS_SYSTEM", "opengl", "", " opengl - Using OpenGL accelleration, experimental!", ' ');
+ desc("GRAPHICS_SYSTEM", "opengl", "", " opengl - Using OpenGL acceleration, experimental!", ' ');
desc( "-help, -h, -?", "Display this information.\n");
@@ -1997,7 +2001,6 @@ bool Configure::verifyConfiguration()
no-gif gif
dll staticlib
- internal
nocrosscompiler
GNUmake
largefile
diff --git a/tools/designer/src/designer/qdesigner_workbench.cpp b/tools/designer/src/designer/qdesigner_workbench.cpp
index f21da8c..2ac9e1f 100644
--- a/tools/designer/src/designer/qdesigner_workbench.cpp
+++ b/tools/designer/src/designer/qdesigner_workbench.cpp
@@ -410,6 +410,12 @@ void QDesignerWorkbench::switchToDockedMode()
switchToNeutralMode();
+#ifndef Q_WS_MAC
+ QDesignerToolWindow *widgetBoxWrapper = widgetBoxToolWindow();
+ widgetBoxWrapper->action()->setVisible(true);
+ widgetBoxWrapper->setWindowTitle(tr("Widget Box"));
+#endif
+
m_mode = DockedMode;
const QDesignerSettings settings(m_core);
m_dockedMainWindow = new DockedMainWindow(this, m_toolbarMenu, m_toolWindows);
@@ -462,8 +468,6 @@ void QDesignerWorkbench::switchToTopLevelMode()
// make sure that the widgetbox is visible if it is different from neutral.
QDesignerToolWindow *widgetBoxWrapper = widgetBoxToolWindow();
Q_ASSERT(widgetBoxWrapper);
- if (!widgetBoxWrapper->action()->isChecked())
- widgetBoxWrapper->action()->trigger();
switchToNeutralMode();
const QPoint desktopOffset = desktopGeometry().topLeft();
@@ -502,9 +506,6 @@ void QDesignerWorkbench::switchToTopLevelMode()
found_visible_window |= tw->isVisible();
}
- if (!widgetBoxWrapper->action()->isChecked())
- widgetBoxWrapper->action()->trigger();
-
if (!m_toolWindows.isEmpty() && !found_visible_window)
m_toolWindows.first()->show();
diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp
index c9250c6..a531af8 100644
--- a/tools/linguist/lupdate/main.cpp
+++ b/tools/linguist/lupdate/main.cpp
@@ -182,9 +182,10 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil
if (options & Verbose)
printOut(QObject::tr("Updating '%1'...\n").arg(fn));
+ UpdateOptions theseOptions = options;
if (tor.locationsType() == Translator::NoLocations) // Could be set from file
- options |= NoLocations;
- Translator out = merge(tor, fetchedTor, options, err);
+ theseOptions |= NoLocations;
+ Translator out = merge(tor, fetchedTor, theseOptions, err);
if (!codecForTr.isEmpty())
out.setCodecName(codecForTr);
diff --git a/tools/linguist/phrasebooks/french.qph b/tools/linguist/phrasebooks/french.qph
index f244013..d38da5a 100644
--- a/tools/linguist/phrasebooks/french.qph
+++ b/tools/linguist/phrasebooks/french.qph
@@ -1,4 +1,5 @@
-<!DOCTYPE QPH><QPH language="fr">
+<!DOCTYPE QPH>
+<QPH language="fr">
<phrase>
<source>About</source>
<target>A propos</target>
@@ -1101,4 +1102,228 @@
<source>Yes</source>
<target>Oui</target>
</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Scinder</target>
+</phrase>
+<phrase>
+ <source>&amp;Edit</source>
+ <target>&amp;Édition</target>
+</phrase>
+<phrase>
+ <source>&amp;Redo</source>
+ <target>Re&amp;faire</target>
+</phrase>
+<phrase>
+ <source>debugger</source>
+ <target>débogueur</target>
+</phrase>
+<phrase>
+ <source>Start Debugger</source>
+ <target>Lancer le débogueur</target>
+</phrase>
+<phrase>
+ <source>Executable:</source>
+ <target>Exécutable:</target>
+</phrase>
+<phrase>
+ <source>Filter:</source>
+ <target>Filtre:</target>
+</phrase>
+<phrase>
+ <source>Clear</source>
+ <target>Effacer</target>
+</phrase>
+<phrase>
+ <source>Host and port:</source>
+ <target>Hôte et port:</target>
+</phrase>
+<phrase>
+ <source>Architecture:</source>
+ <target>Architecture:</target>
+</phrase>
+<phrase>
+ <source>Server start script:</source>
+ <target>Script de démarrage du serveur:</target>
+</phrase>
+<phrase>
+ <source>&amp;Undo</source>
+ <target>Annu&amp;ler</target>
+</phrase>
+<phrase>
+ <source>Add Bookmark</source>
+ <target>Ajouter un signet</target>
+</phrase>
+<phrase>
+ <source>Bookmark:</source>
+ <target>Signet:</target>
+</phrase>
+<phrase>
+ <source>Add in Folder:</source>
+ <target>Ajouter dans le dossier:</target>
+</phrase>
+<phrase>
+ <source>+</source>
+ <target>+</target>
+</phrase>
+<phrase>
+ <source>New Folder</source>
+ <target>Nouveau dossier</target>
+</phrase>
+<phrase>
+ <source>Bookmarks</source>
+ <target>Signets</target>
+</phrase>
+<phrase>
+ <source>Rename Folder</source>
+ <target>Renommer le dossier</target>
+</phrase>
+<phrase>
+ <source>Bookmark</source>
+ <target>Signet</target>
+</phrase>
+<phrase>
+ <source>Remove</source>
+ <target>Retirer</target>
+</phrase>
+<phrase>
+ <source>Delete Folder</source>
+ <target>Supprimer le dossier</target>
+</phrase>
+<phrase>
+ <source>Add</source>
+ <target>Ajouter</target>
+</phrase>
+<phrase>
+ <source>Move Up</source>
+ <target>Vers le Haut</target>
+</phrase>
+<phrase>
+ <source>Move Down</source>
+ <target>Vers le Bas</target>
+</phrase>
+<phrase>
+ <source>Show Bookmark</source>
+ <target>Afficher le signet</target>
+</phrase>
+<phrase>
+ <source>Show Bookmark in New Tab</source>
+ <target>Afficher le signet dans un nouvel onglet</target>
+</phrase>
+<phrase>
+ <source>Delete Bookmark</source>
+ <target>Supprimer le signet</target>
+</phrase>
+<phrase>
+ <source>Rename Bookmark</source>
+ <target>Renommer le signet</target>
+</phrase>
+<phrase>
+ <source>Previous Bookmark</source>
+ <target>Signet précédent</target>
+</phrase>
+<phrase>
+ <source>Next Bookmark</source>
+ <target>Signet suivant</target>
+</phrase>
+<phrase>
+ <source>Condition:</source>
+ <target>Condition:</target>
+</phrase>
+<phrase>
+ <source>Working Directory:</source>
+ <target>Répertoire de travail:</target>
+</phrase>
+<phrase>
+ <source>Environment</source>
+ <target>Environnement</target>
+</phrase>
+<phrase>
+ <source>Arguments</source>
+ <target>Arguments</target>
+</phrase>
+<phrase>
+ <source>Build directory:</source>
+ <target>Répertoire de compilation:</target>
+</phrase>
+<phrase>
+ <source>Path:</source>
+ <target>Chemin:</target>
+</phrase>
+<phrase>
+ <source>General</source>
+ <target>Général</target>
+</phrase>
+<phrase>
+ <source>Username:</source>
+ <target>Nom d&apos;utilisateur:</target>
+</phrase>
+<phrase>
+ <source>User interface</source>
+ <target>Interface utilisateur</target>
+</phrase>
+<phrase>
+ <source>Open Link</source>
+ <target>Ouvrir le lien</target>
+</phrase>
+<phrase>
+ <source> [read only]</source>
+ <target> [lecture seule]</target>
+</phrase>
+<phrase>
+ <source> [directory]</source>
+ <target> [répertoire]</target>
+</phrase>
+<phrase>
+ <source>Close All</source>
+ <target>Fermer tout</target>
+</phrase>
+<phrase>
+ <source>Failed!</source>
+ <target>Échec!</target>
+</phrase>
+<phrase>
+ <source>Proceed</source>
+ <target>Continuer</target>
+</phrase>
+<phrase>
+ <source>Make writable</source>
+ <target>Rendre inscriptible</target>
+</phrase>
+<phrase>
+ <source>Qt Creator</source>
+ <target>Qt Creator</target>
+</phrase>
+<phrase>
+ <source>&amp;File</source>
+ <target>&amp;Fichier</target>
+</phrase>
+<phrase>
+ <source>Activate %1</source>
+ <target>Activer %1</target>
+</phrase>
+<phrase>
+ <source>New Project</source>
+ <target>Nouveau projet</target>
+</phrase>
+<phrase>
+ <source>Close %1</source>
+ <target>Fermer %1</target>
+</phrase>
+<phrase>
+ <source>*</source>
+ <target>*</target>
+</phrase>
+<phrase>
+ <source>&amp;Change</source>
+ <target>&amp;Modifier</target>
+</phrase>
+<phrase>
+ <source>Close Other Editors</source>
+ <target>Fermer les autres éditeurs</target>
+</phrase>
+<phrase>
+ <source>Close All Except %1</source>
+ <target>Fermer tout sauf %1</target>
+</phrase>
</QPH>
diff --git a/tools/linguist/phrasebooks/russian.qph b/tools/linguist/phrasebooks/russian.qph
index 629c60b..69af041 100644
--- a/tools/linguist/phrasebooks/russian.qph
+++ b/tools/linguist/phrasebooks/russian.qph
@@ -10,7 +10,7 @@
</phrase>
<phrase>
<source>accessibility</source>
- <target>удобство</target>
+ <target>специальные возможности</target>
</phrase>
<phrase>
<source>action handle</source>
@@ -345,8 +345,8 @@
<target>активная зона</target>
</phrase>
<phrase>
- <source>icon</source>
- <target>пиктограмма</target>
+ <source>Icon</source>
+ <target>Значок</target>
</phrase>
<phrase>
<source>inactive</source>
@@ -402,7 +402,7 @@
</phrase>
<phrase>
<source>list view</source>
- <target>древовидный список</target>
+ <target>список</target>
</phrase>
<phrase>
<source>manual link</source>
@@ -901,10 +901,6 @@
<target>панель инструментов</target>
</phrase>
<phrase>
- <source>tooltip</source>
- <target>всплывающая подсказка</target>
-</phrase>
-<phrase>
<source>tree view control</source>
<target>древовидный список</target>
</phrase>
@@ -1054,10 +1050,46 @@
</phrase>
<phrase>
<source>Case Sensitive</source>
- <target>Регистрозависимо</target>
+ <target>Учитывать регистр</target>
</phrase>
<phrase>
<source>Whole words</source>
- <target>Слова полностью</target>
+ <target>Слова целиком</target>
+</phrase>
+<phrase>
+ <source>Find Next</source>
+ <target>Найти следующее</target>
+</phrase>
+<phrase>
+ <source>Find Previous</source>
+ <target>Найти предыдущее</target>
+</phrase>
+<phrase>
+ <source>Case Sensitive</source>
+ <target>Учитывать регистр символов</target>
+</phrase>
+<phrase>
+ <source>Whole words only</source>
+ <target>Только слова целиком</target>
+</phrase>
+<phrase>
+ <source>Subwindow</source>
+ <target>Дочернее окно</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Далее</target>
+</phrase>
+<phrase>
+ <source>tree view</source>
+ <target>древовидный список</target>
+</phrase>
+<phrase>
+ <source>ToolTip</source>
+ <target>Подсказка</target>
+</phrase>
+<phrase>
+ <source>Checkable</source>
+ <target>Переключаемое</target>
</phrase>
</QPH>
diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp
index 47c1ec2..a962152 100644
--- a/tools/linguist/shared/profileevaluator.cpp
+++ b/tools/linguist/shared/profileevaluator.cpp
@@ -68,8 +68,10 @@
#ifdef Q_OS_WIN32
#define QT_POPEN _popen
+#define QT_PCLOSE _pclose
#else
#define QT_POPEN popen
+#define QT_PCLOSE pclose
#endif
QT_BEGIN_NAMESPACE
@@ -1513,6 +1515,8 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
output += QLatin1String(buff);
}
ret += split_value_list(output);
+ if (proc)
+ QT_PCLOSE(proc);
}
}
break;
@@ -2067,7 +2071,7 @@ bool ProFileEvaluator::Private::evaluateFile(const QString &fileName, bool *resu
ProFile *pro = q->parsedProFile(fileName);
if (pro) {
m_profileStack.push(pro);
- ok = (currentProFile() ? pro->Accept(this) : false);
+ ok = pro->Accept(this);
m_profileStack.pop();
q->releaseParsedProFile(pro);
@@ -2077,16 +2081,6 @@ bool ProFileEvaluator::Private::evaluateFile(const QString &fileName, bool *resu
if (result)
*result = false;
}
-/* if (ok && readFeatures) {
- QStringList configs = values("CONFIG");
- QSet<QString> processed;
- foreach (const QString &fn, configs) {
- if (!processed.contains(fn)) {
- processed.insert(fn);
- evaluateFeatureFile(fn, 0);
- }
- }
- } */
return ok;
}
diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp
index 222b9a1..d5aca0e 100644
--- a/tools/qdoc3/doc.cpp
+++ b/tools/qdoc3/doc.cpp
@@ -1677,10 +1677,13 @@ void DocParser::startSection(Doc::SectioningUnit unit, int cmd)
leavePara();
if (currentSectioningUnit == Doc::Book) {
+#if 0
+ // mws didn't think this was necessary.
if (unit > Doc::Section1)
location().warning(tr("Unexpected '\\%1' without '\\%2'")
.arg(cmdName(cmd))
.arg(cmdName(CMD_SECTION1)));
+#endif
currentSectioningUnit = (Doc::SectioningUnit) (unit - 1);
priv->constructExtra();
priv->extra->sectioningUnit = currentSectioningUnit;
diff --git a/tools/qtconfig/translations/translations.pro b/tools/qtconfig/translations/translations.pro
index fbbdb2bba2..1f9f572 100644
--- a/tools/qtconfig/translations/translations.pro
+++ b/tools/qtconfig/translations/translations.pro
@@ -8,6 +8,7 @@ HEADERS += ../colorbutton.h ../previewframe.h ../previewwidget.h ../mainw
FORMS = ../mainwindowbase.ui ../paletteeditoradvancedbase.ui ../previewwidgetbase.ui
TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/qtconfig_pl.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/qtconfig_ru.ts \
$$[QT_INSTALL_TRANSLATIONS]/qtconfig_untranslated.ts \
$$[QT_INSTALL_TRANSLATIONS]/qtconfig_zh_CN.ts \
$$[QT_INSTALL_TRANSLATIONS]/qtconfig_zh_TW.ts
diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp
index 0f98619..1080477 100644
--- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp
+++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp
@@ -385,10 +385,14 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo
DWORD error = 0;
HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0);
if (S_OK != res) {
- if (S_OK != CeGetLastError())
- debugOutput(QString::fromLatin1("Error: Could not invoke method on QtRemote"),1);
- else
- debugOutput(QString::fromLatin1("Error: QtRemote return unexpectedly with error Code %1").arg(res), 1);
+ DWORD ce_error = CeGetLastError();
+ if (S_OK != ce_error) {
+ qWarning("Error invoking %s on %s: %s", qPrintable(functionName),
+ qPrintable(dllLocation), strwinerror(ce_error).constData());
+ } else {
+ qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName),
+ qPrintable(dllLocation), res);
+ }
} else {
DWORD written;
int strSize = program.length();
diff --git a/tools/qtestlib/wince/cetest/main.cpp b/tools/qtestlib/wince/cetest/main.cpp
index ba3ef8d..782f6d9 100644
--- a/tools/qtestlib/wince/cetest/main.cpp
+++ b/tools/qtestlib/wince/cetest/main.cpp
@@ -320,6 +320,7 @@ int main(int argc, char **argv)
cout << endl << "Remote Launch:" << qPrintable(TestConfiguration::remoteExecutable) << " " << qPrintable(launchArguments.join(" ")) << endl;
if (!connection.execute(TestConfiguration::remoteExecutable, launchArguments.join(" "), timeout)) {
cout << "Error: Could not execute target file" << endl;
+ return -1;
}
diff --git a/tools/qtestlib/wince/cetest/remoteconnection.cpp b/tools/qtestlib/wince/cetest/remoteconnection.cpp
index 75788e2..3d0c3f3 100644
--- a/tools/qtestlib/wince/cetest/remoteconnection.cpp
+++ b/tools/qtestlib/wince/cetest/remoteconnection.cpp
@@ -66,8 +66,8 @@ QByteArray strwinerror(DWORD errorcode)
out.chop(2);
/* Append error number to error message for good measure */
- out.append(" (");
- out.append(QByteArray::number((int)errorcode));
+ out.append(" (0x");
+ out.append(QByteArray::number(uint(errorcode), 16).rightJustified(8, '0'));
out.append(")");
}
return out;
diff --git a/tools/qvfb/translations/translations.pro b/tools/qvfb/translations/translations.pro
index 736a72c..f667bb8 100644
--- a/tools/qvfb/translations/translations.pro
+++ b/tools/qvfb/translations/translations.pro
@@ -27,6 +27,7 @@ SOURCES = ../qvfb.cpp \
../../shared/deviceskin/deviceskin.cpp
TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/qvfb_pl.ts \
+ $$[QT_INSTALL_TRANSLATIONS]/qvfb_ru.ts \
$$[QT_INSTALL_TRANSLATIONS]/qvfb_untranslated.ts \
$$[QT_INSTALL_TRANSLATIONS]/qvfb_zh_CN.ts \
$$[QT_INSTALL_TRANSLATIONS]/qvfb_zh_TW.ts
diff --git a/translations/assistant_adp_ru.ts b/translations/assistant_adp_ru.ts
index a587a91..c47798b 100644
--- a/translations/assistant_adp_ru.ts
+++ b/translations/assistant_adp_ru.ts
@@ -4,10 +4,12 @@
<context>
<name>AssistantServer</name>
<message>
+ <location filename="../tools/assistant/compat/main.cpp" line="+226"/>
<source>Failed to bind to port %1</source>
<translation>Не удалось открыть порт %1</translation>
</message>
<message>
+ <location line="-1"/>
<source>Qt Assistant</source>
<translation>Qt Assistant</translation>
</message>
@@ -15,22 +17,27 @@
<context>
<name>FontPanel</name>
<message>
+ <location filename="../tools/shared/fontpanel/fontpanel.cpp" line="+77"/>
<source>&amp;Family</source>
<translation>Се&amp;мейство</translation>
</message>
<message>
+ <location line="+4"/>
<source>&amp;Style</source>
<translation>&amp;Стиль</translation>
</message>
<message>
+ <location line="-18"/>
<source>Font</source>
<translation>Шрифт</translation>
</message>
<message>
+ <location line="+11"/>
<source>&amp;Writing system</source>
<translation>Система &amp;письма</translation>
</message>
<message>
+ <location line="+11"/>
<source>&amp;Point size</source>
<translation>&amp;Размер в пикселях</translation>
</message>
@@ -38,22 +45,27 @@
<context>
<name>FontSettingsDialog</name>
<message>
+ <location filename="../tools/assistant/compat/fontsettingsdialog.cpp" line="+75"/>
<source>Application</source>
<translation>Приложение</translation>
</message>
<message>
+ <location line="-1"/>
<source>Browser</source>
<translation>Обозреватель</translation>
</message>
<message>
+ <location line="-4"/>
<source>Font settings for:</source>
<translation>Настройки шрифта для:</translation>
</message>
<message>
+ <location line="+11"/>
<source>Use custom settings</source>
<translation>Использование индивидуальных настроек</translation>
</message>
<message>
+ <location line="-18"/>
<source>Font Settings</source>
<translation>Настройки шрифта</translation>
</message>
@@ -61,202 +73,261 @@
<context>
<name>HelpDialog</name>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.ui" line="+108"/>
<source>&amp;Index</source>
<translation>&amp;Указатель</translation>
</message>
<message>
+ <location line="+12"/>
<source>&amp;Look For:</source>
<translation>&amp;Искать:</translation>
</message>
<message>
+ <location line="+91"/>
<source>&amp;New</source>
- <translation>&amp;Создать</translation>
+ <translation>&amp;Новая</translation>
</message>
<message>
+ <location line="+23"/>
+ <location line="+111"/>
<source>&amp;Search</source>
<translation>&amp;Поиск</translation>
</message>
<message>
+ <location line="-212"/>
<source>&lt;b&gt;Enter a keyword.&lt;/b&gt;&lt;p&gt;The list will select an item that matches the entered string best.&lt;/p&gt;</source>
- <translation>&lt;b&gt;Ввод слова.&lt;/b&gt;&lt;p&gt;В список попадет то, что лучше соответствует введенной строке.&lt;/p&gt;</translation>
+ <translation type="unfinished">&lt;b&gt;Указание ключевого слова.&lt;/b&gt;&lt;p&gt;Список заполняется элементами, лучше соответствующими указанному ключевому слову.&lt;/p&gt;</translation>
</message>
<message>
+ <location line="+142"/>
<source>&lt;b&gt;Enter search word(s).&lt;/b&gt;&lt;p&gt;Enter here the word(s) you are looking for. The words may contain wildcards (*). For a sequence of words quote them.&lt;/p&gt;</source>
- <translation>&lt;b&gt;Ввод одного или более слов для поиска.&lt;/b&gt;&lt;p&gt;Сюда следует ввести одно или несколько слов, которые требуется найти. Слова могут содержкать символы-заменители (*). Если требуется найти словосочетание, то его нужно заключить в кавычки.&lt;/p&gt;</translation>
+ <translation type="unfinished">&lt;b&gt;Указание слов для поиска.&lt;/b&gt;&lt;p&gt;Введите одно или несколько слов, по которым требуется осуществить поиск. Слова могут содержкать символы-заменители (*). Если требуется найти сочетание слов, заключите искомую фразу в кавычки.&lt;/p&gt;</translation>
</message>
<message>
+ <location line="+10"/>
<source>&lt;b&gt;Found documents&lt;/b&gt;&lt;p&gt;This list contains all found documents from the last search. The documents are ordered, i.e. the first document has the most matches.&lt;/p&gt;</source>
- <translation>&lt;b&gt;Найденные документы&lt;/b&gt;&lt;p&gt;В этом списке представлены все найденные при последнем поиске документы. Документы упорядочены по релевантности, т.е. чем выше, тем чаще в нём встречаются указанные слова.&lt;/p&gt;</translation>
+ <translation type="unfinished">&lt;b&gt;Найденные документы&lt;/b&gt;&lt;p&gt;В данном списке представлены все найденные при последнем поиске документы. Документы упорядочены по релевантности, т.е. чем выше в списке, тем чаще в нём встречаются искомые слова.&lt;/p&gt;</translation>
</message>
<message>
+ <location line="-196"/>
<source>&lt;b&gt;Help topics organized by category.&lt;/b&gt;&lt;p&gt;Double-click an item to see the topics in that category. To view a topic, just double-click it.&lt;/p&gt;</source>
- <translation>&lt;b&gt;Статьи справки распределённые по разделам.&lt;/b&gt;&lt;p&gt;Дважды кликните по одному из пунктов, чтобы увидеть какие статьи содержатся в данном разделе. Для открытия статьи просто дважды щелкните на ней.&lt;/p&gt;</translation>
+ <translation type="unfinished">&lt;b&gt;Разделы справки, распределённые по категориям.&lt;/b&gt;&lt;p&gt;Дважды щёлкните по одному из пунктов для отображения разделов в данной категории. Для открытия раздела дважды щёлкните по нему.&lt;/p&gt;</translation>
</message>
<message>
+ <location line="-31"/>
<source>&lt;b&gt;Help&lt;/b&gt;&lt;p&gt;Choose the topic you want help on from the contents list, or search the index for keywords.&lt;/p&gt;</source>
- <translation>&lt;b&gt;Справка&lt;/b&gt;&lt;p&gt;Выберите необходимую статью справки из списка разделов или воспользуйтесь поиском по предметному указателю.&lt;/p&gt;</translation>
+ <translation type="unfinished">&lt;b&gt;Справка&lt;/b&gt;&lt;p&gt;Выберите раздел справки из содержания или воспользуйтесь поиском по предметному указателю.&lt;/p&gt;</translation>
</message>
<message>
+ <location line="+85"/>
<source>&lt;b&gt;List of available help topics.&lt;/b&gt;&lt;p&gt;Double-click on an item to open its help page. If more than one is found, you must specify which page you want.&lt;/p&gt;</source>
- <translation>&lt;b&gt;Список доступных статей справки.&lt;/b&gt;&lt;p&gt;Дважды щёлкните на пункте для открытия страницы помощи. Если найдено более одной, то потребуется выбрать желаемую страницу.&lt;/p&gt;</translation>
+ <translation type="unfinished">&lt;b&gt;Список доступных разделов справки.&lt;/b&gt;&lt;p&gt;Дважды щёлкните по одному из пунктов для открытия страницы справки. Если найдено более одной страницы, выберите желаемую.&lt;/p&gt;</translation>
</message>
<message>
+ <location line="+62"/>
<source>Add new bookmark</source>
- <translation>Добавить новую закладку</translation>
+ <translation>Добавить закладку</translation>
</message>
<message>
+ <location line="+3"/>
<source>Add the currently displayed page as a new bookmark.</source>
- <translation>Добавление текущей открытой страницы в закладки.</translation>
+ <translation>Добавить отображаемую страницу в закладки.</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.cpp" line="+393"/>
<source>Cannot open the index file %1</source>
<translation>Не удаётся открыть файл индекса %1</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.ui" line="-134"/>
<source>Con&amp;tents</source>
<translation>Содер&amp;жание</translation>
</message>
<message>
+ <location line="+144"/>
<source>Delete bookmark</source>
<translation>Удалить закладку</translation>
</message>
<message>
+ <location line="+3"/>
<source>Delete the selected bookmark.</source>
- <translation>Удаление выбранной закладки.</translation>
+ <translation>Удалить выбранную закладку.</translation>
</message>
<message>
+ <location line="+92"/>
<source>Display the help page for the full text search.</source>
- <translation>Открытие справки по полнотекстовому поиску.</translation>
+ <translation>Показать справку по полнотекстовому поиску.</translation>
</message>
<message>
+ <location line="-3"/>
<source>Display the help page.</source>
- <translation>Открыть страницу справки.</translation>
+ <translation>Показать страницу справки.</translation>
</message>
<message>
+ <location line="-240"/>
<source>Displays help topics organized by category, index or bookmarks. Another tab inherits the full text search.</source>
- <translation>Здесь отображается список тем, распределенных по разделам, указатель или закладки. Последняя вкладка содержит полнотекстовый поиск.</translation>
+ <translation>Отображает список разделов, распредёленных по категориям, указатель или закладки. Последняя вкладка содержит панель полнотекстового поиска.</translation>
</message>
<message>
+ <location line="+96"/>
<source>Displays the list of bookmarks.</source>
<translation>Отображает список закладок.</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.cpp" line="+59"/>
+ <location line="+124"/>
<source>Documentation file %1 does not exist!
Skipping file.</source>
<translation>Файл документации %1 не существует!
Пропущен.</translation>
</message>
<message>
+ <location line="+8"/>
<source>Documentation file %1 is not compatible!
Skipping file.</source>
- <translation>Файл документации %1 не совместим!
+ <translation>Несовместимый файл документации %1!
Пропущен.</translation>
</message>
<message>
+ <location line="+48"/>
+ <location line="+469"/>
<source>Done</source>
<translation>Готово</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.ui" line="-36"/>
<source>Enter keyword</source>
<translation>Введите ключевое слово</translation>
</message>
<message>
+ <location line="+142"/>
<source>Enter searchword(s).</source>
- <translation>Введите одно или более слов для поиска.</translation>
+ <translation>Введите одно или несколько слов для поиска.</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.cpp" line="-725"/>
<source>Failed to load keyword index file
Assistant will not work!</source>
<translation>Не удалось загрузить файл индекса ключевых слов
-Assistant не будет работать!</translation>
+Qt Assistant не будет работать!</translation>
</message>
<message>
+ <location line="+678"/>
<source>Failed to save fulltext search index
Assistant will not work!</source>
<translation>Не удалось сохранить индекс полнотекстового поиска
-Assistant не будет работать!</translation>
+Qt Assistant не будет работать!</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.ui" line="+20"/>
<source>Found &amp;Documents:</source>
<translation>Найденные &amp;документы:</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.cpp" line="+90"/>
+ <location line="+9"/>
<source>Full Text Search</source>
<translation>Полнотекстовый поиск</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.ui" line="+24"/>
<source>He&amp;lp</source>
<translation>&amp;Справка</translation>
</message>
<message>
+ <location line="-261"/>
<source>Help</source>
<translation>Справка</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.cpp" line="-70"/>
<source>Indexing files...</source>
<translation>Индексирование файлов...</translation>
</message>
<message>
+ <location line="-798"/>
<source>Open Link in New Tab</source>
<translation>Открыть ссылку в новой вкладке</translation>
</message>
<message>
+ <location line="-3"/>
<source>Open Link in New Window</source>
<translation>Открыть ссылку в новом окне</translation>
</message>
<message>
+ <location line="+182"/>
+ <location line="+133"/>
<source>Parse Error</source>
<translation>Ошибка обработки</translation>
</message>
<message>
+ <location line="-239"/>
+ <location line="+82"/>
<source>Prepare...</source>
<translation>Подготовка...</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.ui" line="+321"/>
<source>Preparing...</source>
<translation>Подготовка...</translation>
</message>
<message>
+ <location line="-34"/>
<source>Pressing this button starts the search.</source>
<translation>Нажатие на эту кнопку запустит процесс поиска.</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.cpp" line="-64"/>
+ <location line="+16"/>
+ <location line="+661"/>
<source>Qt Assistant</source>
<translation>Qt Assistant</translation>
</message>
<message>
+ <location line="+45"/>
<source>Reading dictionary...</source>
<translation>Чтение каталога...</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.ui" line="-80"/>
<source>Searching f&amp;or:</source>
<translation>&amp;Искать:</translation>
</message>
<message>
+ <location line="+77"/>
<source>Start searching.</source>
<translation>Начать поиск.</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.cpp" line="+56"/>
<source>The closing quotation mark is missing.</source>
<translation>Пропущена закрывающая кавычка.</translation>
</message>
<message>
+ <location line="-9"/>
<source>Using a wildcard within phrases is not allowed.</source>
- <translation>Использование символов-заменителей внутри фраз не допустимо.</translation>
+ <translation>Использование символов-заменителей внутри фраз недопустимо.</translation>
</message>
<message>
+ <location line="-694"/>
+ <location line="+124"/>
+ <location line="+8"/>
<source>Warning</source>
<translation>Предупреждение</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.ui" line="-240"/>
+ <location line="+74"/>
<source>column 1</source>
<translation>столбец 1</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.cpp" line="-304"/>
<source>Open Link in Current Tab</source>
<translation>Открыть ссылку в текущей вкладке</translation>
</message>
<message numerus="yes">
+ <location line="+882"/>
<source>%n document(s) found.</source>
<translation>
<numerusform>Найден %n документ.</numerusform>
@@ -265,10 +336,12 @@ Assistant не будет работать!</translation>
</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/helpdialog.ui" line="-22"/>
<source>&amp;Bookmarks</source>
<translation>&amp;Закладки</translation>
</message>
<message>
+ <location line="+73"/>
<source>&amp;Delete</source>
<translation>&amp;Удалить</translation>
</message>
@@ -276,38 +349,47 @@ Assistant не будет работать!</translation>
<context>
<name>HelpWindow</name>
<message>
+ <location filename="../tools/assistant/compat/helpwindow.cpp" line="+127"/>
<source>&lt;div align=&quot;center&quot;&gt;&lt;h1&gt;The page could not be found&lt;/h1&gt;&lt;br&gt;&lt;h3&gt;&apos;%1&apos;&lt;/h3&gt;&lt;/div&gt;</source>
<translation>&lt;div align=&quot;center&quot;&gt;&lt;h1&gt;Страница не найдена&lt;/h1&gt;&lt;br&gt;&lt;h3&gt;&apos;%1&apos;&lt;/h3&gt;&lt;/div&gt;</translation>
</message>
<message>
+ <location line="+58"/>
<source>Copy &amp;Link Location</source>
<translation>Копировать &amp;адрес ссылки</translation>
</message>
<message>
+ <location line="-56"/>
<source>Error...</source>
<translation>Ошибка...</translation>
</message>
<message>
+ <location line="-3"/>
<source>Failed to open link: &apos;%1&apos;</source>
<translation>Не удалось открыть ссылку: &apos;%1&apos;</translation>
</message>
<message>
+ <location line="-29"/>
<source>Help</source>
<translation>Справка</translation>
</message>
<message>
+ <location line="+2"/>
<source>OK</source>
<translation>Закрыть</translation>
</message>
<message>
+ <location line="+89"/>
<source>Open Link in New Tab</source>
<translation>Открыть ссылку в новой вкладке</translation>
</message>
<message>
+ <location line="+2"/>
<source>Open Link in New Window Shift+LMB</source>
<translation>Открыть ссылку в новом окне Shift+LMB</translation>
</message>
<message>
+ <location line="-92"/>
<source>Unable to launch web browser.
</source>
<translation>Невозможно запустить вэб-браузер.
@@ -317,6 +399,7 @@ Assistant не будет работать!</translation>
<context>
<name>Index</name>
<message>
+ <location filename="../tools/assistant/compat/index.cpp" line="+385"/>
<source>Untitled</source>
<translation>Неозаглавлено</translation>
</message>
@@ -324,354 +407,445 @@ Assistant не будет работать!</translation>
<context>
<name>MainWindow</name>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.ui" line="+375"/>
+ <location line="+3"/>
<source>&quot;What&apos;s This?&quot; context sensitive help.</source>
- <translation>&quot;Что это?&quot; - контекстная справка.</translation>
+ <translation>Контекстная справка &quot;Что это?&quot;.</translation>
</message>
<message>
+ <location line="-17"/>
<source>&amp;Add Bookmark</source>
- <translation>&amp;Добавление закладки</translation>
+ <translation>&amp;Добавить закладку</translation>
</message>
<message>
+ <location line="-11"/>
<source>&amp;Close</source>
<translation>&amp;Закрыть</translation>
</message>
<message>
+ <location line="-141"/>
<source>&amp;Copy</source>
<translation>&amp;Копировать</translation>
</message>
<message>
+ <location line="-49"/>
<source>&amp;Edit</source>
<translation>&amp;Правка</translation>
</message>
<message>
+ <location line="-39"/>
<source>&amp;File</source>
<translation>&amp;Файл</translation>
</message>
<message>
+ <location line="+102"/>
<source>&amp;Find in Text...</source>
<translation>П&amp;оиск по тексту...</translation>
</message>
<message>
+ <location line="-82"/>
<source>&amp;Go</source>
<translation>&amp;Перейти</translation>
</message>
<message>
+ <location line="-31"/>
<source>&amp;Help</source>
<translation>&amp;Справка</translation>
</message>
<message>
+ <location line="+143"/>
<source>&amp;Home</source>
<translation>&amp;Домой</translation>
</message>
<message>
+ <location line="+28"/>
<source>&amp;Next</source>
- <translation>&amp;Вперёд</translation>
+ <translation>Сл&amp;едующий</translation>
</message>
<message>
+ <location line="-14"/>
<source>&amp;Previous</source>
- <translation>&amp;Назад</translation>
+ <translation>&amp;Предыдущий</translation>
</message>
<message>
+ <location line="-86"/>
<source>&amp;Print...</source>
<translation>&amp;Печать...</translation>
</message>
<message>
+ <location line="-28"/>
<source>&amp;View</source>
<translation>&amp;Вид</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.cpp" line="+121"/>
<source>&amp;Window</source>
<translation>&amp;Окно</translation>
</message>
<message>
+ <location line="+429"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.ui" line="+150"/>
<source>About Qt</source>
<translation>О Qt</translation>
</message>
<message>
+ <location line="-11"/>
<source>About Qt Assistant</source>
<translation>О Qt Assistant</translation>
</message>
<message>
+ <location line="+94"/>
<source>Add Tab</source>
<translation>Добавить вкладку</translation>
</message>
<message>
+ <location line="-22"/>
<source>Add the currently displayed page as a new bookmark.</source>
- <translation>Добавление текущей открытой страницы в закладки.</translation>
+ <translation>Добавить отображаемую страницу в закладки.</translation>
</message>
<message>
+ <location line="-228"/>
<source>Boo&amp;kmarks</source>
<translation>&amp;Закладки</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.cpp" line="+244"/>
<source>Cannot open file for writing!</source>
- <translation>Не удается открыть файл для записи!</translation>
+ <translation>Не удалось открыть файл для записи!</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.ui" line="+274"/>
<source>Close Tab</source>
<translation>Закрыть вкладку</translation>
</message>
<message>
+ <location line="-57"/>
<source>Close the current window.</source>
<translation>Закрыть текущее окно.</translation>
</message>
<message>
+ <location line="-58"/>
<source>Display further information about Qt Assistant.</source>
<translation>Показать дополнительную информацию о Qt Assistant.</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.cpp" line="-514"/>
<source>Displays the main page of a specific documentation set.</source>
- <translation>Открывает главную страницу выбранного набора документации.</translation>
+ <translation type="unfinished">Открывает стартовую страницу выбранного набора документации.</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.ui" line="-103"/>
<source>E&amp;xit</source>
- <translation>Вы&amp;ход</translation>
+ <translation>В&amp;ыход</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.cpp" line="+69"/>
<source>Failed to open about application contents in file: &apos;%1&apos;</source>
<translation>Не удалось получить информацию о приложении из файла: &apos;%1&apos;</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.ui" line="+42"/>
<source>Find &amp;Next</source>
- <translation>Продолжить п&amp;оиск</translation>
+ <translation>Найти &amp;следующее</translation>
</message>
<message>
+ <location line="+8"/>
<source>Find &amp;Previous</source>
<translation>Найти &amp;предыдущее</translation>
</message>
<message>
+ <location line="+206"/>
<source>Font Settings...</source>
<translation>Настройки шрифта...</translation>
</message>
<message>
+ <location line="-361"/>
<source>Go</source>
<translation>Перейти</translation>
</message>
<message>
+ <location line="+169"/>
<source>Go to the home page. Qt Assistant&apos;s home page is the Qt Reference Documentation.</source>
<translation>Перейти на домашнюю страницу. Домашная страница Qt Assistant - Справочная документация по Qt.</translation>
</message>
<message>
+ <location line="+28"/>
<source>Go to the next page.</source>
<translation>Переход на следующую страницу.</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.cpp" line="-191"/>
<source>Initializing Qt Assistant...</source>
<translation>Инициализация Qt Assistant...</translation>
</message>
<message>
+ <location line="-35"/>
<source>Minimize</source>
<translation>Свернуть</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.ui" line="+55"/>
<source>New Window</source>
<translation>Новое окно</translation>
</message>
<message>
+ <location line="+55"/>
<source>Next Tab</source>
<translation>Следующая вкладка</translation>
</message>
<message>
+ <location line="-52"/>
<source>Open a new window.</source>
<translation>Открыть новое окно.</translation>
</message>
<message>
+ <location line="-116"/>
<source>Open the Find dialog. Qt Assistant will search the currently displayed page for the text you enter.</source>
- <translation>Открыть окно поиска. Qt Assistant произведёт поиск введённого текста на текущей открытой странице.</translation>
+ <translation>Открыть окно поиска. Qt Assistant произведёт поиск введённого текста на отображаемой странице.</translation>
</message>
<message>
+ <location line="+176"/>
<source>Previous Tab</source>
<translation>Предыдущая вкладка</translation>
</message>
<message>
+ <location line="-218"/>
<source>Print the currently displayed page.</source>
- <translation>Печать текущей открытой страницы.</translation>
+ <translation>Печатать отображаемую страницу.</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.cpp" line="+206"/>
+ <location line="+1"/>
<source>Qt Assistant</source>
<translation>Qt Assistant</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.ui" line="+237"/>
<source>Qt Assistant Manual</source>
<translation>Руководство по Qt Assistant</translation>
</message>
<message>
+ <location line="-366"/>
<source>Qt Assistant by Nokia</source>
<translation>Qt Assistant от Nokia</translation>
</message>
<message>
+ <location line="+140"/>
<source>Quit Qt Assistant.</source>
<translation>Выйти из Qt Assistant.</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.cpp" line="+458"/>
+ <location line="+6"/>
<source>Save Page</source>
<translation>Сохранить страницу</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.ui" line="+234"/>
<source>Save Page As...</source>
<translation>Сохранить страницу как...</translation>
</message>
<message>
+ <location line="+14"/>
<source>Select the page in contents tab.</source>
- <translation>Выбор страницы в оглавлении.</translation>
+ <translation>Выбрать страницу во вкладке содержания.</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.cpp" line="-691"/>
<source>Sidebar</source>
<translation>Боковая панель</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.ui" line="-3"/>
<source>Sync with Table of Contents</source>
- <translation>Синхронизировать с оглавлением</translation>
+ <translation>Синхронизировать с содержанием</translation>
</message>
<message>
+ <location line="-380"/>
<source>Toolbar</source>
<translation>Панель инструментов</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.cpp" line="+97"/>
<source>Views</source>
<translation>Виды</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.ui" line="+312"/>
<source>What&apos;s This?</source>
<translation>Что это?</translation>
</message>
<message>
+ <location line="-58"/>
<source>Zoom &amp;in</source>
<translation>У&amp;величить</translation>
</message>
<message>
+ <location line="+14"/>
<source>Zoom &amp;out</source>
<translation>У&amp;меньшить</translation>
</message>
<message>
+ <location line="-11"/>
<source>Zoom in on the document, i.e. increase the font size.</source>
- <translation>Увеличение масштаба документа, т.е. увеличение размера шрифта.</translation>
+ <translation>Увеличить размер шрифта.</translation>
</message>
<message>
+ <location line="+14"/>
<source>Zoom out on the document, i.e. decrease the font size.</source>
- <translation>Уменьшение масштаба документа, т.е. уменьшение размера шрифта.</translation>
+ <translation>Уменьшить размер шрифта.</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.cpp" line="-76"/>
<source>Ctrl+M</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+60"/>
<source>SHIFT+CTRL+=</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+4"/>
<source>Ctrl+T</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+1"/>
<source>Ctrl+I</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+1"/>
<source>Ctrl+B</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+1"/>
<source>Ctrl+S</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+1"/>
<source>Ctrl+]</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+1"/>
<source>Ctrl+[</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/mainwindow.ui" line="-144"/>
<source>Ctrl+P</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+11"/>
<source>Ctrl+Q</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+14"/>
<source>Copy the selected text to the clipboard.</source>
<translation>Скопировать выделенный текст в буфер обмена.</translation>
</message>
<message>
+ <location line="+3"/>
<source>Ctrl+C</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+14"/>
<source>Ctrl+F</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+8"/>
<source>F3</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+8"/>
<source>Shift+F3</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+14"/>
<source>Ctrl+Home</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+11"/>
<source>Go to the previous page.</source>
<translation>Переход на предыдущую страницу.</translation>
</message>
<message>
+ <location line="+3"/>
<source>Alt+Left</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+14"/>
<source>Alt+Right</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+33"/>
<source>Ctrl++</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+14"/>
<source>Ctrl+-</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+11"/>
<source>Ctrl+N</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+11"/>
<source>Ctrl+W</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+25"/>
<source>Shift+F1</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+8"/>
<source>Ctrl+Alt+N</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+8"/>
<source>Ctrl+Alt+Right</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+8"/>
<source>Ctrl+Alt+Left</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+8"/>
<source>Ctrl+Alt+Q</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+11"/>
<source>F1</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <location line="+8"/>
<source>Ctrl+Alt+S</source>
<translation type="unfinished"></translation>
</message>
@@ -679,6 +853,7 @@ Assistant не будет работать!</translation>
<context>
<name>QObject</name>
<message>
+ <location filename="../tools/assistant/compat/config.cpp" line="+350"/>
<source>Qt Assistant by Nokia</source>
<translation>Qt Assistant от Nokia</translation>
</message>
@@ -686,54 +861,67 @@ Assistant не будет работать!</translation>
<context>
<name>TabbedBrowser</name>
<message>
+ <location filename="../tools/assistant/compat/tabbedbrowser.cpp" line="+149"/>
<source>...</source>
<translation>...</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/tabbedbrowser.ui" line="+197"/>
<source>&lt;img src=&quot;:/trolltech/assistant/images/wrap.png&quot;&gt;&amp;nbsp;Search wrapped</source>
<translation>&lt;img src=&quot;:/trolltech/assistant/images/wrap.png&quot;&gt;&amp;nbsp;Поиск с начала</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/tabbedbrowser.cpp" line="+86"/>
<source>Add page</source>
- <translation>Добавить страницу</translation>
+ <translation>Добавить вкладку</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/tabbedbrowser.ui" line="-26"/>
<source>Case Sensitive</source>
- <translation>Регистрозависимо</translation>
+ <translation>Учитывать регистр</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/tabbedbrowser.cpp" line="+254"/>
<source>Close Other Tabs</source>
<translation>Закрыть остальные вкладки</translation>
</message>
<message>
+ <location line="-1"/>
<source>Close Tab</source>
<translation>Закрыть вкладку</translation>
</message>
<message>
+ <location line="-244"/>
<source>Close page</source>
- <translation>Закрыть страницу</translation>
+ <translation>Закрыть вкладку</translation>
</message>
<message>
+ <location line="+243"/>
<source>New Tab</source>
<translation>Новая вкладка</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/tabbedbrowser.ui" line="-19"/>
<source>Next</source>
- <translation>Следующий</translation>
+ <translation>Следующее</translation>
</message>
<message>
+ <location line="-22"/>
<source>Previous</source>
- <translation>Предыдущий</translation>
+ <translation>Предыдущее</translation>
</message>
<message>
+ <location line="-62"/>
<source>Untitled</source>
<translation>Безымянный</translation>
</message>
<message>
+ <location line="+110"/>
<source>Whole words</source>
- <translation>Слова полностью</translation>
+ <translation>Слова целиком</translation>
</message>
<message>
+ <location line="-123"/>
<source>TabbedBrowser</source>
<translation type="unfinished"></translation>
</message>
@@ -741,40 +929,49 @@ Assistant не будет работать!</translation>
<context>
<name>TopicChooser</name>
<message>
+ <location filename="../tools/assistant/compat/topicchooser.ui" line="+149"/>
<source>&amp;Close</source>
<translation>&amp;Закрыть</translation>
</message>
<message>
+ <location line="-16"/>
<source>&amp;Display</source>
<translation>&amp;Показать</translation>
</message>
<message>
+ <location line="-53"/>
<source>&amp;Topics</source>
- <translation>&amp;Статьи</translation>
+ <translation>&amp;Разделы</translation>
</message>
<message>
+ <location line="-27"/>
<source>Choose Topic</source>
- <translation>Выбор статьи</translation>
+ <translation>Выбор раздела</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/topicchooser.cpp" line="+56"/>
<source>Choose a topic for &lt;b&gt;%1&lt;/b&gt;</source>
- <translation>Выберите статью для &lt;b&gt;%1&lt;/b&gt;</translation>
+ <translation>Выберите раздел для &lt;b&gt;%1&lt;/b&gt;</translation>
</message>
<message>
+ <location filename="../tools/assistant/compat/topicchooser.ui" line="+93"/>
<source>Close the Dialog.</source>
- <translation>Закрытие окна.</translation>
+ <translation>Закрыть диалог.</translation>
</message>
<message>
+ <location line="-56"/>
<source>Displays a list of available help topics for the keyword.</source>
- <translation>Показывает список доступных статей справки, соответствующих ключевому слову.</translation>
+ <translation>Показывает список доступных разделов справки, найденных по ключевому слову.</translation>
</message>
<message>
+ <location line="+40"/>
<source>Open the topic selected in the list.</source>
- <translation>Открытие выбранной в списке темы.</translation>
+ <translation>Открыть выбранный раздел.</translation>
</message>
<message>
+ <location line="-74"/>
<source>Select a topic from the list and click the &lt;b&gt;Display&lt;/b&gt;-button to open the online help.</source>
- <translation>Выберите статью из списка и нажмите на кнопку &lt;b&gt;Показать&lt;/b&gt; для открытия онлайн справки.</translation>
+ <translation>Выберите раздел из списка и нажмите на кнопку &lt;b&gt;Показать&lt;/b&gt; для открытия онлайн справки.</translation>
</message>
</context>
</TS>
diff --git a/translations/assistant_ru.ts b/translations/assistant_ru.ts
index 32aa739..ecec0f8 100644
--- a/translations/assistant_ru.ts
+++ b/translations/assistant_ru.ts
@@ -57,16 +57,16 @@
<translation>Новая папка</translation>
</message>
<message>
- <location filename="../tools/assistant/tools/assistant/bookmarkmanager.cpp" line="+185"/>
+ <location filename="../tools/assistant/tools/assistant/bookmarkmanager.cpp" line="+184"/>
<location line="+18"/>
- <location line="+36"/>
- <location line="+24"/>
- <location line="+32"/>
+ <location line="+39"/>
+ <location line="+18"/>
+ <location line="+30"/>
<source>Bookmarks</source>
<translation>Закладки</translation>
</message>
<message>
- <location line="-69"/>
+ <location line="-61"/>
<source>Delete Folder</source>
<translation>Удалить папку</translation>
</message>
@@ -79,12 +79,12 @@
<context>
<name>BookmarkManager</name>
<message>
- <location line="+449"/>
+ <location line="+434"/>
<source>Bookmarks</source>
<translation>Закладки</translation>
</message>
<message>
- <location line="+36"/>
+ <location line="+37"/>
<source>Remove</source>
<translation>Удалить</translation>
</message>
@@ -94,7 +94,7 @@
<translation>Удаление папки приведёт к удалению её содержимого.&lt;br&gt;Желаете продолжить?</translation>
</message>
<message>
- <location line="+109"/>
+ <location line="+143"/>
<location line="+9"/>
<source>New Folder</source>
<translation>Новая папка</translation>
@@ -103,7 +103,7 @@
<context>
<name>BookmarkWidget</name>
<message>
- <location line="-436"/>
+ <location line="-462"/>
<source>Delete Folder</source>
<translation>Удалить папку</translation>
</message>
@@ -138,7 +138,7 @@
<translation>Фильтр:</translation>
</message>
<message>
- <location line="+23"/>
+ <location line="+24"/>
<source>Add</source>
<translation>Добавить</translation>
</message>
@@ -161,7 +161,7 @@
<translation>Закрыть текущую страницу</translation>
</message>
<message>
- <location line="+284"/>
+ <location line="+291"/>
<source>Print Document</source>
<translation>Печать документа</translation>
</message>
@@ -226,24 +226,24 @@
<context>
<name>FindWidget</name>
<message>
- <location filename="../tools/assistant/tools/assistant/centralwidget.cpp" line="-925"/>
+ <location filename="../tools/assistant/tools/assistant/centralwidget.cpp" line="-932"/>
<source>Previous</source>
- <translation>Предыдущее совпадение</translation>
+ <translation>Предыдущее</translation>
</message>
<message>
<location line="+4"/>
<source>Next</source>
- <translation>Следующее совпадение</translation>
+ <translation>Следующее</translation>
</message>
<message>
<location line="+4"/>
<source>Case Sensitive</source>
- <translation>Регистрозависимо</translation>
+ <translation>Учитывать регистр</translation>
</message>
<message>
<location line="+3"/>
<source>Whole words</source>
- <translation>Слова полностью</translation>
+ <translation>Слова целиком</translation>
</message>
<message>
<location line="+12"/>
@@ -441,31 +441,31 @@
<name>MainWindow</name>
<message>
<location filename="../tools/assistant/tools/assistant/mainwindow.cpp" line="+108"/>
- <location line="+354"/>
+ <location line="+384"/>
<source>Index</source>
- <translation>Индекс</translation>
+ <translation>Указатель</translation>
</message>
<message>
- <location line="-348"/>
- <location line="+346"/>
+ <location line="-378"/>
+ <location line="+376"/>
<source>Contents</source>
<translation>Содержание</translation>
</message>
<message>
- <location line="-341"/>
- <location line="+345"/>
+ <location line="-371"/>
+ <location line="+375"/>
<source>Bookmarks</source>
<translation>Закладки</translation>
</message>
<message>
- <location line="-333"/>
- <location line="+208"/>
- <location line="+476"/>
+ <location line="-363"/>
+ <location line="+215"/>
+ <location line="+500"/>
<source>Qt Assistant</source>
<translation>Qt Assistant</translation>
</message>
<message>
- <location line="-508"/>
+ <location line="-532"/>
<location line="+5"/>
<source>Unfiltered</source>
<translation>Без фильтрации</translation>
@@ -473,10 +473,10 @@
<message>
<location line="+21"/>
<source>Looking for Qt Documentation...</source>
- <translation type="unfinished">Поиск по документации Qt...</translation>
+ <translation>Поиск документации по Qt...</translation>
</message>
<message>
- <location line="+61"/>
+ <location line="+84"/>
<source>&amp;File</source>
<translation>&amp;Файл</translation>
</message>
@@ -656,7 +656,7 @@
<translation>Добавить закладку...</translation>
</message>
<message>
- <location line="+1"/>
+ <location line="+2"/>
<source>CTRL+D</source>
<translation type="unfinished"></translation>
</message>
@@ -723,12 +723,12 @@
<message>
<location line="+114"/>
<source>Could not find the associated content item.</source>
- <translation type="unfinished">Не удалось найти элемент, связанный с содержанием.</translation>
+ <translation>Не удалось найти элемент, связанный с содержанием.</translation>
</message>
<message>
<location line="+81"/>
<source>About %1</source>
- <translation type="unfinished">О %1</translation>
+ <translation>О %1</translation>
</message>
<message>
<location line="+114"/>
@@ -767,7 +767,7 @@
<message>
<location line="+1"/>
<source>Some documents currently opened in Assistant reference the documentation you are attempting to remove. Removing the documentation will close those documents.</source>
- <translation>Некоторые открытые в Qt Assistant документы ссылаются на документацию, которую вы пытаетесь удалить. Удаление данной документации приведёт к закрытию таких документов.</translation>
+ <translation>Некоторые открытые в Qt Assistant документы ссылаются на документацию, которую вы пытаетесь удалить. Её удаление приведёт к закрытию этих документов.</translation>
</message>
<message>
<location line="+2"/>
@@ -830,7 +830,7 @@
<message>
<location line="+11"/>
<source>1</source>
- <translation type="unfinished"></translation>
+ <translation>1</translation>
</message>
<message>
<location line="+8"/>
@@ -876,18 +876,12 @@
<message>
<location line="+7"/>
<source>Restore to default</source>
- <translation type="unfinished">Восстановить по умолчанию</translation>
+ <translation>Страница по умолчанию</translation>
</message>
</context>
<context>
<name>QObject</name>
<message>
- <location filename="../tools/assistant/tools/assistant/bookmarkmanager.cpp" line="+157"/>
- <location line="+1"/>
- <source>Bookmark</source>
- <translation>Закладка</translation>
- </message>
- <message>
<location filename="../tools/assistant/tools/assistant/cmdlineparser.cpp" line="+112"/>
<source>The specified collection file does not exist!</source>
<translation type="unfinished">Указанный файл набора отсутствует!</translation>
@@ -1037,17 +1031,17 @@ Reason:
<message>
<location filename="../tools/assistant/tools/assistant/topicchooser.cpp" line="+54"/>
<source>Choose a topic for &lt;b&gt;%1&lt;/b&gt;:</source>
- <translation>Выберите статью для &lt;b&gt;%1&lt;/b&gt;:</translation>
+ <translation>Выберите раздел для &lt;b&gt;%1&lt;/b&gt;:</translation>
</message>
<message>
<location filename="../tools/assistant/tools/assistant/topicchooser.ui" line="+16"/>
<source>Choose Topic</source>
- <translation>Выбор статьи</translation>
+ <translation>Выбор раздела</translation>
</message>
<message>
<location line="+21"/>
<source>&amp;Topics</source>
- <translation>&amp;Статьи</translation>
+ <translation>&amp;Разделы</translation>
</message>
<message>
<location line="+51"/>
diff --git a/translations/linguist_ru.ts b/translations/linguist_ru.ts
index 058d86a..86c7434 100644
--- a/translations/linguist_ru.ts
+++ b/translations/linguist_ru.ts
@@ -42,7 +42,7 @@
<message>
<location line="+7"/>
<source>Note that the modified entries will be reset to unfinished if &apos;Set translated entries to finished&apos; above is unchecked.</source>
- <translation>Имейте в виду, что изменённые записи будут отмечены как незавершённые, если не включен параметр &quot;Помечать переведенные записи как завершённые&quot;.</translation>
+ <translation>Имейте в виду, что изменённые записи будут отмечены как незавершённые, если не включён параметр &quot;Помечать переведенные записи как завершённые&quot;.</translation>
</message>
<message>
<location line="+3"/>
@@ -289,7 +289,7 @@ Will assume a single universal form.</source>
<context>
<name>LRelease</name>
<message numerus="yes">
- <location filename="../tools/linguist/shared/qm.cpp" line="+715"/>
+ <location filename="../tools/linguist/shared/qm.cpp" line="+732"/>
<source> Generated %n translation(s) (%1 finished and %2 unfinished)
</source>
<translation>
@@ -617,7 +617,7 @@ All files (*)</source>
<message>
<location line="+6"/>
<source>&lt;center&gt;&lt;img src=&quot;:/images/splash.png&quot;/&gt;&lt;/img&gt;&lt;p&gt;%1&lt;/p&gt;&lt;/center&gt;&lt;p&gt;Qt Linguist is a tool for adding translations to Qt applications.&lt;/p&gt;&lt;p&gt;%2&lt;/p&gt;&lt;p&gt;Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).&lt;/p&gt;&lt;p&gt;The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.&lt;/p&gt;</source>
- <translation type="unfinished">&lt;center&gt;&lt;img src=&quot;:/images/splash.png&quot;/&gt;&lt;/img&gt;&lt;p&gt;%1&lt;/p&gt;&lt;/center&gt;&lt;p&gt;Qt Linguist - инструмент для добавления переводов в приложения на основе Qt.&lt;/p&gt;&lt;p&gt;%2&lt;/p&gt;&lt;p&gt;Copyright (C) 2009 Корпорация Nokia и/или её дочерние подразделения.&lt;/p&gt;&lt;p&gt;Программа предоставляется &quot;как есть&quot; без гарантий любого рода, включая гарантии дизайна, коммерческой ценности и пригодности для определённой цели.&lt;/p&gt;</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<location line="+41"/>
@@ -1250,7 +1250,7 @@ All files (*)</source>
<message>
<location line="+3"/>
<source>Toggle checking that phrase suggestions are used.</source>
- <translation>Переключение проверки использования предложений для фраз. Если выявлено несовпадение, будет показано сообщение в окне предупреждений.</translation>
+ <translation>Переключение проверки использования предложений для фраз.</translation>
</message>
<message>
<location line="+3"/>
@@ -1466,6 +1466,11 @@ All files (*)</source>
</message>
<message>
<location line="+30"/>
+ <source>Russian</source>
+ <translation>Русский</translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>German</source>
<translation>Немецкий</translation>
</message>
@@ -1517,7 +1522,7 @@ All files (*)</source>
<message>
<location line="+3"/>
<source>Developer comments</source>
- <translation>Комментарии разработчика</translation>
+ <translation>Комментарий разработчика</translation>
</message>
<message>
<location line="+3"/>
@@ -1547,7 +1552,7 @@ All files (*)</source>
<message>
<location line="+1"/>
<source>%1 translator comments</source>
- <translation>Комментарий переводчика на %1</translation>
+ <translation>%1 перевод: комментарий переводчика</translation>
</message>
<message>
<location line="+140"/>
@@ -1583,10 +1588,11 @@ Line: %2</source>
<context>
<name>MsgEdit</name>
<message>
- <location filename="../tools/linguist/linguist/messageeditor.cpp" line="-544"/>
+ <location filename="../tools/linguist/linguist/messageeditor.cpp" line="-545"/>
<source></source>
<comment>This is the right panel of the main window.</comment>
- <translation type="unfinished"></translation>
+ <translatorcomment>Правая панель главного окна</translatorcomment>
+ <translation></translation>
</message>
</context>
<context>
@@ -1800,17 +1806,17 @@ Line: %2</source>
<message>
<location filename="../tools/linguist/shared/cpp.cpp" line="+1089"/>
<source>C++ source files</source>
- <translation>Исходные коды C++</translation>
+ <translation>Файлы исходных кодов C++</translation>
</message>
<message>
<location filename="../tools/linguist/shared/java.cpp" line="+652"/>
<source>Java source files</source>
- <translation>Исходные коды Java</translation>
+ <translation>Файлы исходных кодов Java</translation>
</message>
<message>
<location filename="../tools/linguist/shared/qscript.cpp" line="+2399"/>
<source>Qt Script source files</source>
- <translation>Исходные коды Qt Script</translation>
+ <translation>Файлы исходных кодов Qt Script</translation>
</message>
<message>
<location filename="../tools/linguist/shared/ui.cpp" line="+213"/>
diff --git a/translations/qt_help_ru.ts b/translations/qt_help_ru.ts
index 16748fb..c2dc041 100644
--- a/translations/qt_help_ru.ts
+++ b/translations/qt_help_ru.ts
@@ -6,17 +6,17 @@
<message>
<location filename="../tools/assistant/lib/qhelpsearchresultwidget.cpp" line="+110"/>
<source>Search Results</source>
- <translation>Результаты поиска</translation>
+ <translation>Результат поиска</translation>
</message>
<message>
<location line="+7"/>
<source>Note:</source>
- <translation>Замечание:</translation>
+ <translation>Примечание:</translation>
</message>
<message>
<location line="+1"/>
<source>The search results may not be complete since the documentation is still being indexed!</source>
- <translation>Могли быть показаны не все результаты, так как документация ещё индексируется!</translation>
+ <translation>Результат поиска может быть неполным, так как документация ещё индексируется!</translation>
</message>
<message>
<location line="+11"/>
@@ -45,7 +45,7 @@
<location line="+11"/>
<location line="+48"/>
<source>Cannot open collection file: %1</source>
- <translation>Не удалось открыть файл набора: %1</translation>
+ <translation type="unfinished">Не удалось открыть файл набора: %1</translation>
</message>
<message>
<location line="-39"/>
@@ -168,12 +168,12 @@
<message>
<location line="+6"/>
<source>Insert custom filters...</source>
- <translation>Вставка индивидуальных фильтров...</translation>
+ <translation>Добавление индивидуальных фильтров...</translation>
</message>
<message>
<location line="+12"/>
<source>Insert help data for filter section (%1 of %2)...</source>
- <translation>Вставка данных справки для секции фильтра (%1 из %2)...</translation>
+ <translation>Добавление данных справки для раздела фильтра (%1 из %2)...</translation>
</message>
<message>
<location line="+18"/>
@@ -198,7 +198,7 @@
<message>
<location line="+10"/>
<source>Insert files...</source>
- <translation>Вставка файлов...</translation>
+ <translation>Добавление файлов...</translation>
</message>
<message>
<location line="+42"/>
@@ -228,22 +228,22 @@
<message>
<location line="+24"/>
<source>Insert indices...</source>
- <translation>Вставка указателей...</translation>
+ <translation>Добавление указателей...</translation>
</message>
<message>
<location line="+80"/>
<source>Insert contents...</source>
- <translation>Вставка оглавления...</translation>
+ <translation>Добавление содержания...</translation>
</message>
<message>
<location line="+8"/>
<source>Cannot insert contents!</source>
- <translation>Не удаётся вставить оглавление!</translation>
+ <translation>Не удалось добавить содержание!</translation>
</message>
<message>
<location line="+12"/>
<source>Cannot register contents!</source>
- <translation>Не удаётся зарегистрировать оглавление!</translation>
+ <translation>Не удалось зарегистрировать содержание!</translation>
</message>
</context>
<context>
@@ -271,12 +271,12 @@
<message>
<location line="+5"/>
<source>&lt;B&gt;without&lt;/B&gt; the words:</source>
- <translation>&lt;B&gt;не содержит&lt;/B&gt; слова:</translation>
+ <translation>&lt;B&gt;не содержит&lt;/B&gt; слов:</translation>
</message>
<message>
<location line="+5"/>
<source>with &lt;B&gt;exact phrase&lt;/B&gt;:</source>
- <translation>содержит &lt;B&gt;фразу полностью&lt;/B&gt;:</translation>
+ <translation>содержит &lt;B&gt;точную фразу&lt;/B&gt;:</translation>
</message>
<message>
<location line="+5"/>
@@ -286,7 +286,7 @@
<message>
<location line="+5"/>
<source>with &lt;B&gt;at least one&lt;/B&gt; of the words:</source>
- <translation>содержит &lt;B&gt; минимум одно&lt;/B&gt; из слов:</translation>
+ <translation>содержит &lt;B&gt;хотя бы одно&lt;/B&gt; из слов:</translation>
</message>
</context>
<context>
@@ -294,7 +294,7 @@
<message>
<location filename="../tools/assistant/lib/qhelpsearchresultwidget.cpp" line="+235"/>
<source>0 - 0 of 0 Hits</source>
- <translation>0 - 0 из 0 соответствий</translation>
+ <translation>0 - 0 из 0 совпадений</translation>
</message>
</context>
<context>
@@ -302,7 +302,7 @@
<message>
<location line="-61"/>
<source>%1 - %2 of %3 Hits</source>
- <translation>%1 - %2 из %3 соответствий</translation>
+ <translation>%1 - %2 из %3 совпадений</translation>
</message>
</context>
<context>
@@ -315,12 +315,12 @@
<message>
<location filename="../tools/assistant/lib/qhelpprojectdata.cpp" line="+80"/>
<source>Unknown token.</source>
- <translation type="unfinished">Неизвестный токен.</translation>
+ <translation>Неизвестный идентификатор.</translation>
</message>
<message>
<location line="+13"/>
<source>Unknown token. Expected &quot;QtHelpProject&quot;!</source>
- <translation type="unfinished">Неизвестный токен. Ожидается &quot;QtHelpProject&quot;!</translation>
+ <translation>Неизвестный идентификатор. Ожидается &quot;QtHelpProject&quot;!</translation>
</message>
<message>
<location line="+5"/>
diff --git a/translations/qt_ru.ts b/translations/qt_ru.ts
index a27b8c4..c856786 100644
--- a/translations/qt_ru.ts
+++ b/translations/qt_ru.ts
@@ -57,7 +57,7 @@
<message>
<location line="+2"/>
<source>Accessibility</source>
- <translation>Средства для людей с ограниченными возможностями</translation>
+ <translation>Специальные возможности</translation>
</message>
</context>
<context>
@@ -917,22 +917,22 @@ to
<context>
<name>QAxSelect</name>
<message>
- <location filename="../src/activeqt/container/qaxselect.ui" line="+54"/>
+ <location filename="../src/activeqt/container/qaxselect.ui"/>
<source>Select ActiveX Control</source>
<translation>Выберите компоненту ActiveX</translation>
</message>
<message>
- <location line="+32"/>
+ <location/>
<source>OK</source>
<translation>Готово</translation>
</message>
<message>
- <location line="+16"/>
+ <location/>
<source>&amp;Cancel</source>
<translation>&amp;Отмена</translation>
</message>
<message>
- <location line="+49"/>
+ <location/>
<source>COM &amp;Object:</source>
<translation>COM &amp;Объект:</translation>
</message>
@@ -1022,7 +1022,7 @@ to
<translation>Открыть</translation>
</message>
<message>
- <location filename="../src/gui/itemviews/qitemeditorfactory.cpp" line="+544"/>
+ <location filename="../src/gui/itemviews/qitemeditorfactory.cpp" line="+556"/>
<source>False</source>
<translation>Нет</translation>
</message>
@@ -1491,32 +1491,32 @@ Please verify the correct file name was given.</source>
<translation>Показать скр&amp;ытые файлы</translation>
</message>
<message>
- <location filename="../src/gui/dialogs/qfiledialog.ui" line="+84"/>
- <location filename="../src/gui/dialogs/qfiledialog_wince.ui" line="+73"/>
+ <location filename="../src/gui/dialogs/qfiledialog.ui"/>
+ <location filename="../src/gui/dialogs/qfiledialog_wince.ui"/>
<source>Back</source>
<translation>Назад</translation>
</message>
<message>
- <location line="+14"/>
- <location filename="../src/gui/dialogs/qfiledialog_wince.ui" line="+14"/>
+ <location/>
+ <location filename="../src/gui/dialogs/qfiledialog_wince.ui"/>
<source>Parent Directory</source>
<translation>Родительский каталог</translation>
</message>
<message>
- <location line="+14"/>
- <location filename="../src/gui/dialogs/qfiledialog_wince.ui" line="+14"/>
+ <location/>
+ <location filename="../src/gui/dialogs/qfiledialog_wince.ui"/>
<source>List View</source>
<translation>Список</translation>
</message>
<message>
- <location line="+7"/>
- <location filename="../src/gui/dialogs/qfiledialog_wince.ui" line="+7"/>
+ <location/>
+ <location filename="../src/gui/dialogs/qfiledialog_wince.ui"/>
<source>Detail View</source>
<translation>Подробный вид</translation>
</message>
<message>
- <location line="+141"/>
- <location filename="../src/gui/dialogs/qfiledialog_wince.ui" line="+162"/>
+ <location/>
+ <location filename="../src/gui/dialogs/qfiledialog_wince.ui"/>
<source>Files of type:</source>
<translation>Типы файлов:</translation>
</message>
@@ -1619,8 +1619,8 @@ Do you want to delete it anyway?</source>
<translation>Показать </translation>
</message>
<message>
- <location filename="../src/gui/dialogs/qfiledialog.ui" line="-169"/>
- <location filename="../src/gui/dialogs/qfiledialog_wince.ui" line="-190"/>
+ <location filename="../src/gui/dialogs/qfiledialog.ui"/>
+ <location filename="../src/gui/dialogs/qfiledialog_wince.ui"/>
<source>Forward</source>
<translation>Вперед</translation>
</message>
@@ -1652,14 +1652,14 @@ Do you want to delete it anyway?</source>
<translation>&amp;Имя файла:</translation>
</message>
<message>
- <location filename="../src/gui/dialogs/qfiledialog.ui" line="-32"/>
- <location filename="../src/gui/dialogs/qfiledialog_wince.ui" line="+212"/>
+ <location filename="../src/gui/dialogs/qfiledialog.ui"/>
+ <location filename="../src/gui/dialogs/qfiledialog_wince.ui"/>
<source>Look in:</source>
<translation>Перейти к:</translation>
</message>
<message>
- <location line="+46"/>
- <location filename="../src/gui/dialogs/qfiledialog_wince.ui" line="-198"/>
+ <location/>
+ <location filename="../src/gui/dialogs/qfiledialog_wince.ui"/>
<source>Create New Folder</source>
<translation>Создать каталог</translation>
</message>
@@ -1828,7 +1828,7 @@ Do you want to delete it anyway?</source>
<message>
<location line="+3"/>
<source>Arabic</source>
- <translation type="unfinished"></translation>
+ <translation>Арабская</translation>
</message>
<message>
<location line="+3"/>
@@ -1838,57 +1838,57 @@ Do you want to delete it anyway?</source>
<message>
<location line="+3"/>
<source>Thaana</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Таана</translation>
</message>
<message>
<location line="+3"/>
<source>Devanagari</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Деванагири</translation>
</message>
<message>
<location line="+3"/>
<source>Bengali</source>
- <translation type="unfinished"></translation>
+ <translation>Бенгальская</translation>
</message>
<message>
<location line="+3"/>
<source>Gurmukhi</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Гурмукхи</translation>
</message>
<message>
<location line="+3"/>
<source>Gujarati</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Гуджарати</translation>
</message>
<message>
<location line="+3"/>
<source>Oriya</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Ория</translation>
</message>
<message>
<location line="+3"/>
<source>Tamil</source>
- <translation type="unfinished"></translation>
+ <translation>Тамильская</translation>
</message>
<message>
<location line="+3"/>
<source>Telugu</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Телугу</translation>
</message>
<message>
<location line="+3"/>
<source>Kannada</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Каннада</translation>
</message>
<message>
<location line="+3"/>
<source>Malayalam</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Малайялам</translation>
</message>
<message>
<location line="+3"/>
<source>Sinhala</source>
- <translation type="unfinished"></translation>
+ <translation>Сингальская</translation>
</message>
<message>
<location line="+3"/>
@@ -1898,7 +1898,7 @@ Do you want to delete it anyway?</source>
<message>
<location line="+3"/>
<source>Lao</source>
- <translation type="unfinished"></translation>
+ <translation>Лаосская</translation>
</message>
<message>
<location line="+3"/>
@@ -1908,7 +1908,7 @@ Do you want to delete it anyway?</source>
<message>
<location line="+3"/>
<source>Myanmar</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Мьянма</translation>
</message>
<message>
<location line="+3"/>
@@ -1953,7 +1953,7 @@ Do you want to delete it anyway?</source>
<message>
<location line="+3"/>
<source>Ogham</source>
- <translation type="unfinished"></translation>
+ <translation>Огамическая</translation>
</message>
<message>
<location line="+3"/>
@@ -2401,7 +2401,7 @@ Do you want to delete it anyway?</source>
<context>
<name>QIBaseDriver</name>
<message>
- <location filename="../src/sql/drivers/ibase/qsql_ibase.cpp" line="+1434"/>
+ <location filename="../src/sql/drivers/ibase/qsql_ibase.cpp" line="+1454"/>
<source>Error opening database</source>
<translation>Невозможно открыть базу данных</translation>
</message>
@@ -2424,7 +2424,7 @@ Do you want to delete it anyway?</source>
<context>
<name>QIBaseResult</name>
<message>
- <location line="-1095"/>
+ <location line="-1112"/>
<source>Unable to create BLOB</source>
<translation>Невозможно создать BLOB</translation>
</message>
@@ -2470,7 +2470,7 @@ Do you want to delete it anyway?</source>
<translation>Невозможно выполнить транзакцию</translation>
</message>
<message>
- <location line="+33"/>
+ <location line="+42"/>
<source>Could not allocate statement</source>
<translation>Не удалось получить ресурсы для создания выражения</translation>
</message>
@@ -2481,12 +2481,12 @@ Do you want to delete it anyway?</source>
</message>
<message>
<location line="+5"/>
- <location line="+7"/>
+ <location line="+11"/>
<source>Could not describe input statement</source>
<translation>Не удалось описать входящее выражение</translation>
</message>
<message>
- <location line="+10"/>
+ <location line="+14"/>
<source>Could not describe statement</source>
<translation>Не удалось описать выражение</translation>
</message>
@@ -3288,7 +3288,7 @@ Do you want to delete it anyway?</source>
<context>
<name>QOCIDriver</name>
<message>
- <location filename="../src/sql/drivers/oci/qsql_oci.cpp" line="+2079"/>
+ <location filename="../src/sql/drivers/oci/qsql_oci.cpp" line="+2082"/>
<source>Unable to logon</source>
<translation>Невозможно авторизоваться</translation>
</message>
@@ -3317,7 +3317,7 @@ Do you want to delete it anyway?</source>
<context>
<name>QOCIResult</name>
<message>
- <location line="-973"/>
+ <location line="-976"/>
<location line="+161"/>
<location line="+15"/>
<source>Unable to bind column for batch execute</source>
@@ -3329,7 +3329,7 @@ Do you want to delete it anyway?</source>
<translation>Невозможно выполнить пакетное выражение</translation>
</message>
<message>
- <location line="+302"/>
+ <location line="+305"/>
<source>Unable to goto next</source>
<translation>Невозможно перейти к следующей строке</translation>
</message>
@@ -3376,7 +3376,7 @@ Do you want to delete it anyway?</source>
<translation>Невозможно соединиться - Драйвер не поддерживает требуемый функционал</translation>
</message>
<message>
- <location line="+242"/>
+ <location line="+239"/>
<source>Unable to disable autocommit</source>
<translation>Невозможно отключить автовыполнение транзакции</translation>
</message>
@@ -3399,7 +3399,7 @@ Do you want to delete it anyway?</source>
<context>
<name>QODBCResult</name>
<message>
- <location line="-1218"/>
+ <location line="-1216"/>
<location line="+349"/>
<source>QODBCResult::reset: Unable to set &apos;SQL_CURSOR_STATIC&apos; as statement attribute. Please check your ODBC driver configuration</source>
<translation>QODBCResult::reset: Невозможно установить &apos;SQL_CURSOR_STATIC&apos; атрибутом выражение. Проверьте настройки драйвера ODBC</translation>
@@ -3428,12 +3428,12 @@ Do you want to delete it anyway?</source>
<message>
<location filename="../src/sql/drivers/db2/qsql_db2.cpp" line="+194"/>
<location filename="../src/sql/drivers/odbc/qsql_odbc.cpp" line="-475"/>
- <location line="+578"/>
+ <location line="+579"/>
<source>Unable to fetch last</source>
<translation>Невозможно получить последнюю строку</translation>
</message>
<message>
- <location filename="../src/sql/drivers/odbc/qsql_odbc.cpp" line="-672"/>
+ <location filename="../src/sql/drivers/odbc/qsql_odbc.cpp" line="-673"/>
<source>Unable to fetch</source>
<translation>Невозможно получить данные</translation>
</message>
@@ -3520,7 +3520,7 @@ Do you want to delete it anyway?</source>
<translation>Не удалось начать транзакцию</translation>
</message>
<message>
- <location line="+17"/>
+ <location line="+30"/>
<source>Could not commit transaction</source>
<translation>Не удалось выполнить транзакцию</translation>
</message>
@@ -3576,86 +3576,82 @@ Do you want to delete it anyway?</source>
<translation>Точки (pt)</translation>
</message>
<message>
- <location filename="../src/gui/dialogs/qpagesetupwidget.ui" line="+13"/>
+ <location filename="../src/gui/dialogs/qpagesetupwidget.ui"/>
<source>Form</source>
<translation>Форма</translation>
</message>
<message>
- <location line="+29"/>
+ <location/>
<source>Paper</source>
<translation>Бумага</translation>
</message>
<message>
- <location line="+6"/>
+ <location/>
<source>Page size:</source>
<translation>Размер страницы:</translation>
</message>
<message>
- <location line="+13"/>
+ <location/>
<source>Width:</source>
<translation>Ширина:</translation>
</message>
<message>
- <location line="+19"/>
+ <location/>
<source>Height:</source>
<translation>Высота:</translation>
</message>
<message>
- <location line="+19"/>
+ <location/>
<source>Paper source:</source>
<translation>Источник бумаги:</translation>
</message>
<message>
- <location line="+29"/>
+ <location/>
<source>Orientation</source>
<translation>Ориентация страницы</translation>
</message>
<message>
- <location line="+6"/>
+ <location/>
<source>Portrait</source>
<translation>Книжная</translation>
</message>
<message>
- <location line="+10"/>
+ <location/>
<source>Landscape</source>
<translation>Альбомная</translation>
</message>
<message>
- <location line="+7"/>
+ <location/>
<source>Reverse landscape</source>
<translation>Перевёрнутая альбомная</translation>
</message>
<message>
- <location line="+7"/>
+ <location/>
<source>Reverse portrait</source>
<translation>Перевёрнутая книжная</translation>
</message>
<message>
- <location line="+26"/>
+ <location/>
<source>Margins</source>
<translation>Поля</translation>
</message>
<message>
- <location line="+8"/>
- <location line="+3"/>
+ <location/>
<source>top margin</source>
<translation>верхнее поле</translation>
</message>
<message>
- <location line="+28"/>
- <location line="+3"/>
+ <location/>
<source>left margin</source>
<translation>Левое поле</translation>
</message>
<message>
- <location line="+29"/>
- <location line="+3"/>
+ <location/>
<source>right margin</source>
<translation>правое поле</translation>
</message>
<message>
- <location line="+28"/>
- <location line="+3"/>
+ <location/>
<source>bottom margin</source>
<translation>Нижнее поле</translation>
</message>
@@ -4213,17 +4209,17 @@ Please choose a different file name.</source>
<context>
<name>QPrintPropertiesWidget</name>
<message>
- <location filename="../src/gui/dialogs/qprintpropertieswidget.ui" line="+13"/>
+ <location filename="../src/gui/dialogs/qprintpropertieswidget.ui"/>
<source>Form</source>
<translation>Форма</translation>
</message>
<message>
- <location line="+21"/>
+ <location/>
<source>Page</source>
<translation>Страница</translation>
</message>
<message>
- <location line="+10"/>
+ <location/>
<source>Advanced</source>
<translation>Дополнительно</translation>
</message>
@@ -4231,97 +4227,97 @@ Please choose a different file name.</source>
<context>
<name>QPrintSettingsOutput</name>
<message>
- <location filename="../src/gui/dialogs/qprintsettingsoutput.ui" line="+13"/>
+ <location filename="../src/gui/dialogs/qprintsettingsoutput.ui"/>
<source>Form</source>
<translation>Форма</translation>
</message>
<message>
- <location line="+21"/>
+ <location/>
<source>Copies</source>
<translation>Копии</translation>
</message>
<message>
- <location line="+12"/>
+ <location/>
<source>Print range</source>
<translation>Печатать диапазон</translation>
</message>
<message>
- <location line="+12"/>
+ <location/>
<source>Print all</source>
<translation>Печатать все</translation>
</message>
<message>
- <location line="+18"/>
+ <location/>
<source>Pages from</source>
<translation>Страницы от</translation>
</message>
<message>
- <location line="+20"/>
+ <location/>
<source>to</source>
<translation>до</translation>
</message>
<message>
- <location line="+35"/>
+ <location/>
<source>Selection</source>
<translation>Выделенные</translation>
</message>
<message>
- <location line="+23"/>
+ <location/>
<source>Output Settings</source>
<translation>Настройки вывода</translation>
</message>
<message>
- <location line="+6"/>
+ <location/>
<source>Copies:</source>
<translation>Количество копий:</translation>
</message>
<message>
- <location line="+33"/>
+ <location/>
<source>Collate</source>
<translation>Разобрать про копиям</translation>
</message>
<message>
- <location line="+17"/>
+ <location/>
<source>Reverse</source>
<translation>Обратный порядок</translation>
</message>
<message>
- <location line="+32"/>
+ <location/>
<source>Options</source>
<translation>Параметры</translation>
</message>
<message>
- <location line="+6"/>
+ <location/>
<source>Color Mode</source>
<translation>Режим цвета</translation>
</message>
<message>
- <location line="+19"/>
+ <location/>
<source>Color</source>
<translation>Цвет</translation>
</message>
<message>
- <location line="+10"/>
+ <location/>
<source>Grayscale</source>
<translation>Оттенки серого</translation>
</message>
<message>
- <location line="+10"/>
+ <location/>
<source>Duplex Printing</source>
<translation>Двусторонняя печать</translation>
</message>
<message>
- <location line="+6"/>
+ <location/>
<source>None</source>
<translation>Нет</translation>
</message>
<message>
- <location line="+10"/>
+ <location/>
<source>Long side</source>
<translation>По длинной стороне</translation>
</message>
<message>
- <location line="+7"/>
+ <location/>
<source>Short side</source>
<translation>По короткой стороне</translation>
</message>
@@ -4329,47 +4325,47 @@ Please choose a different file name.</source>
<context>
<name>QPrintWidget</name>
<message>
- <location filename="../src/gui/dialogs/qprintwidget.ui" line="+13"/>
+ <location filename="../src/gui/dialogs/qprintwidget.ui"/>
<source>Form</source>
<translation>Форма</translation>
</message>
<message>
- <location line="+9"/>
+ <location/>
<source>Printer</source>
<translation>Принтер</translation>
</message>
<message>
- <location line="+6"/>
+ <location/>
<source>&amp;Name:</source>
<translation>&amp;Имя:</translation>
</message>
<message>
- <location line="+26"/>
+ <location/>
<source>P&amp;roperties</source>
<translation>С&amp;войства</translation>
</message>
<message>
- <location line="+7"/>
+ <location/>
<source>Location:</source>
<translation>Положение:</translation>
</message>
<message>
- <location line="+10"/>
+ <location/>
<source>Preview</source>
<translation>Предпросмотр</translation>
</message>
<message>
- <location line="+7"/>
+ <location/>
<source>Type:</source>
<translation>Тип:</translation>
</message>
<message>
- <location line="+10"/>
+ <location/>
<source>Output &amp;file:</source>
<translation>Выходной &amp;файл:</translation>
</message>
<message>
- <location line="+15"/>
+ <location/>
<source>...</source>
<translation>...</translation>
</message>
@@ -6329,7 +6325,7 @@ Please choose a different file name.</source>
<context>
<name>QWizard</name>
<message>
- <location filename="../src/gui/dialogs/qwizard.cpp" line="+637"/>
+ <location filename="../src/gui/dialogs/qwizard.cpp" line="+638"/>
<source>Go Back</source>
<translation>Назад</translation>
</message>
diff --git a/translations/qtconfig_ru.ts b/translations/qtconfig_ru.ts
new file mode 100644
index 0000000..b1965f2
--- /dev/null
+++ b/translations/qtconfig_ru.ts
@@ -0,0 +1,906 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="ru">
+<context>
+ <name>MainWindow</name>
+ <message>
+ <location filename="../tools/qtconfig/mainwindow.cpp" line="+202"/>
+ <source>Desktop Settings (Default)</source>
+ <translation>Настройки рабочего стола (по умолчанию)</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Choose style and palette based on your desktop settings.</source>
+ <translation>Выбор стиля и палитры на основе настроек рабочего стола.</translation>
+ </message>
+ <message>
+ <location line="+144"/>
+ <source>On The Spot</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+33"/>
+ <location line="+1"/>
+ <location line="+38"/>
+ <location line="+1"/>
+ <source>Auto (default)</source>
+ <translation>Автоматически (по умолчанию)</translation>
+ </message>
+ <message>
+ <location line="-38"/>
+ <source>Choose audio output automatically.</source>
+ <translation>Автоматический выбор звукового выхода.</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <location line="+1"/>
+ <source>aRts</source>
+ <translation>aRts</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Experimental aRts support for GStreamer.</source>
+ <translation>Экспериментальная поддержка aRts в GStreamer.</translation>
+ </message>
+ <message>
+ <location line="+31"/>
+ <source>Phonon GStreamer backend not available.</source>
+ <translation type="unfinished">Модуль Phonon поддержки GStreamer не доступен.</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Choose render method automatically</source>
+ <translation>Автоматический выбор метода отрисовки</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <location line="+1"/>
+ <source>X11</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Use X11 Overlays</source>
+ <translation type="unfinished">Использовать оверлеи X11</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <location line="+1"/>
+ <source>OpenGL</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Use OpenGL if avaiable</source>
+ <translation>Использовать OpenGL, если доступен</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <location line="+1"/>
+ <source>Software</source>
+ <translation>Программный</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>Use simple software rendering</source>
+ <translation>Использовать простую программную отрисовку</translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>No changes to be saved.</source>
+ <translation>Нет изменений для сохранения.</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Saving changes...</source>
+ <translation>Сохранение изменений...</translation>
+ </message>
+ <message>
+ <location line="+48"/>
+ <source>Over The Spot</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Off The Spot</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Root</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+466"/>
+ <source>Select a Directory</source>
+ <translation>Выбор каталога</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>&lt;h3&gt;%1&lt;/h3&gt;&lt;br/&gt;Version %2&lt;br/&gt;&lt;br/&gt;Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).&lt;br/&gt;&lt;br/&gt;The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.&lt;br/&gt; </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <location line="+1"/>
+ <location line="+8"/>
+ <source>Qt Configuration</source>
+ <translation>Конфигурация Qt</translation>
+ </message>
+ <message>
+ <location line="+22"/>
+ <source>Save Changes</source>
+ <translation>Сохранение изменений</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Save changes to settings?</source>
+ <translation>Сохранить изменения настроек?</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>&amp;Yes</source>
+ <translation>&amp;Да</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>&amp;No</source>
+ <translation>&amp;Нет</translation>
+ </message>
+ <message>
+ <location line="+0"/>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Отмена</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindowBase</name>
+ <message>
+ <location filename="../tools/qtconfig/mainwindowbase.ui" line="+54"/>
+ <source>Qt Configuration</source>
+ <translation>Конфигурация Qt</translation>
+ </message>
+ <message>
+ <location line="+35"/>
+ <source>Appearance</source>
+ <translation>Внешний вид</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>GUI Style</source>
+ <translation>Стиль пользовательского графического интерфейса</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Select GUI &amp;Style:</source>
+ <translation type="unfinished">&amp;Стиль интерфейса:</translation>
+ </message>
+ <message>
+ <location line="+88"/>
+ <source>Build Palette</source>
+ <translation type="unfinished">Палитра</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>&amp;3-D Effects:</source>
+ <translation>Эффекты &amp;3-D:</translation>
+ </message>
+ <message>
+ <location line="+31"/>
+ <source>Window Back&amp;ground:</source>
+ <translation>&amp;Фон окна:</translation>
+ </message>
+ <message>
+ <location line="+35"/>
+ <source>&amp;Tune Palette...</source>
+ <translation>&amp;Настроить палитру...</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Please use the KDE Control Center to set the palette.</source>
+ <translation>Используйте Центр управления KDE для настройки цветов.</translation>
+ </message>
+ <message>
+ <location line="-154"/>
+ <source>Preview</source>
+ <translation>Предпросмотр</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Select &amp;Palette:</source>
+ <translation>Выбор &amp;палитры:</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>Active Palette</source>
+ <translation>Палитра активных элементов</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Inactive Palette</source>
+ <translation>Палитра неактивных элементов</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Disabled Palette</source>
+ <translation>Палитра выключенных элементов</translation>
+ </message>
+ <message>
+ <location line="+138"/>
+ <source>Fonts</source>
+ <translation>Шрифты</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Default Font</source>
+ <translation>Шрифт по умолчанию</translation>
+ </message>
+ <message>
+ <location line="+45"/>
+ <source>&amp;Style:</source>
+ <translation>&amp;Стиль:</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>&amp;Point Size:</source>
+ <translation>&amp;Размер в точках:</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>F&amp;amily:</source>
+ <translation>Семе&amp;йство:</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Sample Text</source>
+ <translation>Текст для примера (Sample Text)</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Font Substitution</source>
+ <translation>Подстановка шрифтов</translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <source>S&amp;elect or Enter a Family:</source>
+ <translation>&amp;Выберите или введите семейство:</translation>
+ </message>
+ <message>
+ <location line="+38"/>
+ <source>Current Substitutions:</source>
+ <translation type="unfinished">Текущие замены:</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <location line="+501"/>
+ <source>Up</source>
+ <translation>Выше</translation>
+ </message>
+ <message>
+ <location line="-494"/>
+ <location line="+508"/>
+ <source>Down</source>
+ <translation>Ниже</translation>
+ </message>
+ <message>
+ <location line="-501"/>
+ <location line="+494"/>
+ <source>Remove</source>
+ <translation>Удалить</translation>
+ </message>
+ <message>
+ <location line="-464"/>
+ <source>Select s&amp;ubstitute Family:</source>
+ <translation>Выберите п&amp;одставляемое семейство:</translation>
+ </message>
+ <message>
+ <location line="+20"/>
+ <location line="+487"/>
+ <source>Add</source>
+ <translation>Добавить</translation>
+ </message>
+ <message>
+ <location line="-474"/>
+ <source>Interface</source>
+ <translation>Интерфейс</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Feel Settings</source>
+ <translation type="unfinished">Настройка указателя</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <location line="+26"/>
+ <source> ms</source>
+ <translation> мс</translation>
+ </message>
+ <message>
+ <location line="-13"/>
+ <source>&amp;Double Click Interval:</source>
+ <translation>&amp;Интервал двойного щелчка:</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>No blinking</source>
+ <translation>Без мигания</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>&amp;Cursor Flash Time:</source>
+ <translation>&amp;Период мигания курсора:</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source> lines</source>
+ <translation> строк</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Wheel &amp;Scroll Lines:</source>
+ <translation type="unfinished">&amp;Прокручивать строк при повороте колёсика:</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Resolve symlinks in URLs</source>
+ <translation>Разрешать символьные ссылки в URL-ах</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>GUI Effects</source>
+ <translation type="unfinished">Эффекты пользовательского интерфейса</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>&amp;Enable</source>
+ <translation>&amp;Включить</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Alt+E</source>
+ <translation>Alt+D</translation>
+ </message>
+ <message>
+ <location line="+22"/>
+ <source>&amp;Menu Effect:</source>
+ <translation>Эффект &amp;меню:</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>C&amp;omboBox Effect:</source>
+ <translation type="unfinished">Эффект C&amp;omboBox:</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>&amp;ToolTip Effect:</source>
+ <translation type="unfinished">Эффект &amp;ToolTip:</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Tool&amp;Box Effect:</source>
+ <translation type="unfinished">Эффект Tool&amp;Box:</translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <location line="+19"/>
+ <location line="+14"/>
+ <location line="+19"/>
+ <source>Disable</source>
+ <translation>Выключен</translation>
+ </message>
+ <message>
+ <location line="-47"/>
+ <location line="+19"/>
+ <location line="+14"/>
+ <location line="+19"/>
+ <source>Animate</source>
+ <translation>Анимация</translation>
+ </message>
+ <message>
+ <location line="-47"/>
+ <location line="+33"/>
+ <source>Fade</source>
+ <translation>Затухание</translation>
+ </message>
+ <message>
+ <location line="+28"/>
+ <source>Global Strut</source>
+ <translation type="unfinished">Специальные возможности</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>Minimum &amp;Width:</source>
+ <translation>Минимальная &amp;ширина:</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Minimum Hei&amp;ght:</source>
+ <translation>Минимальная в&amp;ысота:</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <location line="+10"/>
+ <source> pixels</source>
+ <translation> пикселей</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Enhanced support for languages written right-to-left</source>
+ <translation>Расширенная поддержка письма справа налево</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>XIM Input Style:</source>
+ <translation>Стиль ввода XIM:</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>On The Spot</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Over The Spot</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Off The Spot</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Root</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>Default Input Method:</source>
+ <translation>Метод ввода по умолчанию:</translation>
+ </message>
+ <message>
+ <location line="+31"/>
+ <source>Printer</source>
+ <translation>Принтер</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Enable Font embedding</source>
+ <translation>Разрешить встраивание шрифтов</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Font Paths</source>
+ <translation>Пути к шрифтам</translation>
+ </message>
+ <message>
+ <location line="+77"/>
+ <source>Browse...</source>
+ <translation>Обзор...</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Press the &lt;b&gt;Browse&lt;/b&gt; button or enter a directory and press Enter to add them to the list.</source>
+ <translation>Нажмите кнопку &lt;b&gt;Обзор...&lt;/b&gt; или укажите каталог и нажмите Ввод для добавления его в список.</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Phonon</source>
+ <translation>Phonon</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>About Phonon</source>
+ <translation>О Phonon</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <location line="+44"/>
+ <source>Current Version:</source>
+ <translation>Текущая версия:</translation>
+ </message>
+ <message>
+ <location line="-37"/>
+ <location line="+44"/>
+ <source>Not available</source>
+ <translation>Недоступно</translation>
+ </message>
+ <message>
+ <location line="-37"/>
+ <location line="+44"/>
+ <source>Website:</source>
+ <translation>Вэб-сайт:</translation>
+ </message>
+ <message>
+ <location line="-37"/>
+ <source>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;http://phonon.kde.org&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://phonon.kde.org&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>About GStreamer</source>
+ <translation>О GStreamer</translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;http://gstreamer.freedesktop.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://gstreamer.freedesktop.org/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+17"/>
+ <source>GStreamer backend settings</source>
+ <translation>Настройки модуля GStreamer</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Preferred audio sink:</source>
+ <translation>Предпочитаемое звуковое устройство:</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Preferred render method:</source>
+ <translation>Предпочитаемый метод отрисовки:</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Note: changes to these settings may prevent applications from starting up correctly.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Sans Serif&apos;; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;Внимание: Изменение данных настроек может повлечь невозможность корректного запуска приложений.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location line="+68"/>
+ <source>&amp;File</source>
+ <translation>&amp;Файл</translation>
+ </message>
+ <message>
+ <location line="+19"/>
+ <source>&amp;Help</source>
+ <translation>&amp;Справка</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>&amp;Save</source>
+ <translation>&amp;Сохранить</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Save</source>
+ <translation>Сохранить</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Ctrl+S</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>E&amp;xit</source>
+ <translation>В&amp;ыход</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Exit</source>
+ <translation>Выход</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>&amp;About</source>
+ <translation>&amp;О программе</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>About</source>
+ <translation>О программе</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <source>About &amp;Qt</source>
+ <translation>О &amp;Qt</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>About Qt</source>
+ <translation>О Qt</translation>
+ </message>
+</context>
+<context>
+ <name>PaletteEditorAdvancedBase</name>
+ <message>
+ <location filename="../tools/qtconfig/paletteeditoradvancedbase.ui" line="+61"/>
+ <source>Tune Palette</source>
+ <translation>Настройка палитры</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>&lt;b&gt;Edit Palette&lt;/b&gt;&lt;p&gt;Change the palette of the current widget or form.&lt;/p&gt;&lt;p&gt;Use a generated palette or select colors for each color group and each color role.&lt;/p&gt;&lt;p&gt;The palette can be tested with different widget layouts in the preview section.&lt;/p&gt;</source>
+ <translation type="unfinished">&lt;b&gt;Изменение палитры&lt;/b&gt;&lt;p&gt;Изменение палитры текущего виджета или формы.&lt;/p&gt;&lt;p&gt;Используйте сформированную палитру или выберите цвета для каждой группы цветов и каждой их роли.&lt;/p&gt;&lt;p&gt;Палитру можно проверить на виджетах в разных режимах отображения в разделе предпросмотра.&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Select &amp;Palette:</source>
+ <translation>Выбор &amp;палитры:</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Active Palette</source>
+ <translation>Палитра активных элементов</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Inactive Palette</source>
+ <translation>Палитра неактивных элементов</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Disabled Palette</source>
+ <translation>Палитра выключенных элементов</translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>Auto</source>
+ <translation type="unfinished">Автоматически</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Build inactive palette from active</source>
+ <translation type="unfinished">Создать неактивную палитру из активной</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>Build disabled palette from active</source>
+ <translation type="unfinished">Создать выключенную палитру из активной</translation>
+ </message>
+ <message>
+ <location line="+16"/>
+ <source>Central color &amp;roles</source>
+ <translation type="unfinished">Роли &amp;цветов</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Choose central color role</source>
+ <translation type="unfinished">Выберите роль цвета</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>&lt;b&gt;Select a color role.&lt;/b&gt;&lt;p&gt;Available central roles are: &lt;ul&gt; &lt;li&gt;Window - general background color.&lt;/li&gt; &lt;li&gt;WindowText - general foreground color. &lt;/li&gt; &lt;li&gt;Base - used as background color for e.g. text entry widgets, usually white or another light color. &lt;/li&gt; &lt;li&gt;Text - the foreground color used with Base. Usually this is the same as WindowText, in what case it must provide good contrast both with Window and Base. &lt;/li&gt; &lt;li&gt;Button - general button background color, where buttons need a background different from Window, as in the Macintosh style. &lt;/li&gt; &lt;li&gt;ButtonText - a foreground color used with the Button color. &lt;/li&gt; &lt;li&gt;Highlight - a color to indicate a selected or highlighted item. &lt;/li&gt; &lt;li&gt;HighlightedText - a text color that contrasts to Highlight. &lt;/li&gt; &lt;li&gt;BrightText - a text color that is very different from WindowText and contrasts well with e.g. black. &lt;/li&gt; &lt;/ul&gt; &lt;/p&gt;</source>
+ <translation type="unfinished">&lt;b&gt;Выбор роли цвета.&lt;/b&gt;&lt;p&gt;Доступны следующие роли: &lt;ul&gt;&lt;li&gt;Window - основной цвет фона.&lt;/li&gt; &lt;li&gt;WindowText - основной цвет текста.&lt;/li&gt; &lt;li&gt;Base - используется в качестве фона для, например, виджетов с текстовыми полями, обычно, белый или другой светлый цвет.&lt;/li&gt; &lt;li&gt;Text - цвет текста используемый совместно с Base. Обычно, он совпадает с WindowText, так как в этом случае получается максимальный контраст и с Window, и с Base.&lt;/li&gt; &lt;li&gt;Button - основной цвет фона кнопки, которой требуется цвет отличный от Window, например, в стиле Macintosh.&lt;/li&gt; &lt;li&gt;ButtonText - цвет текста используемый совместно с Button.&lt;/li&gt; &lt;li&gt;Highlight - цвет для обозначения выбранного или выделенного элемента.&lt;/li&gt; &lt;li&gt;HighlightedText - цвет текста контрастирующий с Highlight.&lt;/li&gt; &lt;li&gt;BrightText - цвет текста, который отличается от WindowText и хорошо контрастирует с черным.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Window</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>WindowText</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Button</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Base</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>BrightText</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>ButtonText</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Highlight</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>HighlightedText</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+52"/>
+ <source>&amp;Select Color:</source>
+ <translation>&amp;Выбор цвета:</translation>
+ </message>
+ <message>
+ <location line="+24"/>
+ <location line="+171"/>
+ <source>Choose a color</source>
+ <translation>Выберите цвет</translation>
+ </message>
+ <message>
+ <location line="-168"/>
+ <source>Choose a color for the selected central color role.</source>
+ <translation>Выберите цвет для указанной роли.</translation>
+ </message>
+ <message>
+ <location line="+15"/>
+ <source>3-D shadow &amp;effects</source>
+ <translation>Эффекты т&amp;рехмерной тени</translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Build &amp;from button color</source>
+ <translation>Получ&amp;ить из цвета кнопки</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Generate shadings</source>
+ <translation type="unfinished">Создание полутонов</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>Check to let 3D-effect colors be calculated from button-color.</source>
+ <translation type="unfinished">Включите, чтобы цвета эффекта трёхмерности были получены из цвета кнопки.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Choose 3D-effect color role</source>
+ <translation type="unfinished">Выбор роли цвета дял эффекта трёхмерности</translation>
+ </message>
+ <message>
+ <location line="+3"/>
+ <source>&lt;b&gt;Select a color role.&lt;/b&gt;&lt;p&gt;Available effect roles are: &lt;ul&gt; &lt;li&gt;Light - lighter than Button color. &lt;/li&gt; &lt;li&gt;Midlight - between Button and Light. &lt;/li&gt; &lt;li&gt;Mid - between Button and Dark. &lt;/li&gt; &lt;li&gt;Dark - darker than Button. &lt;/li&gt; &lt;li&gt;Shadow - a very dark color. &lt;/li&gt; &lt;/ul&gt;</source>
+ <translation>&lt;b&gt;Выбор роли цвета.&lt;/b&gt;&lt;p&gt;Доступны следующие роли: &lt;ul&gt; &lt;li&gt;Light - светлее цвета Button. &lt;/li&gt; &lt;li&gt;Midlight - среднее между Light и Button. &lt;/li&gt; &lt;li&gt;Mid - среднее между Button и Dark. &lt;/li&gt; &lt;li&gt;Dark - темнее цвета Button. &lt;/li&gt; &lt;li&gt;Shadow - очень темный цвет. &lt;/li&gt; &lt;/ul&gt;</translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <source>Light</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Midlight</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Mid</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Dark</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>Shadow</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+54"/>
+ <source>Select Co&amp;lor:</source>
+ <translation>Выбор &amp;цвета:</translation>
+ </message>
+ <message>
+ <location line="+27"/>
+ <source>Choose a color for the selected effect color role.</source>
+ <translation type="unfinished">Выбор цвета для указанной роли.</translation>
+ </message>
+ <message>
+ <location line="+42"/>
+ <source>OK</source>
+ <translation>Принять</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Close dialog and apply all changes.</source>
+ <translation>Закрыть окно с применением изменений.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Cancel</source>
+ <translation>Отмена</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Close dialog and discard all changes.</source>
+ <translation>Закрыть окно с отменой изменений.</translation>
+ </message>
+</context>
+<context>
+ <name>PreviewFrame</name>
+ <message>
+ <location filename="../tools/qtconfig/previewframe.cpp" line="+81"/>
+ <source>Desktop settings will only take effect after an application restart.</source>
+ <translation type="unfinished">Настройки рабочего стола применятся после перезапуска приложения.</translation>
+ </message>
+</context>
+<context>
+ <name>PreviewWidgetBase</name>
+ <message>
+ <location filename="../tools/qtconfig/previewwidgetbase.ui" line="+66"/>
+ <source>Preview Window</source>
+ <translation>Окно предпросмотра</translation>
+ </message>
+ <message>
+ <location line="+40"/>
+ <source>ButtonGroup</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>RadioButton1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>RadioButton2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>RadioButton3</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>ButtonGroup2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>CheckBox1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>CheckBox2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+36"/>
+ <source>LineEdit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>ComboBox</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>PushButton</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+41"/>
+ <source>&lt;p&gt;
+&lt;a href=&quot;http://qtsoftware.com&quot;&gt;http://qtsoftware.com&lt;/a&gt;
+&lt;/p&gt;
+&lt;p&gt;
+&lt;a href=&quot;http://www.kde.org&quot;&gt;http://www.kde.org&lt;/a&gt;
+&lt;/p&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/translations/qvfb_ru.ts b/translations/qvfb_ru.ts
new file mode 100644
index 0000000..b084380
--- /dev/null
+++ b/translations/qvfb_ru.ts
@@ -0,0 +1,328 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="ru">
+<context>
+ <name>AnimationSaveWidget</name>
+ <message>
+ <location filename="../tools/qvfb/qvfb.cpp" line="+850"/>
+ <location line="+204"/>
+ <source>Record</source>
+ <translation>Записать</translation>
+ </message>
+ <message>
+ <location line="-202"/>
+ <source>Reset</source>
+ <translation>Сбросить</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Save</source>
+ <translation>Сохранить</translation>
+ </message>
+ <message>
+ <location line="+18"/>
+ <source>Save in MPEG format (requires netpbm package installed)</source>
+ <translation>Сохранить в формат MPEG (требуется установленный пакет netpbm)</translation>
+ </message>
+ <message>
+ <location line="+8"/>
+ <location line="+206"/>
+ <source>Click record to begin recording.</source>
+ <translation>Нажмите &quot;Записать&quot; для начала записи.</translation>
+ </message>
+ <message>
+ <location line="-115"/>
+ <location line="+147"/>
+ <source>Finished saving.</source>
+ <translation>Сохранение завершено.</translation>
+ </message>
+ <message>
+ <location line="-63"/>
+ <source>Paused. Click record to resume, or save if done.</source>
+ <translation>Приостановлено. Нажмите &quot;Записать&quot; для продолжения или &quot;Сохранить&quot;, если готово.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>Pause</source>
+ <translation>Пауза</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>Recording...</source>
+ <translation>Идёт запись...</translation>
+ </message>
+ <message>
+ <location line="+40"/>
+ <source>Saving... </source>
+ <translation>Сохранение... </translation>
+ </message>
+ <message>
+ <location line="+4"/>
+ <location line="+4"/>
+ <source>Save animation...</source>
+ <translation>Сохранение анимации...</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Save canceled.</source>
+ <translation>Сохранение отменено.</translation>
+ </message>
+ <message>
+ <location line="+9"/>
+ <source>Save failed!</source>
+ <translation>Сохранение не удалось!</translation>
+ </message>
+</context>
+<context>
+ <name>Config</name>
+ <message>
+ <location filename="../tools/qvfb/config.ui" line="+53"/>
+ <source>Configure</source>
+ <translation>Настройка</translation>
+ </message>
+ <message>
+ <location line="+47"/>
+ <source>Size</source>
+ <translation>Размер</translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>176x220 &quot;SmartPhone&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>240x320 &quot;PDA&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>320x240 &quot;TV&quot; / &quot;QVGA&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>640x480 &quot;VGA&quot;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>800x600</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>1024x768</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+30"/>
+ <source>Custom</source>
+ <translation>Особый</translation>
+ </message>
+ <message>
+ <location line="+44"/>
+ <source>Depth</source>
+ <translation>Глубина</translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>1 bit monochrome</source>
+ <translation>1 бит (монохромный)</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>4 bit grayscale</source>
+ <translation>4 бита (градации серого)</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>8 bit</source>
+ <translation>8 бит</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>12 (16) bit</source>
+ <translation>12 (16) бит</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>15 bit</source>
+ <translation>15 бит</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>16 bit</source>
+ <translation>16 бит</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>18 bit</source>
+ <translation>18 бит</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>24 bit</source>
+ <translation>24 бита</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>32 bit</source>
+ <translation>32 бита</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>32 bit ARGB</source>
+ <translation>32 бита (ARGB)</translation>
+ </message>
+ <message>
+ <location line="+29"/>
+ <source>Skin</source>
+ <translation>Обложка</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>None</source>
+ <translation>Нет</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Emulate touch screen (no mouse move)</source>
+ <translation>Эмулировать тачскрин (без перемещения мыши)</translation>
+ </message>
+ <message>
+ <location line="+7"/>
+ <source>Emulate LCD screen (Only with fixed zoom of 3.0 times magnification)</source>
+ <translation>Эмулировать ж/к экран (только с 3-х кратным увеличением)</translation>
+ </message>
+ <message>
+ <location line="+26"/>
+ <source>&lt;p&gt;Note that any applications using the virtual framebuffer will be terminated if you change the Size or Depth &lt;i&gt;above&lt;/i&gt;. You may freely modify the Gamma &lt;i&gt;below&lt;/i&gt;.</source>
+ <translation>&lt;p&gt;Имейте в виду, что любая программа будет завершена, если изменится размер или глубина экрана. Параметр Гамма можно менять свободно.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>Gamma</source>
+ <translation>Гамма</translation>
+ </message>
+ <message>
+ <location line="+24"/>
+ <source>Blue</source>
+ <translation>Синий</translation>
+ </message>
+ <message>
+ <location line="+489"/>
+ <location line="+496"/>
+ <location line="+14"/>
+ <location line="+496"/>
+ <source>1.0</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-999"/>
+ <source>Green</source>
+ <translation>Зеленый</translation>
+ </message>
+ <message>
+ <location line="+496"/>
+ <source>All</source>
+ <translation>Все</translation>
+ </message>
+ <message>
+ <location line="+496"/>
+ <source>Red</source>
+ <translation>Красный</translation>
+ </message>
+ <message>
+ <location line="+496"/>
+ <source>Set all to 1.0</source>
+ <translation>Выставить все в 1.0</translation>
+ </message>
+ <message>
+ <location line="+43"/>
+ <source>&amp;OK</source>
+ <translation>&amp;Готово</translation>
+ </message>
+ <message>
+ <location line="+13"/>
+ <source>&amp;Cancel</source>
+ <translation>&amp;Отмена</translation>
+ </message>
+</context>
+<context>
+ <name>DeviceSkin</name>
+ <message>
+ <location filename="../tools/shared/deviceskin/deviceskin.cpp" line="+79"/>
+ <source>The image file &apos;%1&apos; could not be loaded.</source>
+ <translation>Не удалось загрузить изображение &apos;%1&apos;.</translation>
+ </message>
+ <message>
+ <location line="+64"/>
+ <source>The skin directory &apos;%1&apos; does not contain a configuration file.</source>
+ <translation>Каталог обложки &apos;%1&apos; не содержит файла настроек.</translation>
+ </message>
+ <message>
+ <location line="+5"/>
+ <source>The skin configuration file &apos;%1&apos; could not be opened.</source>
+ <translation>Не удалось открыть файл настроек обложки &apos;%1&apos;.</translation>
+ </message>
+ <message>
+ <location line="+6"/>
+ <source>The skin configuration file &apos;%1&apos; could not be read: %2</source>
+ <translation>Не удалось прочитать файл настроек обложки &apos;%1&apos;: %2</translation>
+ </message>
+ <message>
+ <location line="+70"/>
+ <source>Syntax error: %1</source>
+ <translation>Синтаксическая ошибка: %1</translation>
+ </message>
+ <message>
+ <location line="+21"/>
+ <source>The skin &quot;up&quot; image file &apos;%1&apos; does not exist.</source>
+ <translation>Файл изображения &quot;up&quot; &apos;%1&apos; не существует.</translation>
+ </message>
+ <message>
+ <location line="+10"/>
+ <source>The skin &quot;down&quot; image file &apos;%1&apos; does not exist.</source>
+ <translation>Файл изображения &quot;down&quot; &apos;%1&apos; не существует.</translation>
+ </message>
+ <message>
+ <location line="+11"/>
+ <source>The skin &quot;closed&quot; image file &apos;%1&apos; does not exist.</source>
+ <translation>Файл изображения &quot;closed&quot; &apos;%1&apos; не существует.</translation>
+ </message>
+ <message>
+ <location line="+12"/>
+ <source>The skin cursor image file &apos;%1&apos; does not exist.</source>
+ <translation>Файл изображения курсора &apos;%1&apos; не существует.</translation>
+ </message>
+ <message>
+ <location line="+25"/>
+ <source>Syntax error in area definition: %1</source>
+ <translation>Синтаксическая ошибка в определении области: %1</translation>
+ </message>
+ <message>
+ <location line="+38"/>
+ <source>Mismatch in number of areas, expected %1, got %2.</source>
+ <translation>Несовпадение количества зон: ожидается %1, указано %2.</translation>
+ </message>
+</context>
+<context>
+ <name>QVFb</name>
+ <message>
+ <location filename="../tools/qvfb/qvfb.cpp" line="-487"/>
+ <source>Browse...</source>
+ <translation>Обзор...</translation>
+ </message>
+ <message>
+ <location line="+126"/>
+ <source>Load Custom Skin...</source>
+ <translation>Загрузить обложку пользователя...</translation>
+ </message>
+ <message>
+ <location line="+1"/>
+ <source>All QVFB Skins (*.skin)</source>
+ <translation>Все обложки QVFB (*.skin)</translation>
+ </message>
+</context>
+</TS>