diff options
156 files changed, 4196 insertions, 1001 deletions
diff --git a/config.profiles/symbian/bld.inf b/config.profiles/symbian/bld.inf index 6ccb11c..21b3614 100644 --- a/config.profiles/symbian/bld.inf +++ b/config.profiles/symbian/bld.inf @@ -19,6 +19,7 @@ qtconfig.flm /epoc32/tools/makefile_templates/qt/qtconfig.flm ../../mkspecs/symbian-sbsv2/flm/qt/qmake_extra_pre_targetdep.flm /epoc32/tools/makefile_templates/qt/ ../../mkspecs/symbian-sbsv2/flm/qt/qmake_post_link.flm /epoc32/tools/makefile_templates/qt/ ../../mkspecs/symbian-sbsv2/flm/qt/qmake_store_build.flm /epoc32/tools/makefile_templates/qt/ +../../mkspecs/symbian-sbsv2/flm/qt/qmake_clean.flm /epoc32/tools/makefile_templates/qt/ ../../mkspecs/symbian-sbsv2/flm/qt/qt.xml /epoc32/tools/makefile_templates/qt/ qt.conf /epoc32/tools/qt.conf diff --git a/config.profiles/symbian/qtconfig.flm b/config.profiles/symbian/qtconfig.flm index 56c3d6b..94f732a 100644 --- a/config.profiles/symbian/qtconfig.flm +++ b/config.profiles/symbian/qtconfig.flm @@ -66,9 +66,10 @@ $(SOURCEDIR)/qmake$(DOTEXE): $(EXTENSION_ROOT)/$(QT_ROOT)/$(CONFIGURE_APP) $(GNUCP) -R $(EXTENSION_ROOT)/$(QT_ROOT)/mkspecs $(MKSPECDIR) $(call endrule,mkspecexport) -WHAT:: +FINAL WHAT:: $(SOURCEDIR)/qmake$(DOTEXE) $(call startrawoutput) \ echo "$(call whatLogOpen)"; \ + cd $(EXTENSION_ROOT)/$(QT_ROOT)/config.profiles/symbian && \ perl headerexport -base-dir $(EXTENSION_ROOT)/$(QT_ROOT) -outdir $(EPOCROOT)/epoc32/include/ -what | \ (read -r LINE; \ while [ $$$$? -eq 0 ]; do \ @@ -76,7 +77,14 @@ WHAT:: read -r LINE; \ done; \ ); \ - echo "$(call whatLogClose)" \ + $(GNUFIND) $(EXTENSION_ROOT)/$(QT_ROOT)/mkspecs -type f | \ + (read -r LINE; \ + while [ $$$$? -eq 0 ]; do \ + echo "$(call whatLogItem,,$$$$LINE)" | $(GNUSED) 's#$(EXTENSION_ROOT)/$(QT_ROOT)#$(MKSPECDIR)#'; \ + read -r LINE; \ + done; \ + ); \ + echo "$(call whatLogClose)"; \ $(call endrawoutput) endef diff --git a/dist/changes-4.8.0 b/dist/changes-4.8.0 index b8e3842..27c6774 100644 --- a/dist/changes-4.8.0 +++ b/dist/changes-4.8.0 @@ -19,10 +19,16 @@ information about a particular change. * General * **************************************************************************** +Qt Platform Abstraction +----------------------- + +Qt 4.8 adds a new platform: QPA (also known as Lighthouse). QPA is a replacement +for Qt for Embedded Linux (QWS), making it much easier to port Qt to new platforms. + General Improvements -------------------- -- +- Third party components ---------------------- @@ -58,10 +64,13 @@ QtCore - QUrl: add method for retrieving effective top level domain [QTBUG-13601] (MR-1205) - optimised performance of QFileInfo, QDir, QDirIterator, these classes now share metadata and access the filesystem less - QFile: new open() overloads allow control over whether QFile should close an adopted file handle or not + - Fix QProcess emitting two started signals on X11 [QTBUG-7039] + - QLocale: added locale dependent to{Upper,Lower} string conversions QtGui ----- + - QApplication: Add a queryKeyboardModifiers() method. - QTabBar: reduced minimumSizeHint if ElideMode is set. - QComboBox: Fixed a color propagation issue with the lineedit. [QTBUG-5950] - QGraphicsLayout: Made setInstantInvalidatePropagation() public @@ -77,6 +86,11 @@ QtGui like UltraLight. [QTBUG-19366] - Visual text cursor movement behavior is added to QTextEdit and QLineEdit controls, which can be used as an optional mode for bi-directional text editing. [QTBUG-13859] + - Fixed several bidi reordering bugs. + - Make HTML exported from QTextDocument containing empty lines more compliant. + - Include font pixel size when exporting HTML from QTextDocument. + - QPainter: Added a fast stroking algorithm for thin (< 1px wide) aliased and antialiased + lines, giving a huge improvement in drawing speed for certain cases - Fixed a rare race condition when showing toplevel windows on X11 - Accessibility: Fix potential crash in QDockWidget. - Accessibility: Fix crash when asking for relations of child accessibles. @@ -90,6 +104,8 @@ QtGui - Accessibility: Return text attributes for QTextEdit. - Accessibility: Make accessibility work on Windows with alien widgets - Accessibility: Several enablers for accessible graphicsview and Qt Quick applications. + - Fixed loading BMP files with version 4 and 5 headers, ignoring extra data. + - QTextCursor optimization QtNetwork --------- @@ -114,15 +130,31 @@ QtNetwork - Including <QtOpenGL> will not work in combination with GLEW, as QGLFunctions will undefine GLEW's defines. - Optimize behavior of QGLTextureCache + - Support subpixel antialiasing when possible. + - [QTBUG-13450] Fixed path drawing on FBOs without stencil buffer. QtScript -------- - Deprecated qScriptValueFromQMetaObject, qScriptValueToValue, qScriptValueFromValue +QtDBus +------ + - Added a method that returns the local machine ID + QtSql ----- - - Update sqlite to 3.7.7.1 + +QtSvg +----- + - [QTBUG-16216] Fixed infinite loop when loading some SVGs with CSS style. + +QtDBus +------ + - Make QDBusServer work [QTBUG-186] + - QDBusConnection: Add methods disconnectFromPeer and connectToPeer + - Make the DBus timeout configurable in QDBusAbstractInterface. + **************************************************************************** * Database Drivers * **************************************************************************** @@ -139,11 +171,17 @@ Qt for Linux/X11 - Various fixes to FontConfig font matching code to make it consistent with other X11 programs. [QTBUG-2148, QTBUG-19947, QTBUG-14269] - Added experimental support for armCC + - Experimental support for associating Wayland clients with PID or a token, + to facilitate window management. Qt for Windows -------------- - DirectWrite experimental text shaping engine is added with subpixel positioning support. [QTBUG-12678] + - QElapsedTimer: use QueryPerformanceCounter if available. + - MSVC runtime is bound to the runtime you're building with. This makes + deployment on Windows easier. (QTBUG-8215) + - QLocalSocket::isValid() has been fixed. (QTBUG-18204) Qt for Mac OS X --------------- @@ -171,6 +209,36 @@ Qt for Symbian be made via a specific network. For example to mobile operator websites only accessible via the cellular network, or to websites inside a firewall - System proxy settings now work correctly when using service networks [QTBUG-18618] + - Prevent horizontal lines appearing under entered characters when predictive text is off + - Checked state is not shown on highlighted itemview item when using QS60Style [QTBUG-19668] + - Icon is not shown correctly in a menu item in all cases when using QS60Style [QTBUG-19330] + - Remove S60 3rd edition support from QS60Style [QTBUG-18615] + - Prevent softkeys from coming to foreground when taskswitcher is opened [QTBUG-19225] + - Improve robustness of QS60Style when creating native theme bitmaps [QTBUG-21119] + - Make spinboxes and lineedits slightly taller in QS60Style + - Default graphics memory quota for Symbian applications support [QT-4963] + - Improved support for shadow builds in Symbian [QTBUG-10432] + - Fixed panic when global QSettings instance needs flusing at app exit [QTBUG-21421] + - Detect app caption and pkg name translations by id attribute [QT-5247] + - Fixed center aligned layouts for Symbian [QTBUG-14704] + - Fixed Symbian system date format parsing [QT-5237] + - Skip softkeys update if application is not on foreground in Symbian [QTBUG-19225] + - Removed S60 version plugins [QTBUG-18614] + - Improved DEFINES crossplatform compatibility in Symbian builds [QTBUG-19232] + - Fixed loss of focus and activation when hiding a child widget [QTBUG-19196] + - Fixed softkeys in case a dialog with softkeys that have icons is closed [QTBUG-19154] + - Update softkeys after orientation switch [QTBUG-19150] + - Implemented support for enable_backup CONFIG value [QTBUG-17214] + - Improved logic to find default certificates in createpackage script [QTBUG-18684] + - Changed createpackage and patch_capabilties scripts use tmp dir [QTBUG-11394] + - Added ".make.cache" to the files to be cleaned for symbian-abld [QTBUG-15733] + - Fixed emulator deployment for items with "!:" drive [QTBUG-18134] + - Removed broken "deploy.path" support from Symbian [QTBUG-14426] + - Strip echo suppression character "@" from commands in symbian-sbsv2 [QTBUG-4767] + - Don't leave from QNotifyChangeEvent::RunL() in QFileSystemWatcher [QT-4660] + - Fixed QProcess::waitForFinished WaitForRequest handling in Symbian [QT-4659] + - Changed DEPLOYMENT keyword to accept both .sources and .files [QTBUG-3216] + - Removed static vs dynamic library autodetection from qmake in Symbian [QTBUG-13498] Qt for Windows CE ----------------- @@ -182,6 +250,9 @@ Qt for Windows CE - Sun Studio 12 * Fixed build issues in the OpenGL module on Solaris with CC 5.9. [QTBUG-19641] +- Microsoft Visual C++ + * Fixed build issues with STLport. [QTBUG-18374] + **************************************************************************** * Tools * **************************************************************************** @@ -223,9 +294,23 @@ Qt for Windows CE - qmake - + * MinGW: fix DEF_FILE for shadow builds. (QTBUG-11643) + +- qmake - Visual Studio project generator + * Support x64 Qt builds. (QTBUG-17911) + * QMAKE_PROJECT_NAME qmake variable introduced to set the project's name. + * Support PCHs with other extensions than ".h". (QTBUG-16639) + * Fix setting PCH options manually via the MSVC compiler flags. + (QTBUG-15594) + * Set the output directory correctly. (QTBUG-16490) + * Fix handling of DEFINES from .prl files. (QTBUG-16024) + * Fix the language settings generated Windows resource files. + (QTBUG-12249) + * Implemented "aux" template that allows making use of the INSTALLS variable + without building anything. Needed for projects with QML entry point. - configure + * The endianness for Windows is always set to little endian. - qtconfig diff --git a/doc/src/platforms/platform-notes-rtos.qdoc b/doc/src/platforms/platform-notes-rtos.qdoc index 0b1265b..dd72016 100644 --- a/doc/src/platforms/platform-notes-rtos.qdoc +++ b/doc/src/platforms/platform-notes-rtos.qdoc @@ -313,7 +313,7 @@ ARM INTEGRITY target: \code - ./configure --hostprefix=$PWD -embedded integrity -xplatform unsupported/qws/integrity-arm-cxarm -static -qt-kbd-integrity -qt-mouse-integrity -no-mouse-linuxtp -no-mouse-pc -no-kbd-tty -qt-gfx-integrityfb -no-qt3support -no-gfx-linuxfb -no-glib -no-openssl -no-largefile -little-endian -arch integrity -prefix / -opensource -no-feature-QWS_MULTIPROCESS -no-feature-SHAREDMEMORY -no-feature-PROCESS -no-feature-SYSTEMSEMAPHORE -no-feature-PRINTER -no-feature-QWS_QPF2 -no-scripttools + ./configure --hostprefix=$PWD -embedded integrity -xplatform unsupported/qws/integrity-arm-cxarm -static -qt-kbd-integrity -qt-mouse-integrity -no-mouse-linuxtp -no-mouse-pc -no-kbd-tty -qt-gfx-integrityfb -no-qt3support -no-gfx-linuxfb -no-glib -no-openssl -no-largefile -little-endian -arch integrity -prefix / -opensource -no-feature-QWS_MULTIPROCESS -no-feature-SHAREDMEMORY -no-feature-PROCESS -no-feature-SYSTEMSEMAPHORE -no-feature-PRINTER -no-feature-QWS_QPF2 -no-libtiff -no-exceptions -no-scripttools \endcode \list @@ -326,6 +326,7 @@ \o \c{-no-qt3support} - required since the Qt3 support classes are not supported on INTEGRITY \o \c{-no-exceptions} - reduces the size of the library by disabling exception support \o \c{-no-openssl} - disable support for OpenSSL + \o \c(-no-libtiff} - disable support for libTIFF \o \c{-no-glib} - disable support for unavailable Glib \o \c{-no-largefile} - disable support for large (> 2TB) files \o \c{-no-scripttools} - disable support for QtScript tools @@ -346,7 +347,13 @@ of INTEGRITY_DIR and INTEGRITY_BSP in unsupported/qws/integrity-arm-cxarm/qmake.conf. If you do not do this, you will have to modify the resulting generated projects.gpj - \o GIF support is currently not enabled. + \o Compilation of native preprocessing tools (moc, rcc, uic) is not automatic. From + a Linux shell or a MingWin shell, you can run the following command to compile these tools : + \code + cd src/tools/bootstrap && make && cd ../rcc && make && cd ../moc && make && cd ../uic && make && cd ../../.. + \endcode + + \o GIF and TIFF support are currently not enabled. \o Default .int files are generated. You may want to modify the amount of heap assigned to each example by modifying the HeapSize declaration in the specific example .int file. diff --git a/doc/src/sql-programming/sql-driver.qdoc b/doc/src/sql-programming/sql-driver.qdoc index 40c7c6a..ed60e7f 100644 --- a/doc/src/sql-programming/sql-driver.qdoc +++ b/doc/src/sql-programming/sql-driver.qdoc @@ -60,6 +60,7 @@ \row \o \link #QPSQL QPSQL\endlink \o PostgreSQL (versions 7.3 and above) \row \o \link #QSQLITE2 QSQLITE2\endlink \o SQLite version 2 \row \o \link #QSQLITE QSQLITE\endlink \o SQLite version 3 + \row \o \link #QSYMSQL QSYMSQL\endlink \o SQLite version 3 for Symbian SQL Database \row \o \link #QTDS QTDS\endlink \o Sybase Adaptive Server \note obsolete from Qt 4.7 \endtable @@ -665,6 +666,106 @@ ship your own database plugin with your own SQLite library as illustrated above. Some versions of SQLite can be forced to write a specific file format by setting the \c{SQLITE_DEFAULT_FILE_FORMAT} define when building SQLite. + + \target QSYMSQL + \section2 QSYMSQL for SQLite (Version 3 and Above) with Symbian SQL Database + + \section3 General Information about QSYMSQL + + QSYMSQL driver enables clients to access the native Symbian database engine (“Symbian SQL”) + through the QtSQL API. + + The main difference to QSQLITE is that, with Symbian SQL database client can specify a + set of access control policies when creating a new database. It uses Symbian SQL security policy + definitions within open() call (security policy is defined with in the connection options parameters). + + Symbian RSqlSecurityPolicy class is a container for the security policies for a shared SQL database. + + The container can contain: + security policies that apply to the database. + security policies that apply to individual database objects, i.e. database tables. + + For the database, you use RSqlSecurityPolicy::SetDbPolicy() to apply a separate security policy to: + the database schema. + read activity on the database. + write activity on the database. + + For database tables, you use RSqlSecurityPolicy::SetPolicy() to apply a separate security policy to: + write activity on each named database table. + read activity on each named database table. + + More information about Symbian SQL and RSqlSecurityPolicy class reference about policy definitions, + can be found from Forum Nokia Library: http://library.developer.nokia.com/. + + +Example of setting Security Policy: + + Connection options hold definition for security policies and all parameters that does not contain "POLICY_" will be + passed to RSqlDatabase. Policy will be filled according to parsed values. + + Value in database wide parameters starts by definition which can be vendorId or secureId. These come directly from TSecurityPolicy class in Symbian. + + POLICY_DB_DEFAULT + Default security policy which will be used for the database and all database objects. POLICY_DB_DEFAULT must be + defined before any other policy definitions can be used. + POLICY_DB_READ + Read database security policy. An application with read database security policy can read from database. + POLICY_DB_WRITE: + Write database security policy. An application with write database security policy can write to database. + POLICY_DB_SCHEMA: + Schema database security policy. An application with schema database security policy can modify + the database schema, write to database, read from database. + + Format: + POLICY_DB_DEFAULT=cap1,cap2,cap3,cap4,cap5,cap6,cap7 (Up to 7 capabilities) + POLICY_DB_READ=cap1,cap2,cap3,cap4,cap5,cap6,cap7 (Up to 7 capabilities) + POLICY_DB_WRITE=vendorid,cap1,cap2,cap3 (Vendor ID and up to 3 capabilities) + POLICY_DB_SCHEMA=secureid,cap1,cap2,cap3 (Secure ID and up to 3 capabilities) + + Table policies does not support schema policy as database level does. + + Table specific parameters would be as: + POLICY_TABLE_WRITE=tablename,cap1,cap2,cap3,cap4,cap5,cap6,cap7 + POLICY_TABLE_READ=tablename,cap1,cap2,cap3,cap4,cap5,cap6,cap7 + + Vendor Id and Secure id format: + vid[0x12345678] (Hex) + sid[0x12345678] (Hex) + + Examples: + Setting default policy: + QSqlDatabase database = QSqlDatabase::addDatabase("QSYMSQL", "MyConnection"); + database.setConnectOptions("POLICY_DB_DEFAULT=ReadDeviceData"); + database.setDatabaseName("[12345678]myDatabase"); + bool ok = database.open(); + + Setting POLICY_DB_WRITE: + QSqlDatabase database = QSqlDatabase::addDatabase("QSYMSQL", "MyConnection"); + database.setConnectOptions("POLICY_DB_DEFAULT=None; POLICY_DB_WRITE=sid[0x12345678], WriteDeviceData"); + database.setDatabaseName("[12345678]myDatabase"); + bool ok = database.open(); + + FOREIGN KEY: + Enabling foreign key support from underlying SQLite + add: "foreign_keys = ON" to your connection options string. This will be passes to SQLite. + + Foreign key Example: + QSqlDatabase database = QSqlDatabase::addDatabase("QSYMSQL", "MyConnection"); + database.setDatabaseName("[12345678]myDatabase"); + database.setConnectOptions("foreign_keys = ON"); + bool ok = database.open(); + + \section3 How to Build the QSYMSQL Plugin + + Building QSYMSQL requires Symbian SDK. + + The build sequence is similar to the QSQLITE plugin with installing the plugin in the standard location. + + Build sequence: + + >cd sf\mw\qt\src\plugins\sqldrivers\symsql\ + >qmake + >sbs -c winscw_udeb|armv5_urel \target QIBASE \section2 QIBASE for Borland InterBase diff --git a/mkspecs/features/link_pkgconfig.prf b/mkspecs/features/link_pkgconfig.prf index a3dbd1f..91683f6 100644 --- a/mkspecs/features/link_pkgconfig.prf +++ b/mkspecs/features/link_pkgconfig.prf @@ -5,8 +5,21 @@ for(PKGCONFIG_LIB, $$list($$unique(PKGCONFIG))) { # don't proceed if the .pro asks for a package we don't have! !packagesExist($$PKGCONFIG_LIB):error("Package $$PKGCONFIG_LIB not found") - QMAKE_CXXFLAGS += $$system($$PKG_CONFIG --cflags $$PKGCONFIG_LIB) - QMAKE_CFLAGS += $$system($$PKG_CONFIG --cflags $$PKGCONFIG_LIB) + PKGCONFIG_CFLAGS = $$system($$PKG_CONFIG --cflags $$PKGCONFIG_LIB) + + PKGCONFIG_INCLUDEPATH = $$find(PKGCONFIG_CFLAGS, ^-I.*) + PKGCONFIG_INCLUDEPATH ~= s/^-I(.*)/\\1/g + + PKGCONFIG_DEFINES = $$find(PKGCONFIG_CFLAGS, ^-D.*) + PKGCONFIG_DEFINES ~= s/^-D(.*)/\\1/g + + PKGCONFIG_CFLAGS ~= s/^-[ID].*//g + + INCLUDEPATH *= $$PKGCONFIG_INCLUDEPATH + DEFINES *= $$PKGCONFIG_DEFINES + + QMAKE_CXXFLAGS += $$PKGCONFIG_CFLAGS + QMAKE_CFLAGS += $$PKGCONFIG_CFLAGS LIBS += $$system($$PKG_CONFIG --libs $$PKGCONFIG_LIB) } diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 191a449..326fe10 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -64,29 +64,35 @@ for(QT_CURRENT_VERIFY, $$list($$QT_PLUGIN_VERIFY)) { # Check if the plugin is known to Qt. We can use this to determine # the plugin path. Unknown plugins must rely on the default link path. ACCESSIBLEPLUGINS = qtaccessiblewidgets qtaccessiblecompatwidgets + BEARERPLUGINS = qgenericbearer qnativewifibearer CODECPLUGINS = qcncodecs qjpcodecs qkrcodecs qtwcodecs - DECORATIONPLUGINS = qdecorationdefault qdecorationwindows - GFXDRIVERPLUGINS = qgfxvnc qscreenvfb qgfxsnap qgfxvga16 qgfxmatrox qgfxvoodoo qgfxtransformed qgfxshadowfb - IMAGEPLUGINS = qgif qmng qjpeg qsvg + DECORATIONPLUGINS = qdecorationdefault qdecorationstyled qdecorationwindows + GFXDRIVERPLUGINS = qgfxvnc qscreenvfb qgfxtransformed qgfxshadowfb qgfxpvregl qscreenlinuxfb qeglnullws qdirectfbscreen qahiscreen + GRAPHICSSYSTEMPLUGINS = qmeegographicssystem qglgraphicssystem qvggraphicssystem qshivavggraphicssystem + IMAGEPLUGINS = qgif qico qmng qjpeg qsvg qtiff INPUTPLUGINS = qimsw-multi - MOUSEDRIVERPLUGINS = qtslibmousehandler + KBDDRIVERPLUGINS = qlinuxinputkbddriver + MOUSEDRIVERPLUGINS = qtslibmousehandler qpcmousedriver qlinuxtpmousedriver SQLPLUGINS = qsqldb2 qsqloci qsqltds qsqlodbc qsqlpsql qsqlibase qsqlmysql qsqlite2 qsqlite - PHONONPLUGINS = phonon_waveout phonon_ds9 + PHONONPLUGINS = phonon_waveout phonon_ds9 phonon_gstreamer phonon_qt7 phonon_mmf - ALLQTPLUGINS = $$ACCESSIBLEPLUGINS $$CODECPLUGINS $$DECORATIONPLUGINS $$GFXDRIVERPLUGINS $$IMAGEPLUGINS $$INPUTPLUGINS $$MOUSEDRIVERPLUGINS $$SQLPLUGINS $$PHONONPLUGINS + ALLQTPLUGINS = $$ACCESSIBLEPLUGINS $$BEARERPLUGINS $$CODECPLUGINS $$DECORATIONPLUGINS $$GFXDRIVERPLUGINS $$ GRAPHICSSYSTEMPLUGINS $$IMAGEPLUGINS $$INPUTPLUGINS $$KBDDRIVERPLUGINS $$MOUSEDRIVERPLUGINS $$SQLPLUGINS $$PHONONPLUGINS QT_PLUGINPATH = contains(ALLQTPLUGINS, $$QTPLUG) { # Determine the plugin path contains(ACCESSIBLEPLUGINS, $$QTPLUG): QT_PLUGINPATH = accessible + contains(BEARERPLUGINS, $$QTPLUG): QT_PLUGINPATH = bearer contains(CODECPLUGINS, $$QTPLUG): QT_PLUGINPATH = codecs contains(DECORATIONPLUGINS, $$QTPLUG): QT_PLUGINPATH = decorations contains(GFXDRIVERPLUGINS, $$QTPLUG): QT_PLUGINPATH = gfxdrivers + contains(GRAPHICSSYSTEMPLUGINS, $$QTPLUG): QT_PLUGINPATH = graphicssystems contains(IMAGEPLUGINS, $$QTPLUG): QT_PLUGINPATH = imageformats contains(INPUTPLUGINS, $$QTPLUG): QT_PLUGINPATH = inputmethods + contains(KBDDRIVERPLUGINS, $$QTPLUG): QT_PLUGINPATH = kbddrivers contains(MOUSEDRIVERPLUGINS, $$QTPLUG): QT_PLUGINPATH = mousedrivers contains(SQLPLUGINS, $$QTPLUG): QT_PLUGINPATH = sqldrivers - contains(PHONONPLUGINS, $$QTPLUG): QT_PLUGINPATH = phonon_backend + contains(PHONONPLUGINS, $$QTPLUG): QT_PLUGINPATH = phonon_backend } # Generate the plugin linker line diff --git a/mkspecs/symbian-sbsv2/flm/qt/qmake_extra_pre_targetdep.flm b/mkspecs/symbian-sbsv2/flm/qt/qmake_extra_pre_targetdep.flm index dce7f20..26afff6 100644 --- a/mkspecs/symbian-sbsv2/flm/qt/qmake_extra_pre_targetdep.flm +++ b/mkspecs/symbian-sbsv2/flm/qt/qmake_extra_pre_targetdep.flm @@ -31,6 +31,7 @@ endef ifeq ($($(SINGLETON)),) $(eval $(qmake_extra_pre_targetdep)) $(eval $(call GenerateStandardCleanTarget,$(PREDEP_TARGET),'')) +$(eval $(call whatmacro,$(PREDEP_TARGET))) endif diff --git a/mkspecs/unsupported/integrity-ghs/qplatformdefs.h b/mkspecs/unsupported/integrity-ghs/qplatformdefs.h index 919d2cf..589b3bf 100644 --- a/mkspecs/unsupported/integrity-ghs/qplatformdefs.h +++ b/mkspecs/unsupported/integrity-ghs/qplatformdefs.h @@ -89,6 +89,7 @@ #define QT_TRUNCATE ::truncate #define QT_FTRUNCATE ::ftruncate #define QT_LSEEK ::lseek +#define QT_OPEN_LARGEFILE 0 #endif #ifdef QT_LARGEFILE_SUPPORT diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index f50afc3..0b201b8 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -1524,8 +1524,8 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCEventTool &tool) { xml << tag(tool.EventName) - << attrTagS(_Command, tool.CommandLine.join(vcxCommandSeparator())) - << attrTagS(_Message, tool.Description) + << tag(_Command) << valueTag(tool.CommandLine.join(vcxCommandSeparator())) + << tag(_Message) << valueTag(tool.Description) << closetag(tool.EventName); } diff --git a/qmake/option.cpp b/qmake/option.cpp index 31372ab..c3e89de 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -750,64 +750,11 @@ qmakeAddCacheClear(qmakeCacheClearFunc func, void **data) cache_items.append(new QMakeCacheClearItem(func, data)); } -#ifdef Q_OS_WIN -# include <windows.h> - -QT_USE_NAMESPACE -#endif - QString qmake_libraryInfoFile() { - QString ret; -#if defined( Q_OS_WIN ) - wchar_t module_name[MAX_PATH]; - GetModuleFileName(0, module_name, MAX_PATH); - QFileInfo filePath = QString::fromWCharArray(module_name); - ret = filePath.filePath(); -#else - QString argv0 = QFile::decodeName(QByteArray(Option::application_argv0)); - QString absPath; - - if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) { - /* - If argv0 starts with a slash, it is already an absolute - file path. - */ - absPath = argv0; - } else if (argv0.contains(QLatin1Char('/'))) { - /* - If argv0 contains one or more slashes, it is a file path - relative to the current directory. - */ - absPath = QDir::current().absoluteFilePath(argv0); - } else { - /* - Otherwise, the file path has to be determined using the - PATH environment variable. - */ - QByteArray pEnv = qgetenv("PATH"); - QDir currentDir = QDir::current(); - QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1String(":")); - for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) { - if ((*p).isEmpty()) - continue; - QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0); - QFileInfo candidate_fi(candidate); - if (candidate_fi.exists() && !candidate_fi.isDir()) { - absPath = candidate; - break; - } - } - } - - absPath = QDir::cleanPath(absPath); - - QFileInfo fi(absPath); - ret = fi.exists() ? fi.canonicalFilePath() : QString(); -#endif - if(!ret.isEmpty()) - ret = QDir(QFileInfo(ret).absolutePath()).filePath("qt.conf"); - return ret; + if(!Option::qmake_abslocation.isEmpty()) + return QDir(QFileInfo(Option::qmake_abslocation).absolutePath()).filePath("qt.conf"); + return QString(); } QT_END_NAMESPACE diff --git a/src/3rdparty/webkit/.tag b/src/3rdparty/webkit/.tag index 458898a..34446ae 100644 --- a/src/3rdparty/webkit/.tag +++ b/src/3rdparty/webkit/.tag @@ -1 +1 @@ -a2bd2bb1b19949c6807da38e25bfa7d210bb4b17 +64cce100215c71575f19ca0b090c65fa97d4ba10 diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/Source/JavaScriptCore/ChangeLog index 5aec2e3..9cda920 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/Source/JavaScriptCore/ChangeLog @@ -1,3 +1,28 @@ +2011-05-23 Thouraya ANDOLSI <thouraya.andolsi@st.com> + + Reviewed by Gavin Barraclough. + + [SH4] AssemblerLabel does not name a type + https://bugs.webkit.org/show_bug.cgi?id=59927 + + SH4Assembler.h file shoold be included before AbstractMacroAssembler.h. + + * assembler/MacroAssemblerSH4.h: + +2011-06-28 Pierre Rossi <pierre.rossi@gmail.com> + + Reviewed by Eric Seidel. + + Warnings in JSC's JIT on 32 bit + https://bugs.webkit.org/show_bug.cgi?id=63259 + + Fairly straightforward, just use ASSERT_JIT_OFFSET_UNUSED when it applies. + + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_method_check): + (JSC::JIT::compileGetByIdHotPath): + (JSC::JIT::emit_op_put_by_id): + 2011-08-30 Ademar de Souza Reis Jr. <ademar.reis@openbossa.org> [Qt] Do not unconditionally use pkg-config in .pro files diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h b/src/3rdparty/webkit/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h index 5ef7b20..9036f0f 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h +++ b/src/3rdparty/webkit/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h @@ -29,8 +29,8 @@ #if ENABLE(ASSEMBLER) && CPU(SH4) -#include "AbstractMacroAssembler.h" #include "SH4Assembler.h" +#include "AbstractMacroAssembler.h" #include <wtf/Assertions.h> namespace JSC { diff --git a/src/3rdparty/webkit/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/src/3rdparty/webkit/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp index f18e277..c88e9ad 100644 --- a/src/3rdparty/webkit/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp +++ b/src/3rdparty/webkit/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp @@ -225,9 +225,9 @@ void JIT::emit_op_method_check(Instruction* currentInstruction) move(TrustedImm32(JSValue::CellTag), regT1); Jump match = jump(); - ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, protoObj), patchOffsetMethodCheckProtoObj); + ASSERT_JIT_OFFSET_UNUSED(protoObj, differenceBetween(info.structureToCompare, protoObj), patchOffsetMethodCheckProtoObj); ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, protoStructureToCompare), patchOffsetMethodCheckProtoStruct); - ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, putFunction), patchOffsetMethodCheckPutFunction); + ASSERT_JIT_OFFSET_UNUSED(putFunction, differenceBetween(info.structureToCompare, putFunction), patchOffsetMethodCheckPutFunction); // Link the failure cases here. structureCheck.link(this); @@ -436,9 +436,9 @@ void JIT::compileGetByIdHotPath() loadPtr(Address(regT0, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), regT2); DataLabel32 displacementLabel1 = loadPtrWithAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT0); // payload - ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel1), patchOffsetGetByIdPropertyMapOffset1); + ASSERT_JIT_OFFSET_UNUSED(displacementLabel1, differenceBetween(hotPathBegin, displacementLabel1), patchOffsetGetByIdPropertyMapOffset1); DataLabel32 displacementLabel2 = loadPtrWithAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT1); // tag - ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel2), patchOffsetGetByIdPropertyMapOffset2); + ASSERT_JIT_OFFSET_UNUSED(displacementLabel2, differenceBetween(hotPathBegin, displacementLabel2), patchOffsetGetByIdPropertyMapOffset2); Label putResult(this); ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, putResult), patchOffsetGetByIdPutResult); @@ -514,8 +514,8 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction) END_UNINTERRUPTED_SEQUENCE(sequencePutById); - ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel1), patchOffsetPutByIdPropertyMapOffset1); - ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel2), patchOffsetPutByIdPropertyMapOffset2); + ASSERT_JIT_OFFSET_UNUSED(displacementLabel1, differenceBetween(hotPathBegin, displacementLabel1), patchOffsetPutByIdPropertyMapOffset1); + ASSERT_JIT_OFFSET_UNUSED(displacementLabel2, differenceBetween(hotPathBegin, displacementLabel2), patchOffsetPutByIdPropertyMapOffset2); } void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) diff --git a/src/3rdparty/webkit/Source/WebCore/ChangeLog b/src/3rdparty/webkit/Source/WebCore/ChangeLog index a781b1f..da9d1b2 100644..100755 --- a/src/3rdparty/webkit/Source/WebCore/ChangeLog +++ b/src/3rdparty/webkit/Source/WebCore/ChangeLog @@ -1,3 +1,165 @@ +2011-09-12 Adam Klein <adamk@chromium.org> + + Fix out-of-bounds access in Gradient::sortStopsIfNecessary + https://bugs.webkit.org/show_bug.cgi?id=67958 + + Reviewed by Darin Adler. + + Reported by Valgrind in http://crbug.com/77049. + + The errant code was added as an optimization in r67804. + This patch reverts that one, as all parties agree that the optimization + doesn't seem worthwhile, and there clearly aren't any tests covering + the special case. + + No new tests, as existing tests should cover the remaining call to + |std::stable_sort|. + + * platform/graphics/Gradient.cpp: + (WebCore::Gradient::sortStopsIfNecessary): + +2011-09-09 Dominic Mazzoni <dmazzoni@google.com> + + Assert being hit in AccessibilityRenderObject::addChildren() + https://bugs.webkit.org/show_bug.cgi?id=61805 + + Reviewed by Chris Fleizach. + + Fix nextSibling and previousSibling to handle adjacent continuations + properly, otherwise nodes end up appearing in the accessibility + tree twice (or a debug assertion could be raised). + + Test: accessibility/adjacent-continuations-cause-assertion-failure.html + + * accessibility/AccessibilityRenderObject.cpp: + (WebCore::AccessibilityRenderObject::previousSibling): + (WebCore::AccessibilityRenderObject::nextSibling): + +2011-09-08 Abhishek Arya <inferno@chromium.org> + + :before content rendering issues with list markers and run-ins. + https://bugs.webkit.org/show_bug.cgi?id=67735 + + 1) Remove the isAnonymous checks for run-in detection since the + run-in can belong to a node. + 2) When the parent has block children, then the list marker will + be enclosed in an anonymous block. In that case, for going to the + next list marker, we need to traverse one level up. We don't need + this check when searching for generated run-in (loop 2), since we + know parent will have inline children, so the list marker wont be + enclosed in an anonymous block. + + Reviewed by Dave Hyatt. + + Tests: fast/lists/list-marker-before-content-table.html + fast/runin/runin-generated-before-content.html + + * rendering/RenderObjectChildList.cpp: + (WebCore::RenderObjectChildList::beforePseudoElementRenderer): + +2011-09-10 Ken Buchanan <kenrb@chromium.org> + + Crash due to bad data in SVGDocumentExtensions m_pendingResources + https://bugs.webkit.org/show_bug.cgi?id=67488 + + Reviewed by Nikolas Zimmermann. + + Resolving a crash condition caused by the deletion of + elements while pending resource entries for those elements are still + recorded. + + * rendering/svg/RenderSVGResourceContainer.cpp: + (WebCore::RenderSVGResourceContainer::registerResource) + * svg/SVGDocumentExtensions.h: + (WebCore::SVGDocumentExtensions::isElementInPendingResources) + * svg/SVGDocumentExtensions.cpp: + (WebCore::SVGDocumentExtensions::addPendingResource) + (WebCore::SVGDocumentExtensions::isElementInPendingResources) + (WebCore::SVGDocumentExtensions::removeElementFromPendingResources) + * svg/SVGStyledElement.h: + (WebCore::SVGStyledElement::clearHasPendingResourcesIfPossible) + * svg/SVGStyledElement.cpp: + (WebCore::SVGStyledElement::buildPendingResourcesIfNeeded) + (WebCore::SVGStyledElement::clearHasPendingResourcesIfPossible) + * svg/SVGUseElement.cpp: + (WebCore::SVGUseElement::svgAttributeChanged) + +2011-09-08 Alexey Proskuryakov <ap@apple.com> + + REGRESSION (r66874): Missing RefPtr in ScriptController + https://bugs.webkit.org/show_bug.cgi?id=67748 + + Reviewed by Adam Barth. + + * bindings/ScriptControllerBase.cpp: (WebCore::ScriptController::executeScript): + +2011-09-06 Abhishek Arya <inferno@chromium.org> + + Style not propagated to anonymous boxes and anonymous + inline-blocks. + https://bugs.webkit.org/show_bug.cgi?id=67364 + + Reviewed by James Robinson. + + Share propagateStyleToAnonymousChildren with RenderBlock::styleDidChange. + + * rendering/RenderBlock.cpp: + (WebCore::RenderBlock::styleDidChange): + * rendering/RenderObject.cpp: + (WebCore::RenderObject::propagateStyleToAnonymousChildren): + * rendering/RenderObject.h: + +2011-09-04 Abhishek Arya <inferno@chromium.org> + + Style not propagated to anonymous boxes and anonymous + inline-blocks. + https://bugs.webkit.org/show_bug.cgi?id=67364 + + Reviewed by James Robinson. + + Tests: fast/ruby/ruby-block-style-not-updated-with-before-after-content.html + fast/ruby/ruby-block-style-not-updated.html + fast/ruby/ruby-inline-style-not-updated-with-before-after-content.html + fast/ruby/ruby-inline-style-not-updated.html + fast/table/table-row-style-not-updated-with-after-content.html + fast/table/table-row-style-not-updated-with-before-content.html + fast/table/table-row-style-not-updated.html + fast/table/table-style-not-updated.html + + * rendering/RenderObject.cpp: + (WebCore::RenderObject::propagateStyleToAnonymousChildren): + * rendering/RenderObject.h: + (WebCore::RenderObject::isBeforeAfterContent): + * rendering/RenderRuby.cpp: + (WebCore::RenderRubyAsInline::styleDidChange): + (WebCore::RenderRubyAsBlock::styleDidChange): + * rendering/RenderRuby.h: + * rendering/RenderTable.cpp: + (WebCore::RenderTable::styleDidChange): + * rendering/RenderTableRow.cpp: + (WebCore::RenderTableRow::styleDidChange): + (WebCore::RenderTableRow::addChild): + * rendering/RenderTableSection.cpp: + (WebCore::RenderTableSection::styleDidChange): + (WebCore::RenderTableSection::addChild): + * rendering/RenderTableSection.h: + +2011-09-05 Abhishek Arya <inferno@chromium.org> + + Crash in RenderObjectChildList::destroyLeftOverChildren() + https://bugs.webkit.org/show_bug.cgi?id=64753 + + Reviewed by James Robinson. + + If any of the ancestors between column span element and containing + column's block is a continuation, then don't attempt to render the + column span by splitting the block into continuations. + + Test: fast/multicol/column-span-parent-continuation-crash.html + + * rendering/RenderBlock.cpp: + (WebCore::RenderBlock::columnsBlockForSpanningElement): + 2011-08-30 Abhishek Arya <inferno@chromium.org> Removed m_owner accessed in custom scrollbars. diff --git a/src/3rdparty/webkit/Source/WebCore/accessibility/AccessibilityRenderObject.cpp b/src/3rdparty/webkit/Source/WebCore/accessibility/AccessibilityRenderObject.cpp index 25078c5..9725a6b 100644 --- a/src/3rdparty/webkit/Source/WebCore/accessibility/AccessibilityRenderObject.cpp +++ b/src/3rdparty/webkit/Source/WebCore/accessibility/AccessibilityRenderObject.cpp @@ -302,8 +302,12 @@ AccessibilityObject* AccessibilityRenderObject::previousSibling() const // Case 2: Anonymous block parent of the end of a continuation - skip all the way to before // the parent of the start, since everything in between will be linked up via the continuation. - else if (m_renderer->isAnonymousBlock() && firstChildIsInlineContinuation(m_renderer)) - previousSibling = startOfContinuations(m_renderer->firstChild())->parent()->previousSibling(); + else if (m_renderer->isAnonymousBlock() && firstChildIsInlineContinuation(m_renderer)) { + RenderObject* firstParent = startOfContinuations(m_renderer->firstChild())->parent(); + while (firstChildIsInlineContinuation(firstParent)) + firstParent = startOfContinuations(firstParent->firstChild())->parent(); + previousSibling = firstParent->previousSibling(); + } // Case 3: The node has an actual previous sibling else if (RenderObject* ps = m_renderer->previousSibling()) @@ -340,8 +344,12 @@ AccessibilityObject* AccessibilityRenderObject::nextSibling() const // Case 2: Anonymous block parent of the start of a continuation - skip all the way to // after the parent of the end, since everything in between will be linked up via the continuation. - else if (m_renderer->isAnonymousBlock() && lastChildHasContinuation(m_renderer)) - nextSibling = endOfContinuations(m_renderer->lastChild())->parent()->nextSibling(); + else if (m_renderer->isAnonymousBlock() && lastChildHasContinuation(m_renderer)) { + RenderObject* lastParent = endOfContinuations(m_renderer->lastChild())->parent(); + while (lastChildHasContinuation(lastParent)) + lastParent = endOfContinuations(lastParent->lastChild())->parent(); + nextSibling = lastParent->nextSibling(); + } // Case 3: node has an actual next sibling else if (RenderObject* ns = m_renderer->nextSibling()) diff --git a/src/3rdparty/webkit/Source/WebCore/bindings/ScriptControllerBase.cpp b/src/3rdparty/webkit/Source/WebCore/bindings/ScriptControllerBase.cpp index 4190637..254a6c2 100644 --- a/src/3rdparty/webkit/Source/WebCore/bindings/ScriptControllerBase.cpp +++ b/src/3rdparty/webkit/Source/WebCore/bindings/ScriptControllerBase.cpp @@ -59,6 +59,8 @@ ScriptValue ScriptController::executeScript(const ScriptSourceCode& sourceCode) bool wasInExecuteScript = m_inExecuteScript; m_inExecuteScript = true; + RefPtr<Frame> protect(m_frame); // Script execution can destroy the frame, and thus the ScriptController. + ScriptValue result = evaluate(sourceCode); if (!wasInExecuteScript) { diff --git a/src/3rdparty/webkit/Source/WebCore/platform/graphics/Gradient.cpp b/src/3rdparty/webkit/Source/WebCore/platform/graphics/Gradient.cpp index 7e3984f..fc7b741 100644 --- a/src/3rdparty/webkit/Source/WebCore/platform/graphics/Gradient.cpp +++ b/src/3rdparty/webkit/Source/WebCore/platform/graphics/Gradient.cpp @@ -124,10 +124,6 @@ void Gradient::sortStopsIfNecessary() if (!m_stops.size()) return; - // Shortcut for the ideal case (ordered 2-stop gradient) - if (m_stops.size() == 2 && compareStops(*m_stops.begin(), *m_stops.end())) - return; - std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); } diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlock.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlock.cpp index df30adb..4ad1bfe 100644 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlock.cpp +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderBlock.cpp @@ -241,21 +241,7 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty } } - // FIXME: We could save this call when the change only affected non-inherited properties - for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { - if (child->isAnonymousBlock()) { - RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style()); - if (style()->specifiesColumns()) { - if (child->style()->specifiesColumns()) - newStyle->inheritColumnPropertiesFrom(style()); - if (child->style()->columnSpan()) - newStyle->setColumnSpan(true); - } - newStyle->setDisplay(BLOCK); - child->setStyle(newStyle.release()); - } - } - + propagateStyleToAnonymousChildren(true); m_lineHeight = -1; // Update pseudos for :before and :after now. @@ -654,8 +640,22 @@ RenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild) && !newChild->isInline() && !isAnonymousColumnSpanBlock()) { if (style()->specifiesColumns()) columnsBlockAncestor = this; - else if (!isInline() && parent() && parent()->isRenderBlock()) + else if (!isInline() && parent() && parent()->isRenderBlock()) { columnsBlockAncestor = toRenderBlock(parent())->containingColumnsBlock(false); + + if (columnsBlockAncestor) { + // Make sure that none of the parent ancestors have a continuation. + // If yes, we do not want split the block into continuations. + RenderObject* curr = this; + while (curr && curr != columnsBlockAncestor) { + if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) { + columnsBlockAncestor = 0; + break; + } + curr = curr->parent(); + } + } + } } return columnsBlockAncestor; } diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderObject.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderObject.cpp index a81e668..c1f5ba0 100644 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderObject.cpp +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderObject.cpp @@ -1811,6 +1811,24 @@ void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldSt } } +void RenderObject::propagateStyleToAnonymousChildren(bool blockChildrenOnly) +{ + // FIXME: We could save this call when the change only affected non-inherited properties. + for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { + if (blockChildrenOnly ? child->isAnonymousBlock() : child->isAnonymous() && !child->isBeforeOrAfterContent()) { + RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyle(style()); + if (style()->specifiesColumns()) { + if (child->style()->specifiesColumns()) + newStyle->inheritColumnPropertiesFrom(style()); + if (child->style()->columnSpan()) + newStyle->setColumnSpan(true); + } + newStyle->setDisplay(blockChildrenOnly ? BLOCK : child->style()->display()); + child->setStyle(newStyle.release()); + } + } +} + void RenderObject::updateFillImages(const FillLayer* oldLayers, const FillLayer* newLayers) { // Optimize the common case diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderObject.h b/src/3rdparty/webkit/Source/WebCore/rendering/RenderObject.h index 44ee43c..2ba0114 100644 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderObject.h +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderObject.h @@ -322,8 +322,10 @@ public: inline bool isBeforeContent() const; inline bool isAfterContent() const; + inline bool isBeforeOrAfterContent() const; static inline bool isBeforeContent(const RenderObject* obj) { return obj && obj->isBeforeContent(); } static inline bool isAfterContent(const RenderObject* obj) { return obj && obj->isAfterContent(); } + static inline bool isBeforeOrAfterContent(const RenderObject* obj) { return obj && obj->isBeforeOrAfterContent(); } bool childrenInline() const { return m_childrenInline; } void setChildrenInline(bool b = true) { m_childrenInline = b; } @@ -791,6 +793,7 @@ protected: virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle); // Overrides should call the superclass at the start virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); + void propagateStyleToAnonymousChildren(bool blockChildrenOnly = false); void drawLineForBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, BoxSide, Color, EBorderStyle, int adjbw1, int adjbw2, bool antialias = false); @@ -932,6 +935,11 @@ inline bool RenderObject::isAfterContent() const return true; } +inline bool RenderObject::isBeforeOrAfterContent() const +{ + return isBeforeContent() || isAfterContent(); +} + inline void RenderObject::setNeedsLayout(bool b, bool markParents) { bool alreadyNeededLayout = m_needsLayout; diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderObjectChildList.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderObjectChildList.cpp index a6c2da9..28703c5 100644 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderObjectChildList.cpp +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderObjectChildList.cpp @@ -271,7 +271,12 @@ RenderObject* RenderObjectChildList::beforePseudoElementRenderer(const RenderObj do { // Skip list markers and generated run-ins first = first->firstChild(); - while (first && (first->isListMarker() || (first->isRenderInline() && first->isRunIn() && first->isAnonymous()))) + while (first && first->isListMarker()) { + if (first->parent() != owner && first->parent()->isAnonymousBlock()) + first = first->parent(); + first = first->nextSibling(); + } + while (first && first->isRenderInline() && first->isRunIn()) first = first->nextSibling(); } while (first && first->isAnonymous() && first->style()->styleType() == NOPSEUDO); @@ -293,7 +298,7 @@ RenderObject* RenderObjectChildList::beforePseudoElementRenderer(const RenderObj // We still need to skip any list markers that could exist before the run-in. while (first && first->isListMarker()) first = first->nextSibling(); - if (first && first->style()->styleType() == BEFORE && first->isRenderInline() && first->isRunIn() && first->isAnonymous()) + if (first && first->style()->styleType() == BEFORE && first->isRenderInline() && first->isRunIn()) return first; } return 0; diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderRuby.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderRuby.cpp index e0137de..41604d6 100644 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderRuby.cpp +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderRuby.cpp @@ -119,6 +119,12 @@ RenderRubyAsInline::~RenderRubyAsInline() { } +void RenderRubyAsInline::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) +{ + RenderInline::styleDidChange(diff, oldStyle); + propagateStyleToAnonymousChildren(); +} + void RenderRubyAsInline::addChild(RenderObject* child, RenderObject* beforeChild) { // Insert :before and :after content before/after the RenderRubyRun(s) @@ -220,6 +226,12 @@ RenderRubyAsBlock::~RenderRubyAsBlock() { } +void RenderRubyAsBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) +{ + RenderBlock::styleDidChange(diff, oldStyle); + propagateStyleToAnonymousChildren(); +} + void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild) { // Insert :before and :after content before/after the RenderRubyRun(s) diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderRuby.h b/src/3rdparty/webkit/Source/WebCore/rendering/RenderRuby.h index 24ac0db..2ab964c 100644 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderRuby.h +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderRuby.h @@ -59,6 +59,9 @@ public: virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0); virtual void removeChild(RenderObject* child); +protected: + virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); + private: virtual bool isRuby() const { return true; } virtual const char* renderName() const { return "RenderRuby (inline)"; } @@ -75,6 +78,9 @@ public: virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0); virtual void removeChild(RenderObject* child); +protected: + virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); + private: virtual bool isRuby() const { return true; } virtual const char* renderName() const { return "RenderRuby (block)"; } diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp index 4e90ffc..73b0801 100644 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTable.cpp @@ -73,6 +73,7 @@ RenderTable::~RenderTable() void RenderTable::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { RenderBlock::styleDidChange(diff, oldStyle); + propagateStyleToAnonymousChildren(); ETableLayout oldTableLayout = oldStyle ? oldStyle->tableLayout() : TAUTO; diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableRow.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableRow.cpp index dd44577..686bc3a 100644 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableRow.cpp +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableRow.cpp @@ -74,10 +74,10 @@ void RenderTableRow::updateBeforeAndAfterContent() void RenderTableRow::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { RenderBox::styleDidChange(diff, oldStyle); + propagateStyleToAnonymousChildren(); if (parent()) updateBeforeAndAfterContent(); - } void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild) @@ -90,7 +90,7 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild) RenderObject* last = beforeChild; if (!last) last = lastChild(); - if (last && last->isAnonymous() && last->isTableCell() && !isAfterContent(last) && !isBeforeContent(last)) { + if (last && last->isAnonymous() && last->isTableCell() && !last->isBeforeOrAfterContent()) { if (beforeChild == last) beforeChild = last->firstChild(); last->addChild(child, beforeChild); @@ -98,7 +98,7 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild) } // If beforeChild is inside an anonymous cell, insert into the cell. - if (last && !last->isTableCell() && last->parent() && last->parent()->isAnonymous() && !isAfterContent(last->parent()) && !isBeforeContent(last->parent())) { + if (last && !last->isTableCell() && last->parent() && last->parent()->isAnonymous() && !last->parent()->isBeforeOrAfterContent()) { last->parent()->addChild(child, beforeChild); return; } diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp index 3f84404..7d414a0 100644 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.cpp @@ -74,6 +74,12 @@ RenderTableSection::~RenderTableSection() clearGrid(); } +void RenderTableSection::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) +{ + RenderBox::styleDidChange(diff, oldStyle); + propagateStyleToAnonymousChildren(); +} + void RenderTableSection::destroy() { RenderTable* recalcTable = table(); @@ -96,7 +102,7 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild RenderObject* last = beforeChild; if (!last) last = lastChild(); - if (last && last->isAnonymous() && !isAfterContent(last) && !isBeforeContent(last)) { + if (last && last->isAnonymous() && !last->isBeforeOrAfterContent()) { if (beforeChild == last) beforeChild = last->firstChild(); last->addChild(child, beforeChild); @@ -108,7 +114,7 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild RenderObject* lastBox = last; while (lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableRow()) lastBox = lastBox->parent(); - if (lastBox && lastBox->isAnonymous() && !isAfterContent(lastBox) && !isBeforeContent(lastBox)) { + if (lastBox && lastBox->isAnonymous() && !lastBox->isBeforeOrAfterContent()) { lastBox->addChild(child, beforeChild); return; } diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h index cc969e8..db6edc2 100644 --- a/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h +++ b/src/3rdparty/webkit/Source/WebCore/rendering/RenderTableSection.h @@ -118,6 +118,9 @@ public: int getBaseline(int row) { return m_grid[row].baseline; } +protected: + virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle); + private: virtual RenderObjectChildList* virtualChildren() { return children(); } virtual const RenderObjectChildList* virtualChildren() const { return children(); } diff --git a/src/3rdparty/webkit/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp b/src/3rdparty/webkit/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp index 79e8e1e..db4027b 100644 --- a/src/3rdparty/webkit/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp +++ b/src/3rdparty/webkit/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp @@ -168,7 +168,7 @@ void RenderSVGResourceContainer::registerResource() const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end(); for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) { ASSERT((*it)->hasPendingResources()); - (*it)->setHasPendingResources(false); + (*it)->clearHasPendingResourcesIfPossible(); RenderObject* renderer = (*it)->renderer(); if (!renderer) continue; diff --git a/src/3rdparty/webkit/Source/WebCore/svg/SVGDocumentExtensions.cpp b/src/3rdparty/webkit/Source/WebCore/svg/SVGDocumentExtensions.cpp index d74f646..4b339ca 100644..100755 --- a/src/3rdparty/webkit/Source/WebCore/svg/SVGDocumentExtensions.cpp +++ b/src/3rdparty/webkit/Source/WebCore/svg/SVGDocumentExtensions.cpp @@ -227,7 +227,7 @@ void SVGDocumentExtensions::addPendingResource(const AtomicString& id, SVGStyled m_pendingResources.add(id, set); } - element->setHasPendingResources(true); + element->setHasPendingResources(); } bool SVGDocumentExtensions::hasPendingResources(const AtomicString& id) const @@ -238,6 +238,24 @@ bool SVGDocumentExtensions::hasPendingResources(const AtomicString& id) const return m_pendingResources.contains(id); } +bool SVGDocumentExtensions::isElementInPendingResources(SVGStyledElement* element) const +{ + ASSERT(element); + + if (m_pendingResources.isEmpty()) + return false; + + HashMap<AtomicString, SVGPendingElements*>::const_iterator end = m_pendingResources.end(); + for (HashMap<AtomicString, SVGPendingElements*>::const_iterator it = m_pendingResources.begin(); it != end; ++it) { + SVGPendingElements* elements = it->second; + ASSERT(elements); + + if (elements->contains(element)) + return true; + } + return false; +} + void SVGDocumentExtensions::removeElementFromPendingResources(SVGStyledElement* element) { ASSERT(element); @@ -245,8 +263,6 @@ void SVGDocumentExtensions::removeElementFromPendingResources(SVGStyledElement* if (m_pendingResources.isEmpty() || !element->hasPendingResources()) return; - element->setHasPendingResources(false); - Vector<AtomicString> toBeRemoved; HashMap<AtomicString, SVGPendingElements*>::iterator end = m_pendingResources.end(); for (HashMap<AtomicString, SVGPendingElements*>::iterator it = m_pendingResources.begin(); it != end; ++it) { @@ -259,6 +275,8 @@ void SVGDocumentExtensions::removeElementFromPendingResources(SVGStyledElement* toBeRemoved.append(it->first); } + element->clearHasPendingResourcesIfPossible(); + if (toBeRemoved.isEmpty()) return; diff --git a/src/3rdparty/webkit/Source/WebCore/svg/SVGDocumentExtensions.h b/src/3rdparty/webkit/Source/WebCore/svg/SVGDocumentExtensions.h index a66b066..8ad44f8 100644..100755 --- a/src/3rdparty/webkit/Source/WebCore/svg/SVGDocumentExtensions.h +++ b/src/3rdparty/webkit/Source/WebCore/svg/SVGDocumentExtensions.h @@ -81,6 +81,7 @@ public: // For instance, dynamically build gradients / patterns / clippers... void addPendingResource(const AtomicString& id, SVGStyledElement*); bool hasPendingResources(const AtomicString& id) const; + bool isElementInPendingResources(SVGStyledElement*) const; void removeElementFromPendingResources(SVGStyledElement*); PassOwnPtr<SVGPendingElements> removePendingResource(const AtomicString& id); }; diff --git a/src/3rdparty/webkit/Source/WebCore/svg/SVGStyledElement.cpp b/src/3rdparty/webkit/Source/WebCore/svg/SVGStyledElement.cpp index c1a6449..0693eb0 100644..100755 --- a/src/3rdparty/webkit/Source/WebCore/svg/SVGStyledElement.cpp +++ b/src/3rdparty/webkit/Source/WebCore/svg/SVGStyledElement.cpp @@ -380,7 +380,7 @@ void SVGStyledElement::insertedIntoDocument() for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) { ASSERT((*it)->hasPendingResources()); (*it)->buildPendingResource(); - (*it)->setHasPendingResources(false); + (*it)->clearHasPendingResourcesIfPossible(); } } @@ -453,9 +453,15 @@ bool SVGStyledElement::hasPendingResources() const return hasRareSVGData() && rareSVGData()->hasPendingResources(); } -void SVGStyledElement::setHasPendingResources(bool value) +void SVGStyledElement::setHasPendingResources() { - ensureRareSVGData()->setHasPendingResources(value); + ensureRareSVGData()->setHasPendingResources(true); +} + +void SVGStyledElement::clearHasPendingResourcesIfPossible() +{ + if (!document()->accessSVGExtensions()->isElementInPendingResources(this)) + ensureRareSVGData()->setHasPendingResources(false); } AffineTransform SVGStyledElement::localCoordinateSpaceTransform(SVGLocatable::CTMScope) const diff --git a/src/3rdparty/webkit/Source/WebCore/svg/SVGStyledElement.h b/src/3rdparty/webkit/Source/WebCore/svg/SVGStyledElement.h index f48513c..fdad347 100644..100755 --- a/src/3rdparty/webkit/Source/WebCore/svg/SVGStyledElement.h +++ b/src/3rdparty/webkit/Source/WebCore/svg/SVGStyledElement.h @@ -53,7 +53,8 @@ public: void setInstanceUpdatesBlocked(bool); bool hasPendingResources() const; - void setHasPendingResources(bool); + void setHasPendingResources(); + void clearHasPendingResourcesIfPossible(); AnimatedAttributeType animatedPropertyTypeForCSSProperty(const QualifiedName&); static bool isAnimatableCSSProperty(const QualifiedName&); diff --git a/src/3rdparty/webkit/Source/WebCore/svg/SVGUseElement.cpp b/src/3rdparty/webkit/Source/WebCore/svg/SVGUseElement.cpp index d8f9674..7de1f4c 100644 --- a/src/3rdparty/webkit/Source/WebCore/svg/SVGUseElement.cpp +++ b/src/3rdparty/webkit/Source/WebCore/svg/SVGUseElement.cpp @@ -172,11 +172,11 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end(); for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) { ASSERT((*it)->hasPendingResources()); - (*it)->setHasPendingResources(false); + (*it)->clearHasPendingResourcesIfPossible(); } m_resourceId = String(); - setHasPendingResources(false); + clearHasPendingResourcesIfPossible(); } invalidateShadowTree(); diff --git a/src/3rdparty/webkit/Source/WebKit/qt/ChangeLog b/src/3rdparty/webkit/Source/WebKit/qt/ChangeLog index 4758de0..32428f1 100644 --- a/src/3rdparty/webkit/Source/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/Source/WebKit/qt/ChangeLog @@ -1,3 +1,13 @@ +2011-09-06 Ademar de Souza Reis Jr. <ademar.reis@openbossa.org> + + [Qt][Symbian] REGRESSION[94105] DumpRenderTree.exe doesn't build on Symbian + https://bugs.webkit.org/show_bug.cgi?id=67644 + + Reviewed by Csaba Osztrogonác. + + * symbian/eabi/QtWebKitu.def: add missing entry for + FrameLoaderClientQt::dumpProgressFinishedCallback(bool) + 2011-08-31 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> [Qt] Unskip API test for load signals order diff --git a/src/3rdparty/webkit/Source/WebKit/qt/symbian/eabi/QtWebKitu.def b/src/3rdparty/webkit/Source/WebKit/qt/symbian/eabi/QtWebKitu.def index 0a1c6cb..b67d3f8 100644 --- a/src/3rdparty/webkit/Source/WebKit/qt/symbian/eabi/QtWebKitu.def +++ b/src/3rdparty/webkit/Source/WebKit/qt/symbian/eabi/QtWebKitu.def @@ -880,3 +880,4 @@ EXPORTS _ZN8QDRTNodeaSERKS_ @ 879 NONAME
_ZN23DumpRenderTreeSupportQt21injectInternalsObjectEP9QWebFrame @ 880 NONAME
_ZN23DumpRenderTreeSupportQt20resetInternalsObjectEP9QWebFrame @ 881 NONAME
+ _ZN23DumpRenderTreeSupportQt28dumpProgressFinishedCallbackEb @ 882 NONAME
diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index aeaa22c..6a40345 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -4,4 +4,4 @@ This is a snapshot of the Qt port of WebKit from and has the sha1 checksum - a2bd2bb1b19949c6807da38e25bfa7d210bb4b17 + 64cce100215c71575f19ca0b090c65fa97d4ba10 diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index f59f404..aaebec3 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -90,8 +90,8 @@ QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conve while (ch < end) { uint u = ch->unicode(); if (surrogate_high >= 0) { - if (u >= 0xdc00 && u < 0xe000) { - u = (surrogate_high - 0xd800)*0x400 + (u - 0xdc00) + 0x10000; + if (ch->isLowSurrogate()) { + u = QChar::surrogateToUcs4(surrogate_high, u); surrogate_high = -1; } else { // high surrogate without low @@ -101,13 +101,13 @@ QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conve surrogate_high = -1; continue; } - } else if (u >= 0xdc00 && u < 0xe000) { + } else if (ch->isLowSurrogate()) { // low surrogate without high *cursor = replacement; ++ch; ++invalid; continue; - } else if (u >= 0xd800 && u < 0xdc00) { + } else if (ch->isHighSurrogate()) { surrogate_high = u; ++ch; continue; diff --git a/src/corelib/concurrent/qfuturewatcher.cpp b/src/corelib/concurrent/qfuturewatcher.cpp index 0bef4a6..a70f56b 100644 --- a/src/corelib/concurrent/qfuturewatcher.cpp +++ b/src/corelib/concurrent/qfuturewatcher.cpp @@ -600,5 +600,8 @@ void QFutureWatcherBase::setPaused(bool) { } void QFutureWatcherBase::pause() { } void QFutureWatcherBase::resume() { } void QFutureWatcherBase::togglePaused() { } +bool QFutureWatcherBase::event(QEvent *) { return false; } +void QFutureWatcherBase::connectNotify(const char *) { } +void QFutureWatcherBase::disconnectNotify(const char *) { } #endif // QT_NO_QFUTURE diff --git a/src/corelib/concurrent/qtconcurrentfilter.h b/src/corelib/concurrent/qtconcurrentfilter.h index 4b9c4ae..d8c5f43 100644 --- a/src/corelib/concurrent/qtconcurrentfilter.h +++ b/src/corelib/concurrent/qtconcurrentfilter.h @@ -102,10 +102,9 @@ namespace QtConcurrent { namespace QtConcurrent { -template <typename Sequence, typename KeepFunctor, typename T, typename C, typename U> -ThreadEngineStarter<void> filterInternal(Sequence &sequence, KeepFunctor keep, T (C::*reduce)(U)) +template <typename Sequence, typename KeepFunctor, typename ReduceFunctor> +ThreadEngineStarter<void> filterInternal(Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce) { - typedef MemberFunctionWrapper1<T, C, U> ReduceFunctor; typedef typename Sequence::const_iterator Iterator; typedef FilterKernel<Sequence, KeepFunctor, ReduceFunctor> KernelType; return startThreadEngine(new KernelType(sequence, keep, reduce)); @@ -115,7 +114,7 @@ ThreadEngineStarter<void> filterInternal(Sequence &sequence, KeepFunctor keep, T template <typename Sequence, typename KeepFunctor> QFuture<void> filter(Sequence &sequence, KeepFunctor keep) { - return filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back); + return filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper()); } // filteredReduced() on sequences @@ -184,7 +183,7 @@ QFuture<typename qValueType<Iterator>::value_type> filtered(Iterator begin, Iter template <typename Sequence, typename KeepFunctor> void blockingFilter(Sequence &sequence, KeepFunctor keep) { - filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back).startBlocking(); + filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper()).startBlocking(); } // blocking filteredReduced() on sequences @@ -246,18 +245,17 @@ typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFiltered template <typename Sequence, typename KeepFunctor> Sequence blockingFiltered(const Sequence &sequence, KeepFunctor keep) { - return blockingFilteredReduced(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back, OrderedReduce); + return startFilteredReduced<Sequence>(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper(), OrderedReduce).startBlocking(); } // blocking filtered() on iterators template <typename OutputSequence, typename Iterator, typename KeepFunctor> OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor keep) { - return blockingFilteredReduced(begin, - end, - QtPrivate::createFunctionWrapper(keep), - &OutputSequence::push_back, - OrderedReduce); + return startFilteredReduced<OutputSequence>(begin, end, + QtPrivate::createFunctionWrapper(keep), + QtPrivate::PushBackWrapper(), + OrderedReduce).startBlocking(); } } // namespace QtConcurrent diff --git a/src/corelib/concurrent/qtconcurrentfunctionwrappers.h b/src/corelib/concurrent/qtconcurrentfunctionwrappers.h index 4bf2736..1e09221 100644 --- a/src/corelib/concurrent/qtconcurrentfunctionwrappers.h +++ b/src/corelib/concurrent/qtconcurrentfunctionwrappers.h @@ -195,6 +195,25 @@ QtConcurrent::ConstMemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func return QtConcurrent::ConstMemberFunctionWrapper<T, C>(func); } +struct PushBackWrapper +{ + typedef void result_type; + + template <class C, class U> + inline void operator()(C &c, const U &u) const + { + return c.push_back(u); + } + +#ifdef Q_COMPILER_RVALUE_REFS + template <class C, class U> + inline void operator()(C &c, U &&u) const + { + return c.push_back(u); + } +#endif +}; + template <typename Functor, bool foo = HasResultType<Functor>::Value> struct LazyResultType { typedef typename Functor::result_type Type; }; template <typename Functor> diff --git a/src/corelib/concurrent/qtconcurrentmap.h b/src/corelib/concurrent/qtconcurrentmap.h index 37a4143..166d5c8 100644 --- a/src/corelib/concurrent/qtconcurrentmap.h +++ b/src/corelib/concurrent/qtconcurrentmap.h @@ -271,7 +271,7 @@ OutputSequence blockingMapped(const InputSequence &sequence, MapFunctor map) return blockingMappedReduced<OutputSequence> (sequence, QtPrivate::createFunctionWrapper(map), - &OutputSequence::push_back, + QtPrivate::PushBackWrapper(), QtConcurrent::OrderedReduce); } @@ -282,7 +282,7 @@ typename QtPrivate::MapResultType<InputSequence, MapFunctor>::ResultType blockin return blockingMappedReduced<OutputSequence> (sequence, QtPrivate::createFunctionWrapper(map), - &OutputSequence::push_back, + QtPrivate::PushBackWrapper(), QtConcurrent::OrderedReduce); } @@ -293,7 +293,7 @@ Sequence blockingMapped(Iterator begin, Iterator end, MapFunctor map) return blockingMappedReduced<Sequence> (begin, end, QtPrivate::createFunctionWrapper(map), - &Sequence::push_back, + QtPrivate::PushBackWrapper(), QtConcurrent::OrderedReduce); } @@ -304,7 +304,7 @@ typename QtPrivate::MapResultType<Iterator, MapFunctor>::ResultType blockingMapp return blockingMappedReduced<OutputSequence> (begin, end, QtPrivate::createFunctionWrapper(map), - &OutputSequence::push_back, + QtPrivate::PushBackWrapper(), QtConcurrent::OrderedReduce); } diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 4974aef..03e0d1f 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2560,7 +2560,7 @@ will imply to use the layout direction set on the parent widget or QApplication. This has the same effect as QWidget::unsetLayoutDirection(). - When LayoutDirectoinAuto is used in conjunction with text layouting, it will imply that the text + When LayoutDirectionAuto is used in conjunction with text layouting, it will imply that the text directionality is determined from the content of the string to be layouted. \sa QApplication::setLayoutDirection(), QWidget::setLayoutDirection(), QTextOption::setTextDirection(), QString::isRightToLeft() diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index e411f8f..78993a0 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -118,5 +118,7 @@ win32 { } integrity { SOURCES += io/qfsfileengine_unix.cpp \ - io/qfsfileengine_iterator_unix.cpp + io/qfsfileengine_iterator.cpp \ + io/qfilesystemengine_unix.cpp \ + io/qfilesystemiterator_unix.cpp } diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index d9086c1..48b9358 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -198,7 +198,7 @@ inline void QDirPrivate::resolveAbsoluteEntry() const QString absoluteName; if (fileEngine.isNull()) { - if (!dirEntry.isRelative()) { + if (!dirEntry.isRelative() && dirEntry.isClean()) { absoluteDirEntry = dirEntry; return; } @@ -1638,8 +1638,19 @@ bool QDir::operator==(const QDir &dir) const if (d->dirEntry.filePath() == other->dirEntry.filePath()) return true; - // Fallback to expensive canonical path computation - return canonicalPath().compare(dir.canonicalPath(), sensitive) == 0; + if (exists()) { + if (!dir.exists()) + return false; //can't be equal if only one exists + // Both exist, fallback to expensive canonical path computation + return canonicalPath().compare(dir.canonicalPath(), sensitive) == 0; + } else { + if (dir.exists()) + return false; //can't be equal if only one exists + // Neither exists, compare absolute paths rather than canonical (which would be empty strings) + d->resolveAbsoluteEntry(); + other->resolveAbsoluteEntry(); + return d->absoluteDirEntry.filePath().compare(other->absoluteDirEntry.filePath(), sensitive) == 0; + } } return false; } @@ -1861,7 +1872,10 @@ QString QDir::currentPath() Under non-Windows operating systems the \c HOME environment variable is used if it exists, otherwise the path returned by the - rootPath(). On Symbian always the same as the path returned by the rootPath(). + rootPath(). + + On Symbian this typically returns "c:/data", + i.e. the same as native PathInfo::PhoneMemoryRootPath(). \sa home(), currentPath(), rootPath(), tempPath() */ @@ -1925,9 +1939,8 @@ QString QDir::tempPath() /*! Returns the absolute path of the root directory. - For Unix operating systems this returns "/". For Windows file - systems this normally returns "c:/". On Symbian this typically returns - "c:/data", i.e. the same as native PathInfo::PhoneMemoryRootPath(). + For Unix operating systems this returns "/". For Windows and Symbian file + systems this normally returns "c:/". I.E. the root of the system drive. \sa root(), drives(), currentPath(), homePath(), tempPath() */ diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 18c52cb..c8c1dfd 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -114,9 +114,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) { QString orig = entry.filePath(); const bool isAbsolute = entry.isAbsolute(); - const bool isDirty = (orig.contains(QLatin1String("/../")) || orig.contains(QLatin1String("/./")) || - orig.contains(QLatin1String("//")) || - orig.endsWith(QLatin1String("/..")) || orig.endsWith(QLatin1String("/."))); + const bool isDirty = !entry.isClean(); if (isAbsolute && !isDirty) return entry; diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index b0ebfbd..b1b5e7e 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -223,7 +223,7 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, //static QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) { - if (entry.isAbsolute()) + if (entry.isAbsolute() && entry.isClean()) return entry; QByteArray orig = entry.nativeFilePath(); @@ -264,12 +264,14 @@ QString QFileSystemEngine::resolveUserName(uint userId) #endif struct passwd *pw = 0; +#if !defined(Q_OS_INTEGRITY) #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) struct passwd entry; getpwuid_r(userId, &entry, buf.data(), buf.size(), &pw); #else pw = getpwuid(userId); #endif +#endif if (pw) return QFile::decodeName(QByteArray(pw->pw_name)); return QString(); @@ -286,6 +288,7 @@ QString QFileSystemEngine::resolveGroupName(uint groupId) #endif struct group *gr = 0; +#if !defined(Q_OS_INTEGRITY) #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) size_max = sysconf(_SC_GETGR_R_SIZE_MAX); if (size_max == -1) @@ -305,6 +308,7 @@ QString QFileSystemEngine::resolveGroupName(uint groupId) #else gr = getgrgid(groupId); #endif +#endif if (gr) return QFile::decodeName(QByteArray(gr->gr_name)); return QString(); diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 764ee6d..031d64b 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -508,11 +508,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) if (!entry.isRelative()) { #if !defined(Q_OS_WINCE) - if (entry.isAbsolute() - && !entry.filePath().contains(QLatin1String("/../")) - && !entry.filePath().contains(QLatin1String("/./")) - && !entry.filePath().endsWith(QLatin1String("/..")) - && !entry.filePath().endsWith(QLatin1String("/."))) { + if (entry.isAbsolute() && entry.isClean()) { ret = entry.filePath(); } else { ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(entry.filePath())); diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index bb7cb4e..2f37542 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -380,4 +380,35 @@ void QFileSystemEntry::findFileNameSeparators() const } } +bool QFileSystemEntry::isClean() const +{ + resolveFilePath(); + int dots = 0; + bool dotok = true; // checking for ".." or "." starts to relative paths + bool slashok = true; + for (QString::const_iterator iter = m_filePath.constBegin(); iter != m_filePath.constEnd(); iter++) { + if (*iter == QLatin1Char('/')) { + if (dots == 1 || dots == 2) + return false; // path contains "./" or "../" + if (!slashok) + return false; // path contains "//" + dots = 0; + dotok = true; + slashok = false; + } else if (dotok) { + slashok = true; + if (*iter == QLatin1Char('.')) { + dots++; + if (dots > 2) + dotok = false; + } else { + //path element contains a character other than '.', it's clean + dots = 0; + dotok = false; + } + } + } + return (dots != 1 && dots != 2); // clean if path doesn't end in . or .. +} + QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 34b083a..8d524c0 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -91,6 +91,7 @@ public: QString completeSuffix() const; bool isAbsolute() const; bool isRelative() const; + bool isClean() const; #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) bool isDriveRoot() const; diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index e1f3123..dd4c40f 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -120,9 +120,12 @@ void QFSFileEnginePrivate::init() openMode = QIODevice::NotOpen; fd = -1; fh = 0; -#if defined (Q_OS_SYMBIAN) && !defined(QT_SYMBIAN_USE_NATIVE_FILEMAP) +#if defined (Q_OS_SYMBIAN) + symbianFilePos = 0; +#if !defined(QT_SYMBIAN_USE_NATIVE_FILEMAP) fileHandleForMaps = -1; #endif +#endif lastIOCommand = IOFlushCommand; lastFlushFailed = false; closeFileHandle = false; diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index d35d845..ab8cc39 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -66,13 +66,12 @@ #ifndef QT_NO_QOBJECT #include "qcoreapplication.h" +#endif #ifdef Q_OS_WIN // for homedirpath reading from registry #include "qt_windows.h" #include <private/qsystemlibrary_p.h> - -#endif // Q_OS_WIN -#endif // QT_NO_QOBJECT +#endif #ifdef Q_OS_VXWORKS # include <ioLib.h> @@ -1024,9 +1023,6 @@ static QString windowsConfigPath(int type) { QString result; -#ifndef QT_NO_QOBJECT - // We can't use QLibrary if there is QT_NO_QOBJECT is defined - // This only happens when bootstrapping qmake. #ifndef Q_OS_WINCE QSystemLibrary library(QLatin1String("shell32")); #else @@ -1040,8 +1036,6 @@ static QString windowsConfigPath(int type) result = QString::fromWCharArray(path); } -#endif // QT_NO_QOBJECT - if (result.isEmpty()) { switch (type) { #ifndef Q_OS_WINCE @@ -1114,11 +1108,11 @@ static void initDefaultPaths(QMutexLocker *locker) userPath += QLatin1String(".config"); #endif } else if (*env == '/') { - userPath = QLatin1String(env); + userPath = QFile::decodeName(env); } else { userPath = homePath; userPath += QLatin1Char('/'); - userPath += QLatin1String(env); + userPath += QFile::decodeName(env); } userPath += QLatin1Char('/'); diff --git a/src/corelib/kernel/qcore_symbian_p.cpp b/src/corelib/kernel/qcore_symbian_p.cpp index 04acfb0..57ae2af 100644 --- a/src/corelib/kernel/qcore_symbian_p.cpp +++ b/src/corelib/kernel/qcore_symbian_p.cpp @@ -45,6 +45,7 @@ #include "qcore_symbian_p.h" #include <string> #include <in_sock.h> +#include "qdebug.h" QT_BEGIN_NAMESPACE @@ -115,6 +116,24 @@ public: QS60RFsSession() { qt_symbian_throwIfError(iFs.Connect()); qt_symbian_throwIfError(iFs.ShareProtected()); + //BC with 4.7: create private path on system drive + TInt sysdrive = iFs.GetSystemDrive(); + TInt err = iFs.CreatePrivatePath(sysdrive); + if (err != KErrNone && err != KErrAlreadyExists) + qWarning("Failed to create private path on system drive."); + //BC with 4.7: set working directory to same drive as application + TFileName pfn = RProcess().FileName(); + TInt drive; + if (pfn.Length() > 0 && iFs.CharToDrive(pfn[0], drive) == KErrNone) { + // for system drive or rom based apps, leave the path on system drive + if (drive != sysdrive && drive != EDriveZ) { + err = iFs.CreatePrivatePath(drive); + if (err == KErrNone || err == KErrAlreadyExists) + iFs.SetSessionToPrivate(drive); + else + qWarning("Failed to create private path on application drive."); + } + } } ~QS60RFsSession() { diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 18a5eae..c4a9e40 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -273,6 +273,29 @@ bool QCoreApplicationPrivate::is_app_closing = false; // initialized in qcoreapplication and in qtextstream autotest when setlocale is called. Q_CORE_EXPORT bool qt_locale_initialized = false; +#ifdef Q_OS_SYMBIAN +// The global QSettings needs to be cleaned where cleanup stack is available, which is not +// normally the case when global static destructors are run. +// Declare a custom QGlobalStaticDeleter for QSettings to handle that case. +template<> +class QGlobalStaticDeleter<QSettings> +{ +public: + QGlobalStatic<QSettings> &globalStatic; + QGlobalStaticDeleter(QGlobalStatic<QSettings> &_globalStatic) + : globalStatic(_globalStatic) + { } + + inline ~QGlobalStaticDeleter() + { + CTrapCleanup *cleanup = CTrapCleanup::New(); + delete globalStatic.pointer; + delete cleanup; + globalStatic.pointer = 0; + globalStatic.destroyed = true; + } +}; +#endif /* Create an instance of Trolltech.conf. This ensures that the settings will not @@ -1968,12 +1991,6 @@ QString QCoreApplication::applicationDirPath() appPath = qt_TDesC2QString(privatePath); appPath.prepend(QLatin1Char(':')).prepend(qDriveChar); - // Create the appPath if it doesn't exist. Non-existing appPath will cause - // Platform Security violations later on if the app doesn't have AllFiles capability. - err = fs.CreatePrivatePath(drive); - if (err != KErrNone) - qWarning("QCoreApplication::applicationDirPath: Failed to create private path."); - d->cachedApplicationDirPath = QFileInfo(appPath).path(); } #else diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index bbb64e4..9f9ea1a 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -198,7 +198,7 @@ QPluginLoader::~QPluginLoader() */ QObject *QPluginLoader::instance() { - if (!isLoaded() && !load()) + if (!load()) return 0; if (!d->inst && d->instance) d->inst = d->instance(); diff --git a/src/corelib/thread/qthread_symbian.cpp b/src/corelib/thread/qthread_symbian.cpp index 46339a6..2ea1b44 100644 --- a/src/corelib/thread/qthread_symbian.cpp +++ b/src/corelib/thread/qthread_symbian.cpp @@ -324,13 +324,14 @@ void *QThreadPrivate::start(void *arg) data->threadId = QThread::currentThreadId(); set_thread_data(data); + CTrapCleanup *cleanup = CTrapCleanup::New(); + q_check_ptr(cleanup); + { QMutexLocker locker(&thr->d_func()->mutex); data->quitNow = thr->d_func()->exited; } - CTrapCleanup *cleanup = CTrapCleanup::New(); - // ### TODO: allow the user to create a custom event dispatcher createEventDispatcher(data); diff --git a/src/corelib/tools/qcache.h b/src/corelib/tools/qcache.h index 16861c9..2408cd3 100644 --- a/src/corelib/tools/qcache.h +++ b/src/corelib/tools/qcache.h @@ -205,8 +205,7 @@ void QCache<Key,T>::trim(int m) while (n && total > m) { Node *u = n; n = n->p; - if (qIsDetached(*u->t)) - unlink(*u); + unlink(*u); } } diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index fd2dc45..ca6c496 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -1532,7 +1532,7 @@ bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) d->handleMouseMoveEvent(&mouseEvent); break; case QEvent::GraphicsSceneMousePress: - if (d->pressed) // we are already pressed - this is a delayed replay + if (d->pressed && !event->spontaneous()) // we are already pressed - this is a delayed replay return false; d->handleMousePressEvent(&mouseEvent); diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index e53472d..023737d 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1066,6 +1066,8 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m highlightEnd = highlightRangeEnd; } + bool strictHighlightRange = haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange; + if (snapMode != QDeclarativeGridView::NoSnap) { qreal tempPosition = isRightToLeftTopToBottom() ? -position()-size() : position(); if (snapMode == QDeclarativeGridView::SnapOneRow && moveReason == Mouse) { @@ -1083,7 +1085,7 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m FxGridItem *topItem = snapItemAt(tempPosition+highlightStart); FxGridItem *bottomItem = snapItemAt(tempPosition+highlightEnd); qreal pos; - if (topItem && bottomItem && haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { + if (topItem && bottomItem && strictHighlightRange) { qreal topPos = qMin(topItem->rowPos() - highlightStart, -maxExtent); qreal bottomPos = qMax(bottomItem->rowPos() - highlightEnd, -minExtent); pos = qAbs(data.move + topPos) < qAbs(data.move + bottomPos) ? topPos : bottomPos; @@ -1091,7 +1093,7 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m qreal headerPos = 0; if (header) headerPos = isRightToLeftTopToBottom() ? header->rowPos() + cellWidth - headerSize() : header->rowPos(); - if (topItem->index == 0 && header && tempPosition+highlightStart < headerPos+headerSize()/2) { + if (topItem->index == 0 && header && tempPosition+highlightStart < headerPos+headerSize()/2 && !strictHighlightRange) { pos = isRightToLeftTopToBottom() ? - headerPos + highlightStart - size() : headerPos - highlightStart; } else { if (isRightToLeftTopToBottom()) diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index f0fc96b..6a91e5f 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1295,6 +1295,7 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m correctFlick = false; fixupMode = moveReason == Mouse ? fixupMode : Immediate; + bool strictHighlightRange = haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange; qreal highlightStart; qreal highlightEnd; @@ -1327,9 +1328,9 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m FxListItem *topItem = snapItemAt(tempPosition+highlightStart); FxListItem *bottomItem = snapItemAt(tempPosition+highlightEnd); qreal pos; - bool isInBounds = -position() > maxExtent && -position() < minExtent; + bool isInBounds = -position() > maxExtent && -position() <= minExtent; if (topItem && isInBounds) { - if (topItem->index == 0 && header && tempPosition+highlightStart < header->position()+header->size()/2) { + if (topItem->index == 0 && header && tempPosition+highlightStart < header->position()+header->size()/2 && !strictHighlightRange) { pos = isRightToLeft() ? - header->position() + highlightStart - size() : header->position() - highlightStart; } else { if (isRightToLeft()) @@ -1358,7 +1359,7 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m } vTime = timeline.time(); } - } else if (currentItem && haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange + } else if (currentItem && strictHighlightRange && moveReason != QDeclarativeListViewPrivate::SetIndex) { updateHighlight(); qreal pos = currentItem->itemPosition(); diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index 6a9cf19..1e30e78 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -1712,7 +1712,9 @@ void QDeclarativeTextEdit::updateSize() setImplicitWidth(newWidth); else if (d->requireImplicitWidth) setImplicitWidth(naturalWidth); - qreal newHeight = d->document->isEmpty() ? fm.height() : (int)d->document->size().height(); + qreal newHeight = d->document->size().height(); + if (newHeight == 0) + newHeight = fm.height(); setImplicitHeight(newHeight); d->paintedSize = QSize(newWidth, newHeight); diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index 689cd00..9359196 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -254,6 +254,8 @@ QDeclarativeBinding::createBinding(Identifier id, QObject *obj, QDeclarativeCont cdata = typeData->compiledData(); } QDeclarativeBinding *rv = cdata ? new QDeclarativeBinding((void*)cdata->datas.at(id).constData(), cdata, obj, ctxtdata, url, lineNumber, parent) : 0; + if (cdata) + cdata->release(); if (typeData) typeData->release(); return rv; diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp index 51ffc10..72a3e53 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings.cpp +++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp @@ -235,6 +235,7 @@ public: void run(Binding *, QDeclarativePropertyPrivate::WriteFlags flags); const char *programData; + QDeclarativeRefCount *dataRef; Binding *m_bindings; quint32 *m_signalTable; @@ -267,7 +268,7 @@ public: }; QDeclarativeCompiledBindingsPrivate::QDeclarativeCompiledBindingsPrivate() -: subscriptions(0), identifiers(0) +: subscriptions(0), identifiers(0), programData(0), dataRef(0), m_bindings(0), m_signalTable(0) { } @@ -275,11 +276,16 @@ QDeclarativeCompiledBindingsPrivate::~QDeclarativeCompiledBindingsPrivate() { delete [] subscriptions; subscriptions = 0; delete [] identifiers; identifiers = 0; + if (dataRef) { + dataRef->release(); + dataRef = 0; + } } int QDeclarativeCompiledBindingsPrivate::methodCount = -1; -QDeclarativeCompiledBindings::QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context) +QDeclarativeCompiledBindings::QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context, + QDeclarativeRefCount *dataRef) : QObject(*(new QDeclarativeCompiledBindingsPrivate)) { Q_D(QDeclarativeCompiledBindings); @@ -288,6 +294,8 @@ QDeclarativeCompiledBindings::QDeclarativeCompiledBindings(const char *program, d->methodCount = QDeclarativeCompiledBindings::staticMetaObject.methodCount(); d->programData = program; + d->dataRef = dataRef; + if (d->dataRef) d->dataRef->addref(); d->init(); diff --git a/src/declarative/qml/qdeclarativecompiledbindings_p.h b/src/declarative/qml/qdeclarativecompiledbindings_p.h index e7b6937..8ec0ac3 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings_p.h +++ b/src/declarative/qml/qdeclarativecompiledbindings_p.h @@ -95,7 +95,7 @@ class QDeclarativeCompiledBindingsPrivate; class QDeclarativeCompiledBindings : public QObject, public QDeclarativeAbstractExpression, public QDeclarativeRefCount { public: - QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context); + QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context, QDeclarativeRefCount *); virtual ~QDeclarativeCompiledBindings(); QDeclarativeAbstractBinding *configBinding(int index, QObject *target, QObject *scope, int property); diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index a23f89d..8cf97d2 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -209,7 +209,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack, if (instr.init.contextCache != -1) ctxt->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache)); if (instr.init.compiledBinding != -1) - ctxt->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt); + ctxt->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt, comp); } break; diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp index 9f56ccb..ee3d06b 100644 --- a/src/declarative/util/qdeclarativestate.cpp +++ b/src/declarative/util/qdeclarativestate.cpp @@ -173,6 +173,18 @@ QDeclarativeState::~QDeclarativeState() Q_D(QDeclarativeState); if (d->group) d->group->removeState(this); + + /* + destroying an active state does not return us to the + base state, so we need to clean up our revert list to + prevent leaks. In the future we may want to redconsider + this overall architecture. + */ + for (int i = 0; i < d->revertList.count(); ++i) { + if (d->revertList.at(i).binding()) { + d->revertList.at(i).binding()->destroy(); + } + } } /*! diff --git a/src/gui/accessible/qaccessible_win.cpp b/src/gui/accessible/qaccessible_win.cpp index caabae5..1fd1bfd 100644 --- a/src/gui/accessible/qaccessible_win.cpp +++ b/src/gui/accessible/qaccessible_win.cpp @@ -1316,7 +1316,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accState(VARIANT varID, VARIAN (*pvarState).vt = VT_I4; AccessibleElement elem(varID.lVal, accessible); - (*pvarState).lVal = elem.iface ? elem.iface->state(elem.entry) : 0; + (*pvarState).lVal = elem.iface ? elem.iface->state(elem.entry) : State(Normal); return S_OK; } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index eaa8ac2..deda3ff 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -2966,11 +2966,12 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint AnchorData *ad = variables.at(i); ad->sizeAtPreferred = ad->result - g_offset; } - - // Make sure we delete the simplex solver -before- we delete the - // constraints used by it. - delete simplex; } + + // Make sure we delete the simplex solver -before- we delete the + // constraints used by it. + delete simplex; + // Delete constraints and variables we created. qDeleteAll(preferredConstraints); qDeleteAll(preferredVariables); diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 0c218fc..9092593 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -5378,11 +5378,9 @@ void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively() { QGraphicsItemPrivate *itemPrivate = this; do { - if (itemPrivate->graphicsEffect) { + if (itemPrivate->graphicsEffect && !itemPrivate->updateDueToGraphicsEffect) { itemPrivate->notifyInvalidated = 1; - - if (!itemPrivate->updateDueToGraphicsEffect) - static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache(); + static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache(); } } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); } @@ -5690,21 +5688,27 @@ void QGraphicsItem::update(const QRectF &rect) d_ptr->invalidateParentGraphicsEffectsRecursively(); #endif //QT_NO_GRAPHICSEFFECT - if (CacheMode(d_ptr->cacheMode) != NoCache) { - // Invalidate cache. - QGraphicsItemCache *cache = d_ptr->extraItemCache(); - if (!cache->allExposed) { - if (rect.isNull()) { - cache->allExposed = true; - cache->exposed.clear(); - } else { - cache->exposed.append(rect); +#ifndef QT_NO_GRAPHICSEFFECT + if (!d_ptr->updateDueToGraphicsEffect) { +#endif + if (CacheMode(d_ptr->cacheMode) != NoCache) { + // Invalidate cache. + QGraphicsItemCache *cache = d_ptr->extraItemCache(); + if (!cache->allExposed) { + if (rect.isNull()) { + cache->allExposed = true; + cache->exposed.clear(); + } else { + cache->exposed.append(rect); + } } + // Only invalidate cache; item is already dirty. + if (d_ptr->fullUpdatePending) + return; } - // Only invalidate cache; item is already dirty. - if (d_ptr->fullUpdatePending) - return; +#ifndef QT_NO_GRAPHICSEFFECT } +#endif if (d_ptr->scene) d_ptr->scene->d_func()->markDirty(this, rect); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 1551944..867880c 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -3504,7 +3504,9 @@ bool QGraphicsScene::event(QEvent *event) } break; case QEvent::WindowDeactivate: - if (!--d->activationRefCount) { + if (d->activationRefCount > 0) + --d->activationRefCount; + if (!d->activationRefCount) { if (d->activePanel) { // Deactivate the active panel (but keep it so we can // reactivate it later). diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 965b1b34..c275968 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -152,7 +152,7 @@ QT_BEGIN_NAMESPACE \row \o Qt::WA_SetPalette \o Set by setPalette(). \row \o Qt::WA_SetFont - \o Set by setPalette(). + \o Set by setFont(). \row \o Qt::WA_WindowPropagation \o Enables propagation to window widgets. \endtable @@ -1173,6 +1173,12 @@ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant & QApplication::sendEvent(this, &event); break; } + case ItemChildAddedChange: { + QGraphicsItem *child = qVariantValue<QGraphicsItem *>(value); + if (child->isWidget()) + static_cast<QGraphicsWidget *>(child)->d_func()->resolveLayoutDirection(); + break; + } default: break; } @@ -1668,7 +1674,7 @@ void QGraphicsWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) /*! This event handler, for \a event, can be reimplemented in a subclass to - receive notifications for Qt::GrabMouse events. + receive notifications for QEvent::GrabMouse events. \sa grabMouse(), grabKeyboard() */ @@ -1679,7 +1685,7 @@ void QGraphicsWidget::grabMouseEvent(QEvent *event) /*! This event handler, for \a event, can be reimplemented in a subclass to - receive notifications for Qt::UngrabMouse events. + receive notifications for QEvent::UngrabMouse events. \sa ungrabMouse(), ungrabKeyboard() */ @@ -1690,7 +1696,7 @@ void QGraphicsWidget::ungrabMouseEvent(QEvent *event) /*! This event handler, for \a event, can be reimplemented in a subclass to - receive notifications for Qt::GrabKeyboard events. + receive notifications for QEvent::GrabKeyboard events. \sa grabKeyboard(), grabMouse() */ @@ -1701,7 +1707,7 @@ void QGraphicsWidget::grabKeyboardEvent(QEvent *event) /*! This event handler, for \a event, can be reimplemented in a subclass to - receive notifications for Qt::UngrabKeyboard events. + receive notifications for QEvent::UngrabKeyboard events. \sa ungrabKeyboard(), ungrabMouse() */ diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h index 8c30838..8ef9726 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_p.h +++ b/src/gui/inputmethod/qcoefepinputcontext_p.h @@ -63,13 +63,36 @@ #include <fepbase.h> #include <aknedsts.h> +#include <eikccpu.h> QT_BEGIN_NAMESPACE +class QCoeFepInputMaskHandler +{ +public: + QCoeFepInputMaskHandler(const QString &mask); + ~QCoeFepInputMaskHandler(); + bool canPasteClipboard(const QString &text); +private: + bool isValidInput(QChar key, QChar mask) const; +private: + struct MaskInputData { + enum Casemode { NoCaseMode, Upper, Lower }; + QChar maskChar; + bool separator; + Casemode caseMode; + }; + int m_maxLength; + QChar m_blank; + MaskInputData *m_maskData; +}; + class Q_AUTOTEST_EXPORT QCoeFepInputContext : public QInputContext, public MCoeFepAwareTextEditor, public MCoeFepAwareTextEditor_Extension1, - public MObjectProvider + public MObjectProvider, + public MEikCcpuEditor + { Q_OBJECT @@ -135,6 +158,25 @@ private: void DoCommitFepInlineEditL(); MCoeFepAwareTextEditor_Extension1* Extension1(TBool& aSetToTrue); void ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType); + void enableSymbianCcpuSupport(); + void changeCBA(bool showCopyAndOrPaste); + void copyOrCutTextToClipboard(const char *operation); + + //From MEikCcpuEditor interface +public: + TBool CcpuIsFocused() const; + TBool CcpuCanCut() const; + void CcpuCutL(); + TBool CcpuCanCopy() const; + void CcpuCopyL(); + TBool CcpuCanPaste() const; + void CcpuPasteL(); + TBool CcpuCanUndo() const; + void CcpuUndoL(); + +private slots: + void copy(); + void paste(); // From MCoeFepAwareTextEditor_Extension1 public: @@ -167,6 +209,12 @@ private: Qt::WindowStates m_splitViewPreviousWindowStates; QRectF m_transformation; + CAknCcpuSupport *m_ccpu; + QAction *m_copyAction; + QAction *m_pasteAction; + QPointer<QWidget> m_lastFocusedEditor; + QPointer<QObject> m_lastFocusedObject; + friend class tst_QInputContext; }; diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 87c4045..e7084ac 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -57,6 +57,21 @@ #include <e32property.h> #include <limits.h> + +#include <eikccpu.h> +#include <aknedsts.h> +#include <coeinput.h> +#include <w32std.h> +#include <akndiscreetpopup.h> + +#include <qtextedit.h> +#include <qplaintextedit.h> +#include <qlineedit.h> +#include <qclipboard.h> +#include <qvalidator.h> +#include <qgraphicsproxywidget.h> +#include <qgraphicsitem.h> + // You only find these enumerations on SDK 5 onwards, so we need to provide our own // to remain compatible with older releases. They won't be called by pre-5.0 SDKs. @@ -79,8 +94,253 @@ #define QT_EPSUidAknFep 0x100056de #define QT_EAknFepTouchInputActive 0x00000004 +_LIT(KAvkonResourceFile, "z:\\resource\\avkon.rsc" ); + QT_BEGIN_NAMESPACE +static QWidget* getFocusedChild(const QList<QObject*>& objectList) +{ + for (int j = 0; j < objectList.count(); j++) { + if (QWidget* ow = qobject_cast<QWidget *>(objectList[j])) { + if (ow->hasFocus()) { + return ow; + } else { + if (QWidget* rw = getFocusedChild(ow->children())) + return rw; + } + } + } + return 0; +} + +// A generic method for invoking "cut", "copy", and "paste" slots on editor +// All supported editors are expected to have these. +static bool ccpuInvokeSlot(QObject *obj, QObject *focusObject, const char *member) +{ + QObject *invokeTarget = obj; + if (focusObject) + invokeTarget = focusObject; + + return QMetaObject::invokeMethod(invokeTarget, member, Qt::DirectConnection); +} + +// focusObject is used to return a pointer to focused graphics object, if any +static QWidget *getQWidgetFromQGraphicsView(QWidget *widget, QObject **focusObject = 0) +{ + if (focusObject) + *focusObject = 0; + + if (!widget) + return 0; + + if (QGraphicsView* qgv = qobject_cast<QGraphicsView *>(widget)) { + QGraphicsItem *focusItem = 0; + if (qgv->scene()) + focusItem = qgv->scene()->focusItem(); + if (focusItem) { + if (focusObject) + *focusObject = focusItem->toGraphicsObject(); + if (QGraphicsProxyWidget* const qgpw = qgraphicsitem_cast<QGraphicsProxyWidget* const>(focusItem)) { + if (QWidget* w = qgpw->widget()) { + if (w->layout()) { + if (QWidget* rw = getFocusedChild(w->children())) + return rw; + } else { + return w; + } + } + } + } + } + return widget; +} + +QCoeFepInputMaskHandler::QCoeFepInputMaskHandler(const QString &mask) +{ + QString inputMask; + int delimiter = mask.indexOf(QLatin1Char(';')); + if (mask.isEmpty() || delimiter == 0) + return; + + if (delimiter == -1) { + m_blank = QLatin1Char(' '); + inputMask = mask; + } else { + inputMask = mask.left(delimiter); + m_blank = (delimiter + 1 < mask.length()) ? mask[delimiter + 1] : QLatin1Char(' '); + } + + // Calculate m_maxLength / m_maskData length + m_maxLength = 0; + QChar c = 0; + for (int i = 0; i < inputMask.length(); i++) { + c = inputMask.at(i); + if (i > 0 && inputMask.at(i - 1) == QLatin1Char('\\')) { + m_maxLength++; + continue; + } + if (c != QLatin1Char('\\') && c != QLatin1Char('!') + && c != QLatin1Char('<') && c != QLatin1Char('>') + && c != QLatin1Char('{') && c != QLatin1Char('}') + && c != QLatin1Char('[') && c != QLatin1Char(']')) { + m_maxLength++; + } + } + + m_maskData = new MaskInputData[m_maxLength]; + + MaskInputData::Casemode m = MaskInputData::NoCaseMode; + c = 0; + bool s = false; + bool escape = false; + int index = 0; + for (int i = 0; i < inputMask.length(); i++) { + c = inputMask.at(i); + if (escape) { + s = true; + m_maskData[index].maskChar = c; + m_maskData[index].separator = s; + m_maskData[index].caseMode = m; + index++; + escape = false; + } else if (c == QLatin1Char('<')) { + m = MaskInputData::Lower; + } else if (c == QLatin1Char('>')) { + m = MaskInputData::Upper; + } else if (c == QLatin1Char('!')) { + m = MaskInputData::NoCaseMode; + } else if (c != QLatin1Char('{') && c != QLatin1Char('}') && c != QLatin1Char('[') && c != QLatin1Char(']')) { + switch (c.unicode()) { + case 'A': + case 'a': + case 'N': + case 'n': + case 'X': + case 'x': + case '9': + case '0': + case 'D': + case 'd': + case '#': + case 'H': + case 'h': + case 'B': + case 'b': + s = false; + break; + case '\\': + escape = true; + break; + default: + s = true; + break; + } + + if (!escape) { + m_maskData[index].maskChar = c; + m_maskData[index].separator = s; + m_maskData[index].caseMode = m; + index++; + } + } + } +} + +QCoeFepInputMaskHandler::~QCoeFepInputMaskHandler() +{ + if (m_maskData) + delete[] m_maskData; +} + +bool QCoeFepInputMaskHandler::canPasteClipboard(const QString &text) +{ + if (!m_maskData) + return true; + + if (text.length() > m_maxLength) + return false; + int limit = qMin(m_maxLength, text.length()); + for (int i = 0; i < limit; ++i) { + if (m_maskData[i].separator) { + if (text.at(i) != m_maskData[i].maskChar) + return false; + } else { + if (!isValidInput(text.at(i), m_maskData[i].maskChar)) + return false; + } + } + return true; +} + +bool QCoeFepInputMaskHandler::isValidInput(QChar key, QChar mask) const +{ + switch (mask.unicode()) { + case 'A': + if (key.isLetter()) + return true; + break; + case 'a': + if (key.isLetter() || key == m_blank) + return true; + break; + case 'N': + if (key.isLetterOrNumber()) + return true; + break; + case 'n': + if (key.isLetterOrNumber() || key == m_blank) + return true; + break; + case 'X': + if (key.isPrint()) + return true; + break; + case 'x': + if (key.isPrint() || key == m_blank) + return true; + break; + case '9': + if (key.isNumber()) + return true; + break; + case '0': + if (key.isNumber() || key == m_blank) + return true; + break; + case 'D': + if (key.isNumber() && key.digitValue() > 0) + return true; + break; + case 'd': + if ((key.isNumber() && key.digitValue() > 0) || key == m_blank) + return true; + break; + case '#': + if (key.isNumber() || key == QLatin1Char('+') || key == QLatin1Char('-') || key == m_blank) + return true; + break; + case 'B': + if (key == QLatin1Char('0') || key == QLatin1Char('1')) + return true; + break; + case 'b': + if (key == QLatin1Char('0') || key == QLatin1Char('1') || key == m_blank) + return true; + break; + case 'H': + if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F'))) + return true; + break; + case 'h': + if (key.isNumber() || (key >= QLatin1Char('a') && key <= QLatin1Char('f')) || (key >= QLatin1Char('A') && key <= QLatin1Char('F')) || key == m_blank) + return true; + break; + default: + break; + } + return false; +} + Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable) { S60->partial_keyboard = enable; @@ -116,7 +376,8 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent) m_pointerHandler(0), m_hasTempPreeditString(false), m_splitViewResizeBy(0), - m_splitViewPreviousWindowStates(Qt::WindowNoState) + m_splitViewPreviousWindowStates(Qt::WindowNoState), + m_ccpu(0) { m_fepState->SetObjectProvider(this); int defaultFlags = EAknEditorFlagDefault; @@ -133,6 +394,29 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent) m_fepState->SetPermittedCases( EAknEditorAllCaseModes ); m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG); m_fepState->SetNumericKeymap(EAknEditorAlphanumericNumberModeKeymap); + enableSymbianCcpuSupport(); + + //adding softkeys + QString copyLabel = QLatin1String("Copy"); + QString pasteLabel = QLatin1String("Paste"); + TRAP_IGNORE( + CEikonEnv* coe = CEikonEnv::Static(); + if (coe) { + HBufC* copyBuf = coe->AllocReadResourceLC(R_TEXT_SOFTKEY_COPY); + copyLabel = qt_TDesC2QString(*copyBuf); + CleanupStack::PopAndDestroy(copyBuf); + HBufC* pasteBuf = coe->AllocReadResourceLC(R_TEXT_SOFTKEY_PASTE); + pasteLabel = qt_TDesC2QString(*pasteBuf); + CleanupStack::PopAndDestroy(pasteBuf); + } + ) + + m_copyAction = new QAction(copyLabel, QApplication::desktop()); + m_pasteAction = new QAction(pasteLabel, QApplication::desktop()); + m_copyAction->setSoftKeyRole(QAction::PositiveSoftKey); + m_pasteAction->setSoftKeyRole(QAction::NegativeSoftKey); + connect(m_copyAction, SIGNAL(triggered()), this, SLOT(copy())); + connect(m_pasteAction, SIGNAL(triggered()), this, SLOT(paste())); } QCoeFepInputContext::~QCoeFepInputContext() @@ -145,8 +429,8 @@ QCoeFepInputContext::~QCoeFepInputContext() // but is synchronous, rather than asynchronous. CCoeEnv::Static()->SyncNotifyFocusObserversOfChangeInFocus(); - if (m_fepState) - delete m_fepState; + delete m_fepState; + delete m_ccpu; } void QCoeFepInputContext::reset() @@ -347,6 +631,12 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) sControl = focusWidget()->effectiveWinId()->MopGetObject(sControl); Q_ASSERT(sControl); + // Store last focused widget and object in case of fullscreen VKB + QObject *focusObject = 0; + m_lastFocusedEditor = getQWidgetFromQGraphicsView(focusWidget(), &focusObject); + m_lastFocusedObject = focusObject; // Can be null + Q_ASSERT(m_lastFocusedEditor); + // The FEP UI temporarily steals focus when it shows up the first time, causing // all sorts of weird effects on the focused widgets. Since it will immediately give // back focus to us, we temporarily disable focus handling until the job's done. @@ -369,28 +659,66 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) bool QCoeFepInputContext::symbianFilterEvent(QWidget *keyWidget, const QSymbianEvent *event) { Q_UNUSED(keyWidget); + if (event->type() == QSymbianEvent::WindowServerEvent) { + const TWsEvent* wsEvent = event->windowServerEvent(); + TInt eventType = 0; + if (wsEvent) + eventType = wsEvent->Type(); + + if (eventType == EEventKey) { + TKeyEvent* keyEvent = wsEvent->Key(); + if (keyEvent) { + switch (keyEvent->iScanCode) { + case EEikCmdEditCopy: + CcpuCopyL(); + break; + case EEikCmdEditCut: + CcpuCutL(); + break; + case EEikCmdEditPaste: + CcpuPasteL(); + break; + case EStdKeyF21: + changeCBA(true); + break; + default: + break; + } + switch (keyEvent->iCode) { + case EKeyLeftArrow: + case EKeyRightArrow: + case EKeyUpArrow: + case EKeyDownArrow: + if (CcpuCanCopy() && ((keyEvent->iModifiers & EModifierShift) == EModifierShift)) + changeCBA(true); + break; + default: + break; + } + } + } else if (eventType == EEventKeyUp) { + if (wsEvent->Key() && wsEvent->Key()->iScanCode == EStdKeyLeftShift) + changeCBA(false); + } else if (eventType == EEventWindowVisibilityChanged && S60->splitViewLastWidget) { + QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget); + const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff); + + if (alwaysResize) { + TUint visibleFlags = event->windowServerEvent()->VisibilityChanged()->iFlags; + if (visibleFlags & TWsVisibilityChangedEvent::EPartiallyVisible) + ensureFocusWidgetVisible(S60->splitViewLastWidget); + if (visibleFlags & TWsVisibilityChangedEvent::ENotVisible) + resetSplitViewWidget(true); + } + } + } + if (event->type() == QSymbianEvent::CommandEvent) // A command basically means the same as a button being pushed. With Qt buttons // that would normally result in a reset of the input method due to the focus change. // This should also happen for commands. reset(); - if (event->type() == QSymbianEvent::WindowServerEvent - && event->windowServerEvent() - && event->windowServerEvent()->Type() == EEventWindowVisibilityChanged - && S60->splitViewLastWidget) { - - QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget); - const bool alwaysResize = (gv && gv->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff); - - if (alwaysResize) { - TUint visibleFlags = event->windowServerEvent()->VisibilityChanged()->iFlags; - if (visibleFlags & TWsVisibilityChangedEvent::EPartiallyVisible) - ensureFocusWidgetVisible(S60->splitViewLastWidget); - if (visibleFlags & TWsVisibilityChangedEvent::ENotVisible) - resetSplitViewWidget(true); - } - } if (event->type() == QSymbianEvent::ResourceChangeEvent && (event->resourceChangeType() == KEikMessageFadeAllWindows @@ -956,7 +1284,11 @@ void QCoeFepInputContext::translateInputWidget() // Translation should happen row-by-row, but initially it needs to ensure that cursor is visible. const qreal translation = m_transformation.height() ? cursor.height() : (cursorRect.bottom() - vkbRect.top()); - const qreal dy = -(qMin(maxY, translation)); + qreal dy = -(qMin(maxY, translation)); + + // Correct the translation direction, if the cursor rect would be moved outside of application area. + if ((cursorRect.bottom() + dy) < 0) + dy *= -1; // Do not allow transform above screen top, nor beyond scenerect if (m_transformation.height() + dy > 0 || gv->sceneRect().bottom() + m_transformation.height() < 0) { @@ -1238,6 +1570,71 @@ void QCoeFepInputContext::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLin aAscent = metrics.ascent(); } +void QCoeFepInputContext::enableSymbianCcpuSupport() +{ + if (!m_ccpu) { + QT_TRAP_THROWING( + m_ccpu = new (ELeave) CAknCcpuSupport(this); + m_ccpu->SetMopParent(this); + CleanupStack::PushL(m_ccpu); + m_ccpu->ConstructL(); + CleanupStack::Pop(m_ccpu); + ); + Q_ASSERT(m_fepState); + if (m_fepState) + m_fepState->SetCcpuState(this); + } +} + +void QCoeFepInputContext::changeCBA(bool showCopyAndOrPaste) +{ + QWidget *w = focusWidget(); + if (!w) + w = m_lastFocusedEditor; + + if (w) { + if (showCopyAndOrPaste) { + if (CcpuCanCopy()) + w->addAction(m_copyAction); + if (CcpuCanPaste()) + w->addAction(m_pasteAction); + } else { + w->removeAction(m_copyAction); + w->removeAction(m_pasteAction); + } + } +} + +void QCoeFepInputContext::copyOrCutTextToClipboard(const char *operation) +{ + bool hasText = false; + + QWidget *w = focusWidget(); + QObject *focusObject = 0; + if (!w) { + w = m_lastFocusedEditor; + focusObject = m_lastFocusedObject; + } else { + w = getQWidgetFromQGraphicsView(w, &focusObject); + } + + if (w) { + int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt(); + int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt(); + + if (cursor != anchor) { + if (ccpuInvokeSlot(w, focusObject, operation)) { + TRAP_IGNORE( + CAknDiscreetPopup::ShowGlobalPopupL( + R_AVKON_DISCREET_POPUP_TEXT_COPIED, + KAvkonResourceFile); + ) + } + } + } +} + + void QCoeFepInputContext::DoCommitFepInlineEditL() { commitCurrentString(false); @@ -1302,6 +1699,142 @@ MCoeFepAwareTextEditor_Extension1::CState* QCoeFepInputContext::State(TUid /*aTy return m_fepState; } +TBool QCoeFepInputContext::CcpuIsFocused() const +{ + return focusWidget() != 0; +} + +TBool QCoeFepInputContext::CcpuCanCut() const +{ + bool retval = false; + QWidget *w = focusWidget(); + if (!w) + w = m_lastFocusedEditor; + else + w = getQWidgetFromQGraphicsView(w); + if (w) { + int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt(); + int anchor = w->inputMethodQuery(Qt::ImAnchorPosition).toInt(); + retval = cursor != anchor; + } + return retval; +} + +void QCoeFepInputContext::CcpuCutL() +{ + copyOrCutTextToClipboard("cut"); +} + +TBool QCoeFepInputContext::CcpuCanCopy() const +{ + return CcpuCanCut(); +} + +void QCoeFepInputContext::CcpuCopyL() +{ + copyOrCutTextToClipboard("copy"); +} + +TBool QCoeFepInputContext::CcpuCanPaste() const +{ + bool canPaste = false; + QString textToPaste = QApplication::clipboard()->text(); + if (!textToPaste.isEmpty()) { + QWidget *w = focusWidget(); + QObject *focusObject = 0; + if (!w) { + w = m_lastFocusedEditor; + focusObject = m_lastFocusedObject; + } else { + w = getQWidgetFromQGraphicsView(w, &focusObject); + } + if (w) { + // First, check if we are dealing with standard Qt editors (QLineEdit, QTextEdit, or QPlainTextEdit), + // as they do not have queryable property. + if (QTextEdit* tedit = qobject_cast<QTextEdit *>(w)) { + canPaste = tedit->canPaste(); + } else if (QPlainTextEdit* ptedit = qobject_cast<QPlainTextEdit *>(w)) { + canPaste = ptedit->canPaste(); + } else if (QLineEdit* ledit = qobject_cast<QLineEdit *>(w)) { + QString fullText = ledit->text(); + if (ledit->hasSelectedText()) { + fullText.remove(ledit->selectionStart(), ledit->selectedText().length()); + fullText.insert(ledit->selectionStart(), textToPaste); + } else { + fullText.insert(ledit->cursorPosition(), textToPaste); + } + + if (fullText.length() > ledit->maxLength()) { + canPaste = false; + } else { + const QValidator* validator = ledit->validator(); + if (validator) { + int pos = 0; + if (validator->validate(fullText, pos) == QValidator::Invalid) + canPaste = false; + else + canPaste = true; + } else { + QString mask(ledit->inputMask()); + if (!mask.isEmpty()) { + QCoeFepInputMaskHandler maskhandler(mask); + if (maskhandler.canPasteClipboard(fullText)) + canPaste = true; + else + canPaste = false; + } else { + canPaste = true; + } + } + } + } else { + // Unknown editor (probably a QML one); Request the "canPaste" property. + QObject *invokeTarget = w; + if (focusObject) + invokeTarget = focusObject; + + canPaste = invokeTarget->property("canPaste").toBool(); + } + } + } + return canPaste; +} + +void QCoeFepInputContext::CcpuPasteL() +{ + QWidget *w = focusWidget(); + QObject *focusObject = 0; + if (!w) { + w = m_lastFocusedEditor; + focusObject = m_lastFocusedObject; + } else { + w = getQWidgetFromQGraphicsView(w, &focusObject); + } + if (w) + ccpuInvokeSlot(w, focusObject, "paste"); +} + +TBool QCoeFepInputContext::CcpuCanUndo() const +{ + //not supported + return EFalse; +} + +void QCoeFepInputContext::CcpuUndoL() +{ + //not supported +} + +void QCoeFepInputContext::copy() +{ + QT_TRAP_THROWING(CcpuCopyL()); +} + +void QCoeFepInputContext::paste() +{ + QT_TRAP_THROWING(CcpuPasteL()); +} + TTypeUid::Ptr QCoeFepInputContext::MopSupplyObject(TTypeUid /*id*/) { return TTypeUid::Null(); diff --git a/src/gui/kernel/qeventdispatcher_qpa.cpp b/src/gui/kernel/qeventdispatcher_qpa.cpp index 200696d..3f2e8b2 100644 --- a/src/gui/kernel/qeventdispatcher_qpa.cpp +++ b/src/gui/kernel/qeventdispatcher_qpa.cpp @@ -284,7 +284,7 @@ int QEventDispatcherQPA::select(int nfds, fd_set *readfds, fd_set *writefds, fd_ Q_D(QEventDispatcherQPA); int retVal = 0; if (d->hasIntegration()) { - qint64 timeoutmsec = 0; + qint64 timeoutmsec = 1000; // wait a second if we don't have timers if (timeout) timeoutmsec = timeout->tv_sec * 1000 + (timeout->tv_usec/1000); d->selectReturnMutex->lock(); diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 5fc72d4..469973f 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -1381,11 +1381,11 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat QString p; if (key && key < Qt::Key_Escape && key != Qt::Key_Space) { - if (key < 0x10000) { - p = QChar(key & 0xffff).toUpper(); + if (!QChar::requiresSurrogates(key)) { + p = QChar(ushort(key)).toUpper(); } else { - p = QChar((key-0x10000)/0x400+0xd800); - p += QChar((key-0x10000)%400+0xdc00); + p += QChar(QChar::highSurrogate(key)); + p += QChar(QChar::lowSurrogate(key)); } } else if (key >= Qt::Key_F1 && key <= Qt::Key_F35) { p = nativeText ? QShortcut::tr("F%1").arg(key - Qt::Key_F1 + 1) @@ -1418,11 +1418,11 @@ NonSymbol: // Or else characters like Qt::Key_aring may not get displayed // (Really depends on you locale) if (!keyname[i].name) { - if (key < 0x10000) { - p = QChar(key & 0xffff).toUpper(); + if (!QChar::requiresSurrogates(key)) { + p = QChar(ushort(key)).toUpper(); } else { - p = QChar((key-0x10000)/0x400+0xd800); - p += QChar((key-0x10000)%400+0xdc00); + p += QChar(QChar::highSurrogate(key)); + p += QChar(QChar::lowSurrogate(key)); } } } diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 2b51aaa..e06b625 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -84,21 +84,6 @@ CEikButtonGroupContainer *QS60Data::cba = 0; int qt_symbian_create_desktop_on_screen = -1; -static bool isEqual(const QList<QAction*>& a, const QList<QAction*>& b) -{ - if ( a.count() != b.count()) - return false; - int index=0; - while (index<a.count()) { - if (a.at(index)->softKeyRole() != b.at(index)->softKeyRole()) - return false; - if (a.at(index)->text().compare(b.at(index)->text())!=0) - return false; - index++; - } - return true; -} - void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &) { // Note: based on x11 implementation @@ -231,7 +216,6 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) QPoint oldPos(q->pos()); QSize oldSize(q->size()); - QRect oldGeom(data.crect); bool checkExtra = true; if (q->isWindow() && (data.window_state & (Qt::WindowFullScreen | Qt::WindowMaximized))) { @@ -348,11 +332,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de bool topLevel = (flags & Qt::Window); bool popup = (type == Qt::Popup); - bool dialog = (type == Qt::Dialog - || type == Qt::Sheet - || (flags & Qt::MSWindowsFixedSizeDialogHint)); bool desktop = (type == Qt::Desktop); - //bool tool = (type == Qt::Tool || type == Qt::Drawer); if (popup) flags |= Qt::WindowStaysOnTopHint; // a popup stays on top @@ -1075,7 +1055,7 @@ void QWidgetPrivate::registerTouchWindow() int QWidget::metric(PaintDeviceMetric m) const { Q_D(const QWidget); - int val; + int val = 0; if (m == PdmWidth) { val = data->crect.width(); } else if (m == PdmHeight) { diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index c46513a..38ba6f9 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -756,14 +756,15 @@ void QPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) path.setFillRule(Qt::WindingFill); #endif if (ti.glyphs.numGlyphs) - ti.fontEngine->addOutlineToPath(p.x(), p.y(), ti.glyphs, &path, ti.flags); + ti.fontEngine->addOutlineToPath(0, 0, ti.glyphs, &path, ti.flags); if (!path.isEmpty()) { - bool oldAA = painter()->renderHints() & QPainter::Antialiasing; + painter()->save(); painter()->setRenderHint(QPainter::Antialiasing, bool((painter()->renderHints() & QPainter::TextAntialiasing) && !(painter()->font().styleStrategy() & QFont::NoAntialias))); + painter()->translate(p.x(), p.y()); painter()->fillPath(path, state->pen().brush()); - painter()->setRenderHint(QPainter::Antialiasing, oldAA); + painter()->restore(); } } diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 36786c4..bcc5f9d 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3764,6 +3764,11 @@ extern "C" { int q_gray_rendered_spans(QT_FT_Raster raster); } +static inline uchar *alignAddress(uchar *address, quintptr alignmentMask) +{ + return (uchar *)(((quintptr)address + alignmentMask) & ~alignmentMask); +} + void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *) @@ -3791,19 +3796,10 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, // minimize memory reallocations. However if initial size for // raster pool is changed for lower value, reallocations will // occur normally. - const int rasterPoolInitialSize = MINIMUM_POOL_SIZE; - int rasterPoolSize = rasterPoolInitialSize; - unsigned char *rasterPoolBase; -#if defined(Q_WS_WIN64) - rasterPoolBase = - // We make use of setjmp and longjmp in qgrayraster.c which requires - // 16-byte alignment, hence we hardcode this requirement here.. - (unsigned char *) _aligned_malloc(rasterPoolSize, sizeof(void*) * 2); -#else - unsigned char rasterPoolOnStack[rasterPoolInitialSize]; - rasterPoolBase = rasterPoolOnStack; -#endif - Q_CHECK_PTR(rasterPoolBase); + int rasterPoolSize = MINIMUM_POOL_SIZE; + uchar rasterPoolOnStack[MINIMUM_POOL_SIZE + 0xf]; + uchar *rasterPoolBase = alignAddress(rasterPoolOnStack, 0xf); + uchar *rasterPoolOnHeap = 0; qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize); @@ -3839,31 +3835,20 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, // Out of memory, reallocate some more and try again... if (error == -6) { // ErrRaster_OutOfMemory from qgrayraster.c - int new_size = rasterPoolSize * 2; - if (new_size > 1024 * 1024) { + rasterPoolSize *= 2; + if (rasterPoolSize > 1024 * 1024) { qWarning("QPainter: Rasterization of primitive failed"); break; } rendered_spans += q_gray_rendered_spans(*grayRaster.data()); -#if defined(Q_WS_WIN64) - _aligned_free(rasterPoolBase); -#else - if (rasterPoolBase != rasterPoolOnStack) // initially on the stack - free(rasterPoolBase); -#endif + free(rasterPoolOnHeap); + rasterPoolOnHeap = (uchar *)malloc(rasterPoolSize + 0xf); - rasterPoolSize = new_size; - rasterPoolBase = -#if defined(Q_WS_WIN64) - // We make use of setjmp and longjmp in qgrayraster.c which requires - // 16-byte alignment, hence we hardcode this requirement here.. - (unsigned char *) _aligned_malloc(rasterPoolSize, sizeof(void*) * 2); -#else - (unsigned char *) malloc(rasterPoolSize); -#endif - Q_CHECK_PTR(rasterPoolBase); // note: we just freed the old rasterPoolBase. I hope it's not fatal. + Q_CHECK_PTR(rasterPoolOnHeap); // note: we just freed the old rasterPoolBase. I hope it's not fatal. + + rasterPoolBase = alignAddress(rasterPoolOnHeap, 0xf); qt_ft_grays_raster.raster_done(*grayRaster.data()); qt_ft_grays_raster.raster_new(grayRaster.data()); @@ -3873,12 +3858,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, } } -#if defined(Q_WS_WIN64) - _aligned_free(rasterPoolBase); -#else - if (rasterPoolBase != rasterPoolOnStack) // initially on the stack - free(rasterPoolBase); -#endif + free(rasterPoolOnHeap); } void QRasterPaintEnginePrivate::recalculateFastImages() diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index ad0e151..327bedf 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -837,14 +837,12 @@ static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbut QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItemV4 *option, int role) const { - Q_Q(const QCommonStyle); - const QWidget *widget = option->widget; switch (role) { case Qt::CheckStateRole: if (option->features & QStyleOptionViewItemV2::HasCheckIndicator) - return QSize(q->pixelMetric(QStyle::PM_IndicatorWidth, option, widget), - q->pixelMetric(QStyle::PM_IndicatorHeight, option, widget)); + return QSize(proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth, option, widget), + proxyStyle->pixelMetric(QStyle::PM_IndicatorHeight, option, widget)); break; case Qt::DisplayRole: if (option->features & QStyleOptionViewItemV2::HasDisplay) { @@ -855,7 +853,7 @@ QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItemV4 *option, in textLayout.setFont(option->font); textLayout.setText(option->text); const bool wrapText = option->features & QStyleOptionViewItemV2::WrapText; - const int textMargin = q->pixelMetric(QStyle::PM_FocusFrameHMargin, option, widget) + 1; + const int textMargin = proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, option, widget) + 1; QRect bounds = option->rect; switch (option->decorationPosition) { case QStyleOptionViewItem::Left: @@ -919,9 +917,8 @@ static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth) void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewItemV4 *option, const QRect &rect) const { - Q_Q(const QCommonStyle); const QWidget *widget = option->widget; - const int textMargin = q->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1; + const int textMargin = proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1; QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding const bool wrapText = option->features & QStyleOptionViewItemV2::WrapText; @@ -999,7 +996,6 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItemV4 *opt, QRect *checkRect, QRect *pixmapRect, QRect *textRect, bool sizehint) const { - Q_Q(const QCommonStyle); Q_ASSERT(checkRect && pixmapRect && textRect); *pixmapRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DecorationRole)); *textRect = QRect(QPoint(0, 0), viewItemSize(opt, Qt::DisplayRole)); @@ -1009,9 +1005,9 @@ void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItemV4 *opt, QRe const bool hasCheck = checkRect->isValid(); const bool hasPixmap = pixmapRect->isValid(); const bool hasText = textRect->isValid(); - const int textMargin = hasText ? q->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0; - const int pixmapMargin = hasPixmap ? q->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0; - const int checkMargin = hasCheck ? q->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0; + const int textMargin = hasText ? proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0; + const int pixmapMargin = hasPixmap ? proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0; + const int checkMargin = hasCheck ? proxyStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget) + 1 : 0; int x = opt->rect.left(); int y = opt->rect.top(); int w, h; diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 816c094..eec2d15 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -842,6 +842,7 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) webPalette.setColor(QPalette::WindowText, Qt::black); webPalette.setColor(QPalette::Text, Qt::black); webPalette.setBrush(QPalette::Base, Qt::white); + webPalette.setBrush(QPalette::Window, Qt::white); QApplication::setPalette(webPalette, "QWebView"); QApplication::setPalette(webPalette, "QGraphicsWebView"); diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index dec0982..c9b672b 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -280,6 +280,8 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform int i = glyphs.numGlyphs; int totalKashidas = 0; while(i--) { + if (glyphs.attributes[i].dontPrint) + continue; xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6); ypos += glyphs.advances_y[i]; totalKashidas += glyphs.justifications[i].nKashidas; @@ -1335,8 +1337,7 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len, int glyph_pos = 0; for (int i = 0; i < len; ++i) { - bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1 - && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000); + bool surrogate = (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()); if (glyphs->glyphs[glyph_pos] == 0 && str[i].category() != QChar::Separator_Line) { QGlyphLayoutInstance tmp = glyphs->instance(glyph_pos); diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 9a5d9d6..e20aa25 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -78,6 +78,10 @@ #include FT_ERRORS_H #endif +#if !defined(QT_MAX_CACHED_GLYPH_SIZE) +# define QT_MAX_CACHED_GLYPH_SIZE 64 +#endif + QT_BEGIN_NAMESPACE /* @@ -373,7 +377,7 @@ void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize, *xsize = *ysize = 0; } } else { - *outline_drawing = (*xsize > (64<<6) || *ysize > (64<<6)); + *outline_drawing = (*xsize > (QT_MAX_CACHED_GLYPH_SIZE<<6) || *ysize > (QT_MAX_CACHED_GLYPH_SIZE<<6)); } } @@ -1317,7 +1321,7 @@ QFontEngineFT::QGlyphSet *QFontEngineFT::loadTransformedGlyphSet(const QTransfor if (!gs) { // don't try to load huge fonts - bool draw_as_outline = fontDef.pixelSize * qSqrt(qAbs(matrix.det())) >= 64; + bool draw_as_outline = fontDef.pixelSize * qSqrt(qAbs(matrix.det())) >= QT_MAX_CACHED_GLYPH_SIZE; if (draw_as_outline) return 0; @@ -1418,15 +1422,12 @@ void QFontEngineFT::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_me static inline unsigned int getChar(const QChar *str, int &i, const int len) { - unsigned int uc = str[i].unicode(); - if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) { - uint low = str[i+1].unicode(); - if (low >= 0xdc00 && low < 0xe000) { - uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000; - ++i; - } + uint ucs4 = str[i].unicode(); + if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) { + ++i; + ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode()); } - return uc; + return ucs4; } bool QFontEngineFT::canRender(const QChar *string, int len) diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 57811fa..95e5b82 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -196,12 +196,7 @@ public: inline bool useFastGlyphData(glyph_t index, QFixed subPixelPosition) const { return (index < 256 && subPixelPosition == 0); } - inline Glyph *getGlyph(glyph_t index, QFixed subPixelPosition = 0) const - { - if (useFastGlyphData(index, subPixelPosition)) - return fast_glyph_data[index]; - return glyph_data.value(GlyphAndSubPixelPosition(index, subPixelPosition)); - } + inline Glyph *getGlyph(glyph_t index, QFixed subPixelPosition = 0) const; void setGlyph(glyph_t index, QFixed spp, Glyph *glyph); private: @@ -376,6 +371,14 @@ inline uint qHash(const QFontEngineFT::GlyphAndSubPixelPosition &g) return (g.glyph << 8) | (g.subPixelPosition * 10).round().toInt(); } +inline QFontEngineFT::Glyph *QFontEngineFT::QGlyphSet::getGlyph(glyph_t index, QFixed subPixelPosition) const +{ + if (useFastGlyphData(index, subPixelPosition)) + return fast_glyph_data[index]; + return glyph_data.value(GlyphAndSubPixelPosition(index, subPixelPosition)); +} + + QT_END_NAMESPACE #endif // QT_NO_FREETYPE diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 9d9eaed..6186b2f 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -257,10 +257,8 @@ static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATS #if !defined(QT_NO_DEBUG) int surrogates = 0; const QChar *str = item->string; - for (int i = item->from; i < item->from + item->length - 1; ++i) { - surrogates += (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 - && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000); - } + for (int i = item->from; i < item->from + item->length - 1; ++i) + surrogates += (str[i].isHighSurrogate() && str[i+1].isLowSurrogate()); #endif for (nextCharStop = item->from; nextCharStop < item->from + item->length; ++nextCharStop) if (item->charAttributes[nextCharStop].charStop) @@ -328,10 +326,8 @@ static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATS if (charOffset < item->length - 1) { QChar current = item->string[item->from + charOffset]; QChar next = item->string[item->from + charOffset + 1]; - if (current.unicode() >= 0xd800 && current.unicode() < 0xdc00 - && next.unicode() >= 0xdc00 && next.unicode() < 0xe000) { + if (current.isHighSurrogate() && next.isLowSurrogate()) item->log_clusters[charOffset + 1] = currentClusterGlyph; - } } } } @@ -738,15 +734,12 @@ QFontEngineMac::~QFontEngineMac() static inline unsigned int getChar(const QChar *str, int &i, const int len) { - unsigned int uc = str[i].unicode(); - if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) { - uint low = str[i+1].unicode(); - if (low >= 0xdc00 && low < 0xe000) { - uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000; - ++i; - } + uint ucs4 = str[i].unicode(); + if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) { + ++i; + ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode()); } - return uc; + return ucs4; } // Not used directly for shaping, only used to calculate m_averageCharWidth diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp index cb1e7d6..c829c2f 100644 --- a/src/gui/text/qfontengine_qpa.cpp +++ b/src/gui/text/qfontengine_qpa.cpp @@ -226,15 +226,12 @@ QVariant QFontEngineQPA::extractHeaderField(const uchar *data, HeaderTag request static inline unsigned int getChar(const QChar *str, int &i, const int len) { - unsigned int uc = str[i].unicode(); - if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) { - uint low = str[i+1].unicode(); - if (low >= 0xdc00 && low < 0xe000) { - uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000; - ++i; - } + uint ucs4 = str[i].unicode(); + if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) { + ++i; + ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode()); } - return uc; + return ucs4; } QFontEngineQPA::QFontEngineQPA(const QFontDef &def, const QByteArray &data) diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp index 30a1623..3db5ce1 100644 --- a/src/gui/text/qfontengine_qpf.cpp +++ b/src/gui/text/qfontengine_qpf.cpp @@ -278,15 +278,12 @@ QList<QByteArray> QFontEngineQPF::cleanUpAfterClientCrash(const QList<int> &cras static inline unsigned int getChar(const QChar *str, int &i, const int len) { - unsigned int uc = str[i].unicode(); - if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) { - uint low = str[i+1].unicode(); - if (low >= 0xdc00 && low < 0xe000) { - uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000; - ++i; - } + uint ucs4 = str[i].unicode(); + if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) { + ++i; + ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode()); } - return uc; + return ucs4; } #ifdef QT_FONTS_ARE_RESOURCES QFontEngineQPF::QFontEngineQPF(const QFontDef &def, const uchar *bytes, int size) diff --git a/src/gui/text/qfontengine_qws.cpp b/src/gui/text/qfontengine_qws.cpp index 237842b..ade283f 100644 --- a/src/gui/text/qfontengine_qws.cpp +++ b/src/gui/text/qfontengine_qws.cpp @@ -83,15 +83,12 @@ QT_BEGIN_NAMESPACE static inline unsigned int getChar(const QChar *str, int &i, const int len) { - unsigned int uc = str[i].unicode(); - if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) { - uint low = str[i+1].unicode(); - if (low >= 0xdc00 && low < 0xe000) { - uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000; - ++i; - } + uint ucs4 = str[i].unicode(); + if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) { + ++i; + ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode()); } - return uc; + return ucs4; } #define FM_SMOOTH 1 diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp index b0824cb..203b6e1 100644 --- a/src/gui/text/qfontengine_s60.cpp +++ b/src/gui/text/qfontengine_s60.cpp @@ -233,15 +233,12 @@ bool QSymbianTypeFaceExtras::symbianFontTableApiAvailable() // duplicated from qfontengine_xyz.cpp static inline unsigned int getChar(const QChar *str, int &i, const int len) { - unsigned int uc = str[i].unicode(); - if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) { - uint low = str[i+1].unicode(); - if (low >= 0xdc00 && low < 0xe000) { - uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000; - ++i; - } + uint ucs4 = str[i].unicode(); + if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) { + ++i; + ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode()); } - return uc; + return ucs4; } extern QString qt_symbian_fontNameWithAppFontMarker(const QString &fontName); // qfontdatabase_s60.cpp diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index aef2145..fc11387 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -224,15 +224,12 @@ void QFontEngineWin::getCMap() inline unsigned int getChar(const QChar *str, int &i, const int len) { - unsigned int uc = str[i].unicode(); - if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) { - uint low = str[i+1].unicode(); - if (low >= 0xdc00 && low < 0xe000) { - uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000; - ++i; - } + uint ucs4 = str[i].unicode(); + if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) { + ++i; + ucs4 = QChar::surrogateToUcs4(ucs4, str[i].unicode()); } - return uc; + return ucs4; } int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs, bool mirrored) const diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp index 490866c..6e87f4c 100644 --- a/src/gui/text/qfontengine_x11.cpp +++ b/src/gui/text/qfontengine_x11.cpp @@ -358,9 +358,7 @@ bool QFontEngineXLFD::stringToCMap(const QChar *s, int len, QGlyphLayout *glyphs QVarLengthArray<ushort> _s(len); QChar *str = (QChar *)_s.data(); for (int i = 0; i < len; ++i) { - if (i < len - 1 - && s[i].unicode() >= 0xd800 && s[i].unicode() < 0xdc00 - && s[i+1].unicode() >= 0xdc00 && s[i].unicode() < 0xe000) { + if (s[i].isHighSurrogate() && i < len-1 && s[i+1].isLowSurrogate()) { *str = QChar(); ++i; } else { diff --git a/src/gui/text/qfontenginedirectwrite.cpp b/src/gui/text/qfontenginedirectwrite.cpp index d693273..5bac117 100644 --- a/src/gui/text/qfontenginedirectwrite.cpp +++ b/src/gui/text/qfontenginedirectwrite.cpp @@ -269,15 +269,12 @@ QFixed QFontEngineDirectWrite::emSquareSize() const inline unsigned int getChar(const QChar *str, int &i, const int len) { - unsigned int uc = str[i].unicode(); - if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) { - uint low = str[i+1].unicode(); - if (low >= 0xdc00 && low < 0xe000) { - uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000; - ++i; - } + uint ucs4 = str[i].unicode(); + if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()) { + ++i; + ucs4 = QChar::surrogateToUcs4( ucs4, str[i].unicode()); } - return uc; + return ucs4; } bool QFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, diff --git a/src/gui/text/qglyphrun.cpp b/src/gui/text/qglyphrun.cpp index 442f7cc..7f43378 100644 --- a/src/gui/text/qglyphrun.cpp +++ b/src/gui/text/qglyphrun.cpp @@ -140,14 +140,18 @@ bool QGlyphRun::operator==(const QGlyphRun &other) const return false; } - for (int i=0; i<qMax(d->glyphIndexDataSize, d->glyphPositionDataSize); ++i) { - if (i < d->glyphIndexDataSize && d->glyphIndexData[i] != other.d->glyphIndexData[i]) - return false; - - if (i < d->glyphPositionDataSize && d->glyphPositionData[i] != other.d->glyphPositionData[i]) - return false; + if (d->glyphIndexData != other.d->glyphIndexData) { + for (int i = 0; i < d->glyphIndexDataSize; ++i) { + if (d->glyphIndexData[i] != other.d->glyphIndexData[i]) + return false; + } + } + if (d->glyphPositionData != other.d->glyphPositionData) { + for (int i = 0; i < d->glyphPositionDataSize; ++i) { + if (d->glyphPositionData[i] != other.d->glyphPositionData[i]) + return false; + } } - return (d->overline == other.d->overline && d->underline == other.d->underline @@ -156,13 +160,11 @@ bool QGlyphRun::operator==(const QGlyphRun &other) const } /*! + \fn bool QGlyphRun::operator!=(const QGlyphRun &other) const + Compares \a other to this QGlyphRun object. Returns true if any of the list of glyph indexes, the list of positions or the font are different, otherwise returns false. */ -bool QGlyphRun::operator!=(const QGlyphRun &other) const -{ - return !(*this == other); -} /*! Returns the font selected for this QGlyphRun object. @@ -294,6 +296,9 @@ bool QGlyphRun::overline() const */ void QGlyphRun::setOverline(bool overline) { + if (d->overline == overline) + return; + detach(); d->overline = overline; } @@ -316,6 +321,9 @@ bool QGlyphRun::underline() const */ void QGlyphRun::setUnderline(bool underline) { + if (d->underline == underline) + return; + detach(); d->underline = underline; } @@ -338,6 +346,9 @@ bool QGlyphRun::strikeOut() const */ void QGlyphRun::setStrikeOut(bool strikeOut) { + if (d->strikeOut == strikeOut) + return; + detach(); d->strikeOut = strikeOut; } diff --git a/src/gui/text/qglyphrun.h b/src/gui/text/qglyphrun.h index cf407a8..bc7f4ff 100644 --- a/src/gui/text/qglyphrun.h +++ b/src/gui/text/qglyphrun.h @@ -79,8 +79,10 @@ public: void clear(); QGlyphRun &operator=(const QGlyphRun &other); + bool operator==(const QGlyphRun &other) const; - bool operator!=(const QGlyphRun &other) const; + inline bool operator!=(const QGlyphRun &other) const + { return !operator==(other); } void setOverline(bool overline); bool overline() const; diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 60a6cb3..7c7d4eb 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -46,7 +46,6 @@ #include "qrawfont.h" #include "qrawfont_p.h" -#include <QtCore/qthread.h> #include <QtCore/qendian.h> QT_BEGIN_NAMESPACE @@ -77,7 +76,7 @@ QT_BEGIN_NAMESPACE A QRawFont object represents a single, physical instance of a given font in a given pixel size. I.e. in the typical case it represents a set of TrueType or OpenType font tables and uses a - user specified pixel size to convert metrics into logical pixel units. In can be used in + user specified pixel size to convert metrics into logical pixel units. It can be used in combination with the QGlyphRun class to draw specific glyph indexes at specific positions, and also have accessors to some relevant data in the physical font. @@ -190,8 +189,7 @@ QRawFont &QRawFont::operator=(const QRawFont &other) */ bool QRawFont::isValid() const { - Q_ASSERT(d->thread == 0 || d->thread == QThread::currentThread()); - return d->fontEngine != 0; + return d->isValid(); } /*! @@ -225,7 +223,7 @@ void QRawFont::loadFromData(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { - detach(); + d.detach(); d->cleanUp(); d->hintingPreference = hintingPreference; d->thread = QThread::currentThread(); @@ -240,20 +238,21 @@ void QRawFont::loadFromData(const QByteArray &fontData, If \a antialiasingType is set to QRawFont::SubPixelAntialiasing, then the resulting image will be in QImage::Format_RGB32 and the RGB values of each pixel will represent the subpixel opacities of the pixel in the rasterization of the glyph. Otherwise, the image will be in the format of - QImage::Format_A8 and each pixel will contain the opacity of the pixel in the rasterization. + QImage::Format_Indexed8 and each pixel will contain the opacity of the pixel in the + rasterization. \sa pathForGlyph(), QPainter::drawGlyphRun() */ QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType, const QTransform &transform) const { - if (!isValid()) + if (!d->isValid()) return QImage(); if (antialiasingType == SubPixelAntialiasing) return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixed(), 0, transform); - else - return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform); + + return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform); } /*! @@ -266,7 +265,7 @@ QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialias */ QPainterPath QRawFont::pathForGlyph(quint32 glyphIndex) const { - if (!isValid()) + if (!d->isValid()) return QPainterPath(); QFixedPoint position; @@ -284,16 +283,19 @@ bool QRawFont::operator==(const QRawFont &other) const } /*! + \fn bool QRawFont::operator!=(const QRawFont &other) const + + Returns true if this QRawFont is not equal to \a other. Otherwise, returns false. +*/ + +/*! Returns the ascent of this QRawFont in pixel units. \sa QFontMetricsF::ascent() */ qreal QRawFont::ascent() const { - if (!isValid()) - return 0.0; - - return d->fontEngine->ascent().toReal(); + return d->isValid() ? d->fontEngine->ascent().toReal() : 0.0; } /*! @@ -303,10 +305,7 @@ qreal QRawFont::ascent() const */ qreal QRawFont::descent() const { - if (!isValid()) - return 0.0; - - return d->fontEngine->descent().toReal(); + return d->isValid() ? d->fontEngine->descent().toReal() : 0.0; } /*! @@ -316,10 +315,7 @@ qreal QRawFont::descent() const */ qreal QRawFont::xHeight() const { - if (!isValid()) - return 0.0; - - return d->fontEngine->xHeight().toReal(); + return d->isValid() ? d->fontEngine->xHeight().toReal() : 0.0; } /*! @@ -329,10 +325,7 @@ qreal QRawFont::xHeight() const */ qreal QRawFont::leading() const { - if (!isValid()) - return 0.0; - - return d->fontEngine->leading().toReal(); + return d->isValid() ? d->fontEngine->leading().toReal() : 0.0; } /*! @@ -342,10 +335,7 @@ qreal QRawFont::leading() const */ qreal QRawFont::averageCharWidth() const { - if (!isValid()) - return 0.0; - - return d->fontEngine->averageCharWidth().toReal(); + return d->isValid() ? d->fontEngine->averageCharWidth().toReal() : 0.0; } /*! @@ -355,10 +345,7 @@ qreal QRawFont::averageCharWidth() const */ qreal QRawFont::maxCharWidth() const { - if (!isValid()) - return 0.0; - - return d->fontEngine->maxCharWidth(); + return d->isValid() ? d->fontEngine->maxCharWidth() : 0.0; } /*! @@ -370,10 +357,7 @@ qreal QRawFont::maxCharWidth() const */ qreal QRawFont::pixelSize() const { - if (!isValid()) - return 0.0; - - return d->fontEngine->fontDef.pixelSize; + return d->isValid() ? d->fontEngine->fontDef.pixelSize : 0.0; } /*! @@ -386,10 +370,7 @@ qreal QRawFont::pixelSize() const */ qreal QRawFont::unitsPerEm() const { - if (!isValid()) - return 0.0; - - return d->fontEngine->emSquareSize().toReal(); + return d->isValid() ? d->fontEngine->emSquareSize().toReal() : 0.0; } /*! @@ -397,10 +378,7 @@ qreal QRawFont::unitsPerEm() const */ QString QRawFont::familyName() const { - if (!isValid()) - return QString(); - - return d->fontEngine->fontDef.family; + return d->isValid() ? d->fontEngine->fontDef.family : QString(); } /*! @@ -410,10 +388,7 @@ QString QRawFont::familyName() const */ QString QRawFont::styleName() const { - if (!isValid()) - return QString(); - - return d->fontEngine->fontDef.styleName; + return d->isValid() ? d->fontEngine->fontDef.styleName : QString(); } /*! @@ -423,10 +398,7 @@ QString QRawFont::styleName() const */ QFont::Style QRawFont::style() const { - if (!isValid()) - return QFont::StyleNormal; - - return QFont::Style(d->fontEngine->fontDef.style); + return d->isValid() ? QFont::Style(d->fontEngine->fontDef.style) : QFont::StyleNormal; } /*! @@ -436,10 +408,7 @@ QFont::Style QRawFont::style() const */ int QRawFont::weight() const { - if (!isValid()) - return -1; - - return int(d->fontEngine->fontDef.weight); + return d->isValid() ? int(d->fontEngine->fontDef.weight) : -1; } /*! @@ -457,7 +426,7 @@ int QRawFont::weight() const */ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const { - if (!isValid()) + if (!d->isValid()) return QVector<quint32>(); int nglyphs = text.size(); @@ -490,7 +459,7 @@ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const */ bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const { - if (!isValid()) + if (!d->isValid()) return false; QGlyphLayout glyphs; @@ -507,7 +476,7 @@ bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *g */ QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const { - if (!isValid()) + if (!d->isValid()) return QVector<QPointF>(); int numGlyphs = glyphIndexes.size(); @@ -534,7 +503,7 @@ QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyph */ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const { - if (!isValid()) + if (!d->isValid()) return false; QGlyphLayout glyphs; @@ -560,10 +529,7 @@ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *adv */ QFont::HintingPreference QRawFont::hintingPreference() const { - if (!isValid()) - return QFont::PreferDefaultHinting; - - return d->hintingPreference; + return d->isValid() ? d->hintingPreference : QFont::PreferDefaultHinting; } /*! @@ -574,7 +540,7 @@ QFont::HintingPreference QRawFont::hintingPreference() const */ QByteArray QRawFont::fontTable(const char *tagName) const { - if (!isValid()) + if (!d->isValid()) return QByteArray(); const quint32 *tagId = reinterpret_cast<const quint32 *>(tagName); @@ -597,9 +563,9 @@ extern QList<QFontDatabase::WritingSystem> qt_determine_writing_systems_from_tru */ QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const { - if (isValid()) { + if (d->isValid()) { QByteArray os2Table = fontTable("OS/2"); - if (!os2Table.isEmpty() && os2Table.size() > 86) { + if (os2Table.size() > 86) { char *data = os2Table.data(); quint32 *bigEndianUnicodeRanges = reinterpret_cast<quint32 *>(data + 42); quint32 *bigEndianCodepageRanges = reinterpret_cast<quint32 *>(data + 78); @@ -627,10 +593,7 @@ QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const */ bool QRawFont::supportsCharacter(QChar character) const { - if (!isValid()) - return false; - - return d->fontEngine->canRender(&character, 1); + return d->isValid() && d->fontEngine->canRender(&character, 1); } /*! @@ -641,9 +604,6 @@ bool QRawFont::supportsCharacter(QChar character) const */ bool QRawFont::supportsCharacter(quint32 ucs4) const { - if (!isValid()) - return false; - QChar str[2]; int len; if (!QChar::requiresSurrogates(ucs4)) { @@ -655,7 +615,7 @@ bool QRawFont::supportsCharacter(quint32 ucs4) const len = 2; } - return d->fontEngine->canRender(str, len); + return d->isValid() && d->fontEngine->canRender(str, len); } // qfontdatabase.cpp @@ -667,6 +627,7 @@ extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSyst */ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem) { + QRawFont rawFont; #if defined(Q_WS_MAC) QTextLayout layout(QFontDatabase::writingSystemSample(writingSystem), font); layout.beginLayout(); @@ -677,14 +638,12 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ // Pick the one matches the family name we originally requested, // if none of them match, just pick the first one for (int i = 0; i < list.size(); i++) { - QGlyphRun glyphs = list.at(i); - QRawFont rawfont = glyphs.rawFont(); - if (rawfont.familyName() == font.family()) - return rawfont; + rawFont = list.at(i).rawFont(); + if (rawFont.familyName() == font.family()) + return rawFont; } return list.at(0).rawFont(); } - return QRawFont(); #else QFontPrivate *font_d = QFontPrivate::get(font); int script = qt_script_for_writing_system(writingSystem); @@ -700,15 +659,12 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ } if (fe != 0) { - QRawFont rawFont; rawFont.d.data()->fontEngine = fe; rawFont.d.data()->fontEngine->ref.ref(); rawFont.d.data()->hintingPreference = font.hintingPreference(); - return rawFont; - } else { - return QRawFont(); } #endif + return rawFont; } /*! @@ -719,7 +675,7 @@ void QRawFont::setPixelSize(qreal pixelSize) if (d->fontEngine == 0) return; - detach(); + d.detach(); QFontEngine *oldFontEngine = d->fontEngine; d->fontEngine = d->fontEngine->cloneWithSize(pixelSize); @@ -734,15 +690,6 @@ void QRawFont::setPixelSize(qreal pixelSize) /*! \internal */ -void QRawFont::detach() -{ - if (d->ref != 1) - d.detach(); -} - -/*! - \internal -*/ void QRawFontPrivate::cleanUp() { platformCleanUp(); diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h index d5b5680..cf77996 100644 --- a/src/gui/text/qrawfont.h +++ b/src/gui/text/qrawfont.h @@ -81,7 +81,10 @@ public: bool isValid() const; QRawFont &operator=(const QRawFont &other); + bool operator==(const QRawFont &other) const; + inline bool operator!=(const QRawFont &other) const + { return !operator==(other); } QString familyName() const; QString styleName() const; @@ -132,9 +135,6 @@ public: private: friend class QRawFontPrivate; - - void detach(); - QExplicitlySharedDataPointer<QRawFontPrivate> d; }; diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h index fdf7cad..3557751 100644 --- a/src/gui/text/qrawfont_p.h +++ b/src/gui/text/qrawfont_p.h @@ -54,7 +54,9 @@ // #include "qrawfont.h" + #include "qfontengine_p.h" +#include <QtCore/qthread.h> #include <QtCore/qthreadstorage.h> #if !defined(QT_NO_RAWFONT) @@ -71,21 +73,17 @@ public: , thread(0) #if defined(Q_WS_WIN) , fontHandle(NULL) - , ptrAddFontMemResourceEx(NULL) - , ptrRemoveFontMemResourceEx(NULL) #endif {} QRawFontPrivate(const QRawFontPrivate &other) - : hintingPreference(other.hintingPreference) + : fontEngine(other.fontEngine) + , hintingPreference(other.hintingPreference) , thread(other.thread) #if defined(Q_WS_WIN) , fontHandle(NULL) - , ptrAddFontMemResourceEx(other.ptrAddFontMemResourceEx) - , ptrRemoveFontMemResourceEx(other.ptrRemoveFontMemResourceEx) #endif { - fontEngine = other.fontEngine; if (fontEngine != 0) fontEngine->ref.ref(); } @@ -96,6 +94,12 @@ public: cleanUp(); } + inline bool isValid() const + { + Q_ASSERT(thread == 0 || thread == QThread::currentThread()); + return fontEngine != 0; + } + void cleanUp(); void platformCleanUp(); void platformLoadFromData(const QByteArray &fontData, @@ -111,14 +115,7 @@ public: #if defined(Q_WS_WIN) HANDLE fontHandle; - - typedef HANDLE (WINAPI *PtrAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *); - typedef BOOL (WINAPI *PtrRemoveFontMemResourceEx)(HANDLE); - - PtrAddFontMemResourceEx ptrAddFontMemResourceEx; - PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx; - -#endif // Q_WS_WIN +#endif }; QT_END_NAMESPACE diff --git a/src/gui/text/qrawfont_win.cpp b/src/gui/text/qrawfont_win.cpp index 779652f..a729e31 100644 --- a/src/gui/text/qrawfont_win.cpp +++ b/src/gui/text/qrawfont_win.cpp @@ -40,6 +40,9 @@ ****************************************************************************/ #include "qrawfont_p.h" + +#if !defined(QT_NO_RAWFONT) + #include <private/qsystemlibrary_p.h> #if !defined(QT_NO_DIRECTWRITE) @@ -47,8 +50,6 @@ # include <dwrite.h> #endif -#if !defined(QT_NO_RAWFONT) - QT_BEGIN_NAMESPACE namespace { @@ -61,18 +62,16 @@ namespace { operator T() const { T littleEndian = 0; - for (int i=0; i<sizeof(T); ++i) { + for (int i = 0; i < int(sizeof(T)); ++i) littleEndian |= data[i] << ((sizeof(T) - i - 1) * 8); - } return littleEndian; } BigEndian<T> &operator=(const T &t) { - for (int i=0; i<sizeof(T); ++i) { + for (int i = 0; i < int(sizeof(T)); ++i) data[i] = ((t >> (sizeof(T) - i - 1) * 8) & 0xff); - } return *this; } @@ -157,7 +156,7 @@ namespace { class EmbeddedFont { public: - EmbeddedFont(const QByteArray &fontData); + EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData) {} QString changeFamilyName(const QString &newFamilyName); QByteArray data() const { return m_fontData; } @@ -168,10 +167,6 @@ namespace { QByteArray m_fontData; }; - EmbeddedFont::EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData) - { - } - TableDirectory *EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName) { Q_ASSERT(tagName.size() == 4); @@ -214,9 +209,9 @@ namespace { + nameRecord->offset; const BigEndian<quint16> *s = reinterpret_cast<const BigEndian<quint16> *>(ptr); - for (int j=0; j<nameRecord->length / sizeof(quint16); ++j) - name += QChar(s[j]); - + const BigEndian<quint16> *e = s + nameRecord->length / sizeof(quint16); + while (s != e) + name += QChar(*s++); break; } } @@ -525,41 +520,49 @@ extern QFontEngine *qt_load_font_engine_win(const QFontDef &request); // From qfontdatabase.cpp extern QFont::Weight weightFromInteger(int weight); -void QRawFontPrivate::platformCleanUp() +typedef HANDLE (WINAPI *PtrAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *); +static PtrAddFontMemResourceEx ptrAddFontMemResourceEx = 0; +typedef BOOL (WINAPI *PtrRemoveFontMemResourceEx)(HANDLE); +static PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx = 0; + +static void resolveGdi32() { - if (fontHandle != NULL) { - if (ptrRemoveFontMemResourceEx == NULL) { - void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx"); - ptrRemoveFontMemResourceEx = - reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func); + static bool triedResolve = false; + if (!triedResolve) { + QSystemLibrary gdi32(QLatin1String("gdi32")); + if (gdi32.load()) { + ptrAddFontMemResourceEx = (PtrAddFontMemResourceEx)gdi32.resolve("AddFontMemResourceEx"); + ptrRemoveFontMemResourceEx = (PtrRemoveFontMemResourceEx)gdi32.resolve("RemoveFontMemResourceEx"); } - if (ptrRemoveFontMemResourceEx == NULL) { - qWarning("QRawFont::platformCleanUp: Can't find RemoveFontMemResourceEx in gdi32"); - fontHandle = NULL; - } else { + triedResolve = true; + } +} + +void QRawFontPrivate::platformCleanUp() +{ + if (fontHandle != NULL) { + if (ptrRemoveFontMemResourceEx) ptrRemoveFontMemResourceEx(fontHandle); - fontHandle = NULL; - } + fontHandle = NULL; } } -void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData, +void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { - QByteArray fontData(_fontData); EmbeddedFont font(fontData); #if !defined(QT_NO_DIRECTWRITE) if (hintingPreference == QFont::PreferDefaultHinting - || hintingPreference == QFont::PreferFullHinting) + || hintingPreference == QFont::PreferFullHinting) #endif { GUID guid; CoCreateGuid(&guid); - QString uniqueFamilyName = QString::fromLatin1("f") + QString uniqueFamilyName = QLatin1Char('f') + QString::number(guid.Data1, 36) + QLatin1Char('-') + QString::number(guid.Data2, 36) + QLatin1Char('-') + QString::number(guid.Data3, 36) + QLatin1Char('-') @@ -571,22 +574,13 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData, return; } - if (ptrAddFontMemResourceEx == NULL || ptrRemoveFontMemResourceEx == NULL) { - void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx"); - ptrRemoveFontMemResourceEx = - reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func); - - func = QSystemLibrary::resolve(QLatin1String("gdi32"), "AddFontMemResourceEx"); - ptrAddFontMemResourceEx = - reinterpret_cast<QRawFontPrivate::PtrAddFontMemResourceEx>(func); - } - Q_ASSERT(fontHandle == NULL); - if (ptrAddFontMemResourceEx != NULL && ptrRemoveFontMemResourceEx != NULL) { + resolveGdi32(); + if (ptrAddFontMemResourceEx && ptrRemoveFontMemResourceEx) { DWORD count = 0; - fontData = font.data(); - fontHandle = ptrAddFontMemResourceEx(fontData.data(), fontData.size(), 0, &count); - + QByteArray newFontData = font.data(); + fontHandle = ptrAddFontMemResourceEx((void *)newFontData.constData(), newFontData.size(), + 0, &count); if (count == 0 && fontHandle != NULL) { ptrRemoveFontMemResourceEx(fontHandle); fontHandle = NULL; diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index bde2c34..aeeef85 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1638,16 +1638,13 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons return; } - if (!mousePressed) - return; - const qreal mouseX = qreal(mousePos.x()); int newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit); if (newCursorPos == -1) return; - if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) { + if (mousePressed && wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) { selectedWordOnDoubleClick = cursor; selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor); } @@ -1656,7 +1653,7 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons extendBlockwiseSelection(newCursorPos); else if (selectedWordOnDoubleClick.hasSelection()) extendWordwiseSelection(newCursorPos, mouseX); - else + else if (mousePressed) setCursorPosition(newCursorPos, QTextCursor::KeepAnchor); if (interactionFlags & Qt::TextEditable) { diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 7e7ca6c..acef9fa 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -1511,11 +1511,11 @@ void QTextCursor::deletePreviousChar() const QTextFragmentData * const frag = fragIt.value(); int fpos = fragIt.position(); QChar uc = d->priv->buffer().at(d->anchor - fpos + frag->stringPosition); - if (d->anchor > fpos && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) { + if (d->anchor > fpos && uc.isLowSurrogate()) { // second half of a surrogate, check if we have the first half as well, // if yes delete both at once uc = d->priv->buffer().at(d->anchor - 1 - fpos + frag->stringPosition); - if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) + if (uc.isHighSurrogate()) --d->anchor; } diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index aa4a20d..2fc1dbd 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -968,7 +968,7 @@ void QTextEngine::shapeText(int item) const } for (int i = 0; i < si.num_glyphs; ++i) - si.width += glyphs.advances_x[i]; + si.width += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint; } static inline bool hasCaseChange(const QScriptItem &si) @@ -993,8 +993,7 @@ static void heuristicSetGlyphAttributes(const QChar *uc, int length, QGlyphLayou int glyph_pos = 0; for (int i = 0; i < length; i++) { - if (uc[i].unicode() >= 0xd800 && uc[i].unicode() < 0xdc00 && i < length-1 - && uc[i+1].unicode() >= 0xdc00 && uc[i+1].unicode() < 0xe000) { + if (uc[i].isHighSurrogate() && i < length-1 && uc[i+1].isLowSurrogate()) { logClusters[i] = glyph_pos; logClusters[++i] = glyph_pos; } else { @@ -1387,6 +1386,7 @@ QTextEngine::~QTextEngine() if (!stackEngine) delete layoutData; delete specialData; + resetFontEngineCache(); } const HB_CharAttributes *QTextEngine::attributes() const @@ -1447,6 +1447,13 @@ static inline void releaseCachedFontEngine(QFontEngine *fontEngine) } } +void QTextEngine::resetFontEngineCache() +{ + releaseCachedFontEngine(feCache.prevFontEngine); + releaseCachedFontEngine(feCache.prevScaledFontEngine); + feCache.reset(); +} + void QTextEngine::invalidate() { freeMemory(); @@ -1455,9 +1462,7 @@ void QTextEngine::invalidate() if (specialData) specialData->resolvedFormatIndices.clear(); - releaseCachedFontEngine(feCache.prevFontEngine); - releaseCachedFontEngine(feCache.prevScaledFontEngine); - feCache.reset(); + resetFontEngineCache(); } void QTextEngine::clearLineData() @@ -2658,7 +2663,7 @@ void QTextEngine::splitItem(int item, int pos) const QFixed w = 0; const QGlyphLayout g = shapedGlyphs(&oldItem); for(int j = 0; j < breakGlyph; ++j) - w += g.advances_x[j]; + w += g.advances_x[j] * !g.attributes[j].dontPrint; newItem.width = oldItem.width - w; oldItem.width = w; @@ -2951,7 +2956,7 @@ int QTextEngine::lineNumberForTextPosition(int pos) return lines.size() - 1; for (int i = 0; i < lines.size(); ++i) { const QScriptLine& line = lines[i]; - if (line.from + line.length > pos) + if (line.from + line.length + line.trailingSpaces > pos) return i; } return -1; diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index b1bd0c3..9362022 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -376,7 +376,7 @@ struct Q_AUTOTEST_EXPORT QScriptLine { // created and filled in QTextLine::layout_helper QScriptLine() - : from(0), length(0), + : from(0), trailingSpaces(0), length(0), justified(0), gridfitted(0), hasTrailingSpaces(0), leadingIncluded(0) {} QFixed descent; @@ -388,6 +388,7 @@ struct Q_AUTOTEST_EXPORT QScriptLine QFixed textWidth; QFixed textAdvance; int from; + unsigned short trailingSpaces; signed int length : 28; mutable uint justified : 1; mutable uint gridfitted : 1; @@ -628,6 +629,7 @@ public: int lineNumberForTextPosition(int pos); int positionAfterVisualMovement(int oldPos, QTextCursor::MoveOperation op); void insertionPointsForLine(int lineNum, QVector<int> &insertionPoints); + void resetFontEngineCache(); private: void setBoundary(int strPos) const; diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 5b60dfa..d130c61 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -820,15 +820,11 @@ QString QTextHtmlParser::parseEntity() if (uc >= 0x80 && uc < 0x80 + (sizeof(windowsLatin1ExtendedCharacters)/sizeof(windowsLatin1ExtendedCharacters[0]))) uc = windowsLatin1ExtendedCharacters[uc - 0x80]; QString str; - if (uc > 0xffff) { - // surrogate pair - uc -= 0x10000; - ushort high = uc/0x400 + 0xd800; - ushort low = uc%0x400 + 0xdc00; - str.append(QChar(high)); - str.append(QChar(low)); + if (QChar::requiresSurrogates(uc)) { + str += QChar(QChar::highSurrogate(uc)); + str += QChar(QChar::lowSurrogate(uc)); } else { - str.append(QChar(uc)); + str = QChar(uc); } return str; } diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 4fd6ddf..d0c1a0e 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -375,7 +375,7 @@ QTextLayout::~QTextLayout() void QTextLayout::setFont(const QFont &font) { d->fnt = font; - d->feCache.reset(); + d->resetFontEngineCache(); } /*! @@ -515,7 +515,7 @@ void QTextLayout::setAdditionalFormats(const QList<FormatRange> &formatList) } if (d->block.docHandle()) d->block.docHandle()->documentChange(d->block.position(), d->block.length()); - d->feCache.reset(); + d->resetFontEngineCache(); } /*! @@ -814,7 +814,7 @@ QTextLine QTextLayout::createLine() if (l && d->lines.at(l-1).length < 0) { QTextLine(l-1, d).setNumColumns(INT_MAX); } - int from = l > 0 ? d->lines.at(l-1).from + d->lines.at(l-1).length : 0; + int from = l > 0 ? d->lines.at(l-1).from + d->lines.at(l-1).length + d->lines.at(l-1).trailingSpaces : 0; int strlen = d->layoutData->string.length(); if (l && from >= strlen) { if (!d->lines.at(l-1).length || d->layoutData->string.at(strlen - 1) != QChar::LineSeparator) @@ -1708,6 +1708,7 @@ void QTextLine::layout_helper(int maxGlyphs) { QScriptLine &line = eng->lines[i]; line.length = 0; + line.trailingSpaces = 0; line.textWidth = 0; line.hasTrailingSpaces = false; @@ -1931,7 +1932,7 @@ found: if (eng->option.flags() & QTextOption::IncludeTrailingSpaces) line.textWidth += lbh.spaceData.textWidth; if (lbh.spaceData.length) { - line.length += lbh.spaceData.length; + line.trailingSpaces = lbh.spaceData.length; line.hasTrailingSpaces = true; } @@ -1995,7 +1996,7 @@ int QTextLine::textLength() const && eng->block.isValid() && i == eng->lines.count()-1) { return eng->lines[i].length - 1; } - return eng->lines[i].length; + return eng->lines[i].length + eng->lines[i].trailingSpaces; } static void drawMenuText(QPainter *p, QFixed x, QFixed y, const QScriptItem &si, QTextItemInt &gf, QTextEngine *eng, @@ -2506,6 +2507,9 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const int pos = *cursorPos; int itm; + const HB_CharAttributes *attributes = eng->attributes(); + while (pos < line.from + line.length && !attributes[pos].charStop) + pos++; if (pos == line.from + (int)line.length) { // end of line ensure we have the last item on the line itm = eng->findItem(pos-1); diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index a8031e7..d58da37 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -198,12 +198,10 @@ void QLineControl::backspace() --m_cursor; if (m_maskData) m_cursor = prevMaskBlank(m_cursor); - QChar uc = m_text.at(m_cursor); - if (m_cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) { + if (m_cursor > 0 && m_text.at(m_cursor).isLowSurrogate()) { // second half of a surrogate, check if we have the first half as well, // if yes delete both at once - uc = m_text.at(m_cursor - 1); - if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) { + if (m_text.at(m_cursor - 1).isHighSurrogate()) { internalDelete(true); --m_cursor; } diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 6101eea..4f2145e 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -48,6 +48,7 @@ #include <private/qauthenticator_p.h> #include <qnetworkproxy.h> #include <qauthenticator.h> +#include <qcoreapplication.h> #include <qbuffer.h> #include <qpair.h> @@ -665,32 +666,31 @@ QString QHttpNetworkConnectionPrivate::errorDetail(QNetworkReply::NetworkError e QString errorString; switch (errorCode) { case QNetworkReply::HostNotFoundError: - errorString = QString::fromLatin1(QT_TRANSLATE_NOOP("QHttp", "Host %1 not found")) - .arg(socket->peerName()); + errorString = QCoreApplication::translate("QHttp", "Host %1 not found").arg(socket->peerName()); break; case QNetworkReply::ConnectionRefusedError: - errorString = QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Connection refused")); + errorString = QCoreApplication::translate("QHttp", "Connection refused"); break; case QNetworkReply::RemoteHostClosedError: - errorString = QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Connection closed")); + errorString = QCoreApplication::translate("QHttp", "Connection closed"); break; case QNetworkReply::TimeoutError: - errorString = QLatin1String(QT_TRANSLATE_NOOP("QAbstractSocket", "Socket operation timed out")); + errorString = QCoreApplication::translate("QAbstractSocket", "Socket operation timed out"); break; case QNetworkReply::ProxyAuthenticationRequiredError: - errorString = QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Proxy requires authentication")); + errorString = QCoreApplication::translate("QHttp", "Proxy requires authentication"); break; case QNetworkReply::AuthenticationRequiredError: - errorString = QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Host requires authentication")); + errorString = QCoreApplication::translate("QHttp", "Host requires authentication"); break; case QNetworkReply::ProtocolFailure: - errorString = QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Data corrupted")); + errorString = QCoreApplication::translate("QHttp", "Data corrupted"); break; case QNetworkReply::ProtocolUnknownError: - errorString = QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Unknown protocol specified")); + errorString = QCoreApplication::translate("QHttp", "Unknown protocol specified"); break; case QNetworkReply::SslHandshakeFailedError: - errorString = QLatin1String(QT_TRANSLATE_NOOP("QHttp", "SSL handshake failed")); + errorString = QCoreApplication::translate("QHttp", "SSL handshake failed"); break; default: // all other errors are treated as QNetworkReply::UnknownNetworkError diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 58eb0d8..0b568d4 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -275,6 +275,11 @@ void QNetworkReplyImplPrivate::_q_networkSessionConnected() if (session->state() != QNetworkSession::Connected) return; + #ifndef QT_NO_NETWORKPROXY + // Re-set proxies here as new session might have changed them + proxyList = manager->d_func()->queryProxy(QNetworkProxyQuery(request.url())); + #endif + switch (state) { case QNetworkReplyImplPrivate::Buffering: case QNetworkReplyImplPrivate::Working: diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index ab09932..2a2ad55 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -792,15 +792,38 @@ static const char *certificate_blacklist[] = { "92:39:d5:34:8f:40:d1:69:5a:74:54:70:e1:f2:3f:43", "addons.mozilla.org", // Comodo "b0:b7:13:3e:d0:96:f9:b5:6f:ae:91:c8:74:bd:3a:c0", "login.live.com", // Comodo "d8:f3:5f:4e:b7:87:2b:2d:ab:06:92:e3:15:38:2f:b0", "global trustee", // Comodo - "05:e2:e6:a4:cd:09:ea:54:d6:65:b0:75:fe:22:a2:56", "*.google.com", // DigiNotar + + "05:e2:e6:a4:cd:09:ea:54:d6:65:b0:75:fe:22:a2:56", "*.google.com", // leaf certificate issued by DigiNotar + "0c:76:da:9c:91:0c:4e:2c:9e:fe:15:d0:58:93:3c:4c", "DigiNotar Root CA", // DigiNotar root + "f1:4a:13:f4:87:2b:56:dc:39:df:84:ca:7a:a1:06:49", "DigiNotar Services CA", // DigiNotar intermediate signed by DigiNotar Root + "36:16:71:55:43:42:1b:9d:e6:cb:a3:64:41:df:24:38", "DigiNotar Services 1024 CA", // DigiNotar intermediate signed by DigiNotar Root + "0a:82:bd:1e:14:4e:88:14:d7:5b:1a:55:27:be:bf:3e", "DigiNotar Root CA G2", // other DigiNotar Root CA + "a4:b6:ce:e3:2e:d3:35:46:26:3c:b3:55:3a:a8:92:21", "CertiID Enterprise Certificate Authority", // DigiNotar intermediate signed by "DigiNotar Root CA G2" + "5b:d5:60:9c:64:17:68:cf:21:0e:35:fd:fb:05:ad:41", "DigiNotar Qualified CA", // DigiNotar intermediate signed by DigiNotar Root + + "1184640176", "DigiNotar Services 1024 CA", // DigiNotar intermediate cross-signed by Entrust + "120000525", "DigiNotar Cyber CA", // DigiNotar intermediate cross-signed by CyberTrust + "120000505", "DigiNotar Cyber CA", // DigiNotar intermediate cross-signed by CyberTrust + "120000515", "DigiNotar Cyber CA", // DigiNotar intermediate cross-signed by CyberTrust + "20015536", "DigiNotar PKIoverheid CA Overheid en Bedrijven", // DigiNotar intermediate cross-signed by the Dutch government + "20001983", "DigiNotar PKIoverheid CA Organisatie - G2", // DigiNotar intermediate cross-signed by the Dutch government + "d6:d0:29:77:f1:49:fd:1a:83:f2:b9:ea:94:8c:5c:b4", "DigiNotar Extended Validation CA", // DigiNotar intermediate signed by DigiNotar EV Root + "1e:7d:7a:53:3d:45:30:41:96:40:0f:71:48:1f:45:04", "DigiNotar Public CA 2025", // DigiNotar intermediate +// "(has not been seen in the wild so far)", "DigiNotar Public CA - G2", // DigiNotar intermediate +// "(has not been seen in the wild so far)", "Koninklijke Notariele Beroepsorganisatie CA", // compromised during DigiNotar breach +// "(has not been seen in the wild so far)", "Stichting TTP Infos CA," // compromised during DigiNotar breach + "1184640175", "DigiNotar Root CA", // DigiNotar intermediate cross-signed by Entrust + "1184644297", "DigiNotar Root CA", // DigiNotar intermediate cross-signed by Entrust 0 }; bool QSslCertificatePrivate::isBlacklisted(const QSslCertificate &certificate) { for (int a = 0; certificate_blacklist[a] != 0; a++) { + QString blacklistedCommonName = QString::fromUtf8(certificate_blacklist[(a+1)]); if (certificate.serialNumber() == certificate_blacklist[a++] && - certificate.subjectInfo(QSslCertificate::CommonName) == QString::fromUtf8(certificate_blacklist[a])) + (certificate.subjectInfo(QSslCertificate::CommonName) == blacklistedCommonName || + certificate.issuerInfo(QSslCertificate::CommonName) == blacklistedCommonName)) return true; } return false; diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 5a606af..8e53974 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -1246,12 +1246,15 @@ bool QSslSocketBackendPrivate::startHandshake() // Start translating errors. QList<QSslError> errors; - if (QSslCertificatePrivate::isBlacklisted(configuration.peerCertificate)) { - QSslError error(QSslError::CertificateBlacklisted, configuration.peerCertificate); - errors << error; - emit q->peerVerifyError(error); - if (q->state() != QAbstractSocket::ConnectedState) - return false; + // check the whole chain for blacklisting (including root, as we check for subjectInfo and issuer) + foreach (const QSslCertificate &cert, configuration.peerCertificateChain) { + if (QSslCertificatePrivate::isBlacklisted(cert)) { + QSslError error(QSslError::CertificateBlacklisted, cert); + errors << error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } } bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer diff --git a/src/opengl/opengl.pro.user.2.1pre1 b/src/opengl/opengl.pro.user.2.1pre1 deleted file mode 100644 index 0c38724..0000000 --- a/src/opengl/opengl.pro.user.2.1pre1 +++ /dev/null @@ -1,83 +0,0 @@ -<!DOCTYPE QtCreatorProject> -<qtcreator> - <data> - <variable>ProjectExplorer.Project.ActiveTarget</variable> - <value type="int">0</value> - </data> - <data> - <variable>ProjectExplorer.Project.EditorSettings</variable> - <valuemap type="QVariantMap"> - <value key="EditorConfiguration.Codec" type="QByteArray">UTF-8</value> - </valuemap> - </data> - <data> - <variable>ProjectExplorer.Project.Target.0</variable> - <valuemap type="QVariantMap"> - <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">Desktop</value> - <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Target.DesktopTarget</value> - <value key="ProjectExplorer.Target.ActiveBuildConfiguration" type="int">0</value> - <value key="ProjectExplorer.Target.ActiveRunConfiguration" type="int">0</value> - <valuemap key="ProjectExplorer.Target.BuildConfiguration.0" type="QVariantMap"> - <valuemap key="ProjectExplorer.BuildConfiguration.BuildStep.0" type="QVariantMap"> - <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">qmake</value> - <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">QtProjectManager.QMakeBuildStep</value> - <valuelist key="QtProjectManager.QMakeBuildStep.QMakeArguments" type="QVariantList"> - <value type="QString">QMAKE_ABSOLUTE_SOURCE_PATH=/home/jlind/dev/qt/lighthouse-master/src/opengl</value> - </valuelist> - </valuemap> - <valuemap key="ProjectExplorer.BuildConfiguration.BuildStep.1" type="QVariantMap"> - <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">Make</value> - <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.MakeStep</value> - <value key="Qt4ProjectManager.MakeStep.Clean" type="bool">false</value> - <valuelist key="Qt4ProjectManager.MakeStep.MakeArguments" type="QVariantList"> - <value type="QString">-j9</value> - </valuelist> - <value key="Qt4ProjectManager.MakeStep.MakeCommand" type="QString"></value> - </valuemap> - <value key="ProjectExplorer.BuildConfiguration.BuildStepsCount" type="int">2</value> - <valuemap key="ProjectExplorer.BuildConfiguration.CleanStep.0" type="QVariantMap"> - <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">Make</value> - <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.MakeStep</value> - <value key="Qt4ProjectManager.MakeStep.Clean" type="bool">true</value> - <valuelist key="Qt4ProjectManager.MakeStep.MakeArguments" type="QVariantList"> - <value type="QString">clean</value> - </valuelist> - <value key="Qt4ProjectManager.MakeStep.MakeCommand" type="QString"></value> - </valuemap> - <value key="ProjectExplorer.BuildConfiguration.CleanStepsCount" type="int">1</value> - <value key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment" type="bool">false</value> - <valuelist key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges" type="QVariantList"/> - <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">Debug</value> - <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Qt4BuildConfiguration</value> - <value key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration" type="int">2</value> - <value key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory" type="QString">/home/jlind/builds/master-lighthouse/src/opengl</value> - <value key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId" type="int">23</value> - <value key="Qt4ProjectManager.Qt4BuildConfiguration.ToolChain" type="int">0</value> - <value key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild" type="bool">true</value> - </valuemap> - <value key="ProjectExplorer.Target.BuildConfigurationCount" type="int">1</value> - <valuemap key="ProjectExplorer.Target.RunConfiguration.0" type="QVariantMap"> - <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">headers</value> - <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Qt4RunConfiguration</value> - <value key="Qt4ProjectManager.Qt4RunConfiguration.BaseEnvironmentBase" type="int">2</value> - <valuelist key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments" type="QVariantList"/> - <value key="Qt4ProjectManager.Qt4RunConfiguration.ProFile" type="QString">../../../../../builds/master-lighthouse/include/QtOpenGL/headers.pri</value> - <value key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix" type="bool">false</value> - <value key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal" type="bool">false</value> - <valuelist key="Qt4ProjectManager.Qt4RunConfiguration.UserEnvironmentChanges" type="QVariantList"/> - <value key="Qt4ProjectManager.Qt4RunConfiguration.UserSetName" type="bool">false</value> - <value key="Qt4ProjectManager.Qt4RunConfiguration.UserSetWorkingDirectory" type="bool">false</value> - <value key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory" type="QString"></value> - </valuemap> - <value key="ProjectExplorer.Target.RunConfigurationCount" type="int">1</value> - </valuemap> - </data> - <data> - <variable>ProjectExplorer.Project.TargetCount</variable> - <value type="int">1</value> - </data> - <data> - <variable>ProjectExplorer.Project.Updater.FileVersion</variable> - <value type="int">4</value> - </data> -</qtcreator> diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.cpp b/src/plugins/accessible/widgets/qaccessiblemenu.cpp index 1454c7c..4ae1d15 100644 --- a/src/plugins/accessible/widgets/qaccessiblemenu.cpp +++ b/src/plugins/accessible/widgets/qaccessiblemenu.cpp @@ -433,6 +433,8 @@ QString QAccessibleMenuItem::actionText(int action, Text text, int child ) const switch (action) { case Press: case DefaultAction: + if (m_action->menu()) + return QMenu::tr("Open"); return QMenu::tr("Execute"); break; default: @@ -444,11 +446,41 @@ QString QAccessibleMenuItem::actionText(int action, Text text, int child ) const bool QAccessibleMenuItem::doAction(int action, int child, const QVariantList & /*params = QVariantList()*/ ) { - if ((action == Press || action == DefaultAction) && child == 0) { - m_action->trigger(); - return true; + if ((child) || ((action != DefaultAction) && (action != Press))) + return false; + + // if the action has a menu, expand/hide it + if (m_action->menu()) { + if (m_action->menu()->isVisible()) { + m_action->menu()->hide(); + return true; + } else { + if (QMenuBar *bar = qobject_cast<QMenuBar*>(owner())) { + bar->setActiveAction(m_action); + return true; + } else if (QMenu *menu = qobject_cast<QMenu*>(owner())){ + menu->setActiveAction(m_action); + return true; + } + } } - return false; + // no menu + m_action->trigger(); + return true; +} + +// action interface +int QAccessibleMenuItem::actionCount() +{ + return 1; +} + +void QAccessibleMenuItem::doAction(int actionIndex) +{ + if (actionIndex) + return; + + doAction(DefaultAction, 0); } int QAccessibleMenuItem::indexOfChild( const QAccessibleInterface * child ) const @@ -618,7 +650,7 @@ QAccessible::State QAccessibleMenuItem::state(int child ) const delete iface; } } - return s; + return s | HasInvokeExtension;; } QString QAccessibleMenuItem::text ( Text t, int child ) const @@ -654,17 +686,50 @@ QString QAccessibleMenuItem::text ( Text t, int child ) const return str; } +// action interface int QAccessibleMenuItem::userActionCount ( int /*child*/ ) const { return 0; } - QAction *QAccessibleMenuItem::action() const { return m_action; } +QString QAccessibleMenuItem::description(int) +{ + return text(QAccessible::Description, 0); +} + +QString QAccessibleMenuItem::name(int) +{ + return actionText(DefaultAction, QAccessible::Name, 0); +} + +QString QAccessibleMenuItem::localizedName(int) +{ + return text(QAccessible::Name, 0); +} + +QStringList QAccessibleMenuItem::keyBindings(int) +{ + QStringList keys; +#ifndef QT_NO_SHORTCUT + QKeySequence key = m_action->shortcut(); + if (!key.isEmpty()) { + keys.append(key.toString()); + } +#endif + return keys; +} + + +QVariant QAccessibleMenuItem::invokeMethodEx(Method, int, const QVariantList &) +{ + return QVariant(); +} + QWidget *QAccessibleMenuItem::owner() const { return m_owner; diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.h b/src/plugins/accessible/widgets/qaccessiblemenu.h index 680594d..47f42cb 100644 --- a/src/plugins/accessible/widgets/qaccessiblemenu.h +++ b/src/plugins/accessible/widgets/qaccessiblemenu.h @@ -43,6 +43,7 @@ #define QACCESSIBLEMENU_H #include <QtGui/qaccessiblewidget.h> +#include <QtGui/qaccessible2.h> QT_BEGIN_NAMESPACE @@ -101,8 +102,9 @@ protected: -class QAccessibleMenuItem : public QAccessibleInterface +class QAccessibleMenuItem : public QAccessibleActionInterface, public QAccessibleInterfaceEx { + Q_ACCESSIBLE_OBJECT public: explicit QAccessibleMenuItem(QWidget *owner, QAction *w); @@ -123,9 +125,17 @@ public: virtual QString text ( Text t, int child ) const; virtual int userActionCount ( int child ) const; - QWidget *owner() const; + // action interface + virtual int actionCount(); + virtual void doAction(int actionIndex); + virtual QString description(int); + virtual QString name(int); + virtual QString localizedName(int); + virtual QStringList keyBindings(int); + virtual QVariant invokeMethodEx(Method, int, const QVariantList &); + QWidget *owner() const; protected: QAction *action() const; private: diff --git a/src/plugins/bearer/corewlan/corewlan.pro b/src/plugins/bearer/corewlan/corewlan.pro index 90078e9..590a85b 100644 --- a/src/plugins/bearer/corewlan/corewlan.pro +++ b/src/plugins/bearer/corewlan/corewlan.pro @@ -5,9 +5,8 @@ QT = core network LIBS += -framework Foundation -framework SystemConfiguration contains(QT_CONFIG, corewlan) { - isEmpty(QMAKE_MAC_SDK)|contains(QMAKE_MAC_SDK, "/Developer/SDKs/MacOSX10.6.sdk") { + isEmpty(QMAKE_MAC_SDK)|contains(QMAKE_MAC_SDK, "/Developer/SDKs/MacOSX10\.[67]\.sdk") { LIBS += -framework CoreWLAN -framework Security - DEFINES += MAC_SDK_10_6 } } diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp index fc65b86..a7dad2b 100644 --- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp +++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp @@ -1377,6 +1377,9 @@ void QNetworkSessionPrivateImpl::handleSymbianConnectionStatusChange(TInt aConne newState(QNetworkSession::Closing,accessPointId); break; + // Connection stopped + case KConfigDaemonFinishedDeregistrationStop: //this comes if this is the last session, instead of KLinkLayerClosed + case KConfigDaemonFinishedDeregistrationPreserve: // Connection closed case KConnectionClosed: case KLinkLayerClosed: diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp index fc2791a..ee80297 100644 --- a/src/plugins/bearer/symbian/symbianengine.cpp +++ b/src/plugins/bearer/symbian/symbianengine.cpp @@ -329,7 +329,27 @@ void SymbianEngine::updateConfigurationsL() cpPriv->connectionId = 0; cpPriv->state = QNetworkConfiguration::Defined; cpPriv->type = QNetworkConfiguration::ServiceNetwork; - cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; + + // determine purpose of this SNAP + TUint32 purpose = CMManager::ESnapPurposeUnknown; + TRAP_IGNORE(purpose = destination.MetadataL(CMManager::ESnapMetadataPurpose)); + switch (purpose) { + case CMManager::ESnapPurposeInternet: + cpPriv->purpose = QNetworkConfiguration::PublicPurpose; + break; + case CMManager::ESnapPurposeIntranet: + cpPriv->purpose = QNetworkConfiguration::PrivatePurpose; + break; + case CMManager::ESnapPurposeMMS: + case CMManager::ESnapPurposeOperator: + cpPriv->purpose = QNetworkConfiguration::ServiceSpecificPurpose; + break; + case CMManager::ESnapPurposeUnknown: + default: + cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; + break; + } + cpPriv->roamingSupported = false; QNetworkConfigurationPrivatePointer ptr(cpPriv); @@ -482,9 +502,39 @@ void SymbianEngine::updateConfigurationsL() #ifdef SNAP_FUNCTIONALITY_AVAILABLE updateStatesToSnaps(); + updatePurposeToIaps(); #endif } +//copy purpose from SNAP to child IAPs, unless child is contained in more than one SNAP with conflicting purposes. +void SymbianEngine::updatePurposeToIaps() +{ + QMutexLocker lock(&mutex); + QHash<QString,int> purposes; + foreach (QNetworkConfigurationPrivatePointer snap, snapConfigurations.values()) { + QMutexLocker snaplock(&snap->mutex); + foreach (QNetworkConfigurationPrivatePointer iap, snap->serviceNetworkMembers.values()) { + QMutexLocker iaplock(&iap->mutex); + QString id = iap->id; + if (purposes.contains(id) && purposes.value(id) != snap->purpose) + purposes[id] = -1; //conflict detected + else + purposes[id] = snap->purpose; + } + } + + for (QHash<QString,int>::const_iterator it = purposes.constBegin(); it != purposes.constEnd(); ++it) { + if (accessPointConfigurations.contains(it.key())) { + QNetworkConfigurationPrivatePointer iap = accessPointConfigurations.value(it.key()); + QMutexLocker iaplock(&iap->mutex); + int purpose = it.value(); + if (purpose == -1) //resolve conflicts as unknown + purpose = QNetworkConfiguration::UnknownPurpose; + iap->purpose = (QNetworkConfiguration::Purpose)purpose; + } + } +} + #ifdef SNAP_FUNCTIONALITY_AVAILABLE SymbianNetworkConfigurationPrivate *SymbianEngine::configFromConnectionMethodL( RCmConnectionMethod& connectionMethod) @@ -505,8 +555,33 @@ SymbianNetworkConfigurationPrivate *SymbianEngine::configFromConnectionMethodL( cpPriv->bearerType = QNetworkConfiguration::Bearer2G; break; case KCommDbBearerWcdma: - cpPriv->bearerType = QNetworkConfiguration::BearerWCDMA; - break; + { + //This is ambiguous, check the network status to find out what the expected connection will be + TUint mode; + TRequestStatus status; + iConnectionMonitor.GetUintAttribute(0, 0, KMobilePhoneNetworkMode, mode, status); + User::WaitForRequest(status); + if (status != KErrNone) + cpPriv->bearerType = QNetworkConfiguration::BearerUnknown; + else switch (mode) { + case EConnMonNetworkModeCdma2000: + cpPriv->bearerType = QNetworkConfiguration::BearerCDMA2000; + break; + case EConnMonNetworkModeWcdma: + case EConnMonNetworkModeTdcdma: + cpPriv->bearerType = QNetworkConfiguration::BearerWCDMA; //includes HSDPA, as this API can't detect it + break; + case EConnMonNetworkModeGsm: + case EConnMonNetworkModeAmps: + case EConnMonNetworkModeCdma95: + cpPriv->bearerType = QNetworkConfiguration::Bearer2G; //includes GPRS and EDGE, Qt API treats them both as 2G + break; + default: + cpPriv->bearerType = QNetworkConfiguration::BearerUnknown; + break; + } + break; + } case KCommDbBearerLAN: cpPriv->bearerType = QNetworkConfiguration::BearerEthernet; break; @@ -1122,6 +1197,13 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) } ); } + + //update bearer type for 2G/3G connections + TInt bearer; + iConnectionMonitor.GetIntAttribute(connectionId, 0, KBearerInfo, bearer, status); + User::WaitForRequest(status); + if (status == KErrNone) + updateMobileBearerToConfigs(TConnMonBearerInfo(bearer)); } else if (connectionStatus == KConfigDaemonStartingDeregistration) { TUint connectionId = realEvent->ConnectionId(); QNetworkConfigurationPrivatePointer ptr = dataByConnectionId(connectionId); diff --git a/src/plugins/bearer/symbian/symbianengine.h b/src/plugins/bearer/symbian/symbianengine.h index a205c97..b75f27e 100644 --- a/src/plugins/bearer/symbian/symbianengine.h +++ b/src/plugins/bearer/symbian/symbianengine.h @@ -155,6 +155,7 @@ public Q_SLOTS: private: void updateStatesToSnaps(); + void updatePurposeToIaps(); bool changeConfigurationStateTo(QNetworkConfigurationPrivatePointer ptr, QNetworkConfiguration::StateFlags newState); bool changeConfigurationStateAtMinTo(QNetworkConfigurationPrivatePointer ptr, diff --git a/src/plugins/codecs/cn/qgb18030codec.cpp b/src/plugins/codecs/cn/qgb18030codec.cpp index 0a45eeb..d12f5d9 100644 --- a/src/plugins/codecs/cn/qgb18030codec.cpp +++ b/src/plugins/codecs/cn/qgb18030codec.cpp @@ -108,10 +108,10 @@ QByteArray QGb18030Codec::convertFromUnicode(const QChar *uc, int len, Converter int len; uchar buf[4]; if (high >= 0) { - if (ch >= 0xdc00 && ch < 0xe000) { + if (uc[i].isLowSurrogate()) { // valid surrogate pair ++i; - uint u = (high-0xd800)*0x400+(ch-0xdc00)+0x10000; + uint u = QChar::surrogateToUcs4(high, uc[i].unicode()); len = qt_UnicodeToGb18030(u, buf); if (len >= 2) { for (int j=0; j<len; j++) @@ -129,10 +129,10 @@ QByteArray QGb18030Codec::convertFromUnicode(const QChar *uc, int len, Converter } } - if (ch < 0x80) { + if (IsLatin(ch)) { // ASCII *cursor++ = ch; - } else if ((ch >= 0xd800 && ch < 0xdc00)) { + } else if (uc[i].isHighSurrogate()) { // surrogates area. check for correct encoding // we need at least one more character, first the high surrogate, then the low one high = ch; @@ -181,7 +181,7 @@ QString QGb18030Codec::convertToUnicode(const char* chars, int len, ConverterSta uchar ch = chars[i]; switch (nbuf) { case 0: - if (ch < 0x80) { + if (IsLatin(ch)) { // ASCII resultData[unicodeLen] = ch; ++unicodeLen; @@ -339,7 +339,7 @@ QString QGbkCodec::convertToUnicode(const char* chars, int len, ConverterState * uchar ch = chars[i]; switch (nbuf) { case 0: - if (ch < 0x80) { + if (IsLatin(ch)) { // ASCII resultData[unicodeLen] = ch; ++unicodeLen; @@ -487,7 +487,7 @@ QString QGb2312Codec::convertToUnicode(const char* chars, int len, ConverterStat uchar ch = chars[i]; switch (nbuf) { case 0: - if (ch < 0x80) { + if (IsLatin(ch)) { // ASCII resultData[unicodeLen] = ch; ++unicodeLen; diff --git a/src/plugins/sqldrivers/symsql/main.cpp b/src/plugins/sqldrivers/symsql/main.cpp new file mode 100644 index 0000000..5dfa9f4 --- /dev/null +++ b/src/plugins/sqldrivers/symsql/main.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtSql module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qsqldriverplugin.h> +#include <QStringList> +#include "../../../sql/drivers/symsql/qsql_symsql.h" + +QT_BEGIN_NAMESPACE + +class QSymSQLDriverPlugin : public QSqlDriverPlugin +{ +public: + QSymSQLDriverPlugin(); + + QSqlDriver* create(const QString &); + QStringList keys() const; +}; + +QSymSQLDriverPlugin::QSymSQLDriverPlugin() + : QSqlDriverPlugin() +{ +} + +QSqlDriver* QSymSQLDriverPlugin::create(const QString &name) +{ + if (name == QLatin1String("QSYMSQL")) { + QSymSQLDriver* driver = new QSymSQLDriver(); + return driver; + } + return 0; +} + +QStringList QSymSQLDriverPlugin::keys() const +{ + QStringList l; + l.append(QLatin1String("QSYMSQL")); + return l; +} + +Q_EXPORT_STATIC_PLUGIN(QSymSQLDriverPlugin) +Q_EXPORT_PLUGIN2(qsymsql, QSymSQLDriverPlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/sqldrivers/symsql/symsql.pro b/src/plugins/sqldrivers/symsql/symsql.pro new file mode 100644 index 0000000..8b8434c --- /dev/null +++ b/src/plugins/sqldrivers/symsql/symsql.pro @@ -0,0 +1,13 @@ +TARGET = qsymsql +PLUGIN_TYPE = sqldrivers +SOURCES = main.cpp + +include(../../../sql/drivers/symsql/qsql_symsql.pri) +include(../qsqldriverbase.pri) + +symbian: { +pluginDep.sources = $${TARGET}.dll +pluginDep.path = $${QT_PLUGINS_BASE_DIR}/$${PLUGIN_TYPE} +DEPLOYMENT += pluginDep +} + diff --git a/src/sql/drivers/symsql/qsql_symsql.cpp b/src/sql/drivers/symsql/qsql_symsql.cpp new file mode 100644 index 0000000..4ceac9b --- /dev/null +++ b/src/sql/drivers/symsql/qsql_symsql.cpp @@ -0,0 +1,1185 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtSql module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsql_symsql.h" + + +#define SYMBIAN_ENABLE_PUBLIC_PLATFORM_HEADER_SPLIT + +#include <qcoreapplication.h> +#include <qvariant.h> +#include <qsqlerror.h> +#include <qsqlfield.h> +#include <qsqlindex.h> +#include <qsqlquery.h> +#include <qstringlist.h> +#include <qvector.h> +#include <qdebug.h> +#include "../../../corelib/kernel/qcore_symbian_p.h" + +#if defined Q_OS_WIN +# include <qt_windows.h> +#else +# include <unistd.h> +#endif + +#include <sqldb.h> +#include <e32capability.h> + +const char* qCapabilityNames[ECapability_Limit] = +{ + "TCB", + "CommDD", + "PowerMgmt", + "MultimediaDD", + "ReadDeviceData", + "WriteDeviceData", + "DRM", + "TrustedUI", + "ProtServ", + "DiskAdmin", + "NetworkControl", + "AllFiles", + "SwEvent", + "NetworkServices", + "LocalServices", + "ReadUserData", + "WriteUserData", + "Location", + "SurroundingsDD", + "UserEnvironment" +}; + +const char qCapabilityNone[] = "None"; + + +Q_DECLARE_METATYPE(RSqlDatabase) +Q_DECLARE_METATYPE(RSqlStatement) + +QT_BEGIN_NAMESPACE + +const QString valueSeparator(QLatin1String("=")); +const QString fieldSeparator(QLatin1String(",")); + +static QString _q_escapeIdentifier(const QString &identifier) +{ + QString res = identifier; + if (!identifier.isEmpty() + && identifier.left(1) != QString(QLatin1Char('"')) + && identifier.right(1) != QString(QLatin1Char('"'))) { + res.replace(QLatin1Char('"'), QLatin1String("\"\"")); + res.prepend(QLatin1Char('"')).append(QLatin1Char('"')); + res.replace(QLatin1Char('.'), QLatin1String("\".\"")); + } + return res; +} + +static QVariant::Type qGetColumnType(const TSqlColumnType coltype) +{ + switch(coltype){ + case ESqlInt: + case ESqlInt64: + return QVariant::Int; + case ESqlReal: + return QVariant::Double; + case ESqlBinary: + return QVariant::ByteArray; + case ESqlText: + case ESqlNull: + default: + return QVariant::String; + } +} + +static QVariant::Type qGetColumnType(const QString &tpName) +{ + const QString typeName = tpName.toLower(); + + if (typeName == QLatin1String("integer") + || typeName == QLatin1String("int")) + return QVariant::Int; + if (typeName == QLatin1String("double") + || typeName == QLatin1String("float") + || typeName == QLatin1String("real") + || typeName.startsWith(QLatin1String("numeric"))) + return QVariant::Double; + if (typeName == QLatin1String("blob")) + return QVariant::ByteArray; + return QVariant::String; +} + +static QSqlError qMakeError(RSqlDatabase& access, + const QString &descr, + QSqlError::ErrorType type, + int errorCode = -1) +{ + return QSqlError(descr, + QString::fromUtf16(static_cast<const ushort *>(access.LastErrorMessage().Ptr())), + type, + errorCode); +} + + +static QSqlError gMakeErrorOpen(const QString &descr, + QSqlError::ErrorType type, + TInt errorCode) +{ + return QSqlError(descr, QLatin1String(""), type, errorCode); +} + +class QSymSQLDriverPrivate +{ +public: + inline QSymSQLDriverPrivate() {} + RSqlDatabase access; +}; + +class QSymSQLResultPrivate +{ +public: + QSymSQLResultPrivate(QSymSQLResult *res); + void cleanup(); + bool fetchNext(bool initialFetch); + // initializes the recordInfo + void initColumns(QSqlRecord& rec); + void finalize(); + + QSymSQLResult* q; + RSqlDatabase access; + RSqlStatement stmt; + bool skipRow; // skip the next fetchNext()? + bool skippedStatus; // the status of the fetchNext() that's skipped + bool prepareCalled; +}; + +QSymSQLResultPrivate::QSymSQLResultPrivate(QSymSQLResult* res) : q(res), + skipRow(false), + skippedStatus(false), + prepareCalled(false) +{ +} + +void QSymSQLResultPrivate::cleanup() +{ + finalize(); + skippedStatus = false; + skipRow = false; + q->setAt(QSql::BeforeFirstRow); + q->setActive(false); +} + +void QSymSQLResultPrivate::finalize() +{ + prepareCalled = false; + stmt.Close(); +} + +void QSymSQLResultPrivate::initColumns(QSqlRecord& rec) +{ + int nCols = stmt.ColumnCount(); + if (nCols <= 0) { + q->setLastError(qMakeError(access, QCoreApplication::translate("QSymSQLResult", + "Error retreving column count"), QSqlError::UnknownError, nCols)); + return; + } + + for (int i = 0; i < nCols; ++i) { + TPtrC cName; + TInt err = stmt.ColumnName(i, cName); + + if (err != KErrNone) { + q->setLastError(qMakeError(access, QCoreApplication::translate("QSymSQLResult", + "Error retreving column name"), QSqlError::UnknownError, err)); + return; + } + + QString colName = qt_TDesC2QString(cName); + + // must use typeName for resolving the type to match QSymSQLDriver::record + TPtrC tName; + TSqlColumnType decColType; + err = stmt.DeclaredColumnType(i, decColType); + + if (err != KErrNone) { + q->setLastError(qMakeError(access, QCoreApplication::translate("QSymSQLResult", + "Error retreving column type"), QSqlError::UnknownError, err)); + return; + } + + int dotIdx = colName.lastIndexOf(QLatin1Char('.')); + QSqlField fld(colName.mid(dotIdx == -1 ? 0 : dotIdx + 1), qGetColumnType(decColType)); + + rec.append(fld); + } +} + +bool QSymSQLResultPrivate::fetchNext(bool initialFetch) +{ + int res; + + if (skipRow) { + // already fetched + Q_ASSERT(!initialFetch); + skipRow = false; + return skippedStatus; + } + + skipRow = initialFetch; + res = stmt.Next(); + + switch(res) { + case KSqlAtRow: + return true; + case KSqlAtEnd: + stmt.Reset(); + return false; + case KSqlErrGeneral: + // KSqlErrGeneral is a generic error code and we must call stmt.Reset() + // to get the specific error message. + stmt.Reset(); + q->setLastError(qMakeError(access, QCoreApplication::translate("QSymSQLResult", + "Unable to fetch row"), QSqlError::ConnectionError, res)); + q->setAt(QSql::AfterLastRow); + return false; + case KSqlErrMisuse: + case KSqlErrBusy: + default: + // something wrong, don't get col info, but still return false + q->setLastError(qMakeError(access, QCoreApplication::translate("QSymSQLResult", + "Unable to fetch row"), QSqlError::ConnectionError, res)); + stmt.Reset(); + q->setAt(QSql::AfterLastRow); + return false; + } + return false; +} + +////////////////////////////////// QSymSQLResult ///////////////////////////////////////////////// + +QSymSQLResult::QSymSQLResult(const QSymSQLDriver* db) + : QSqlResult(db) +{ + d = new QSymSQLResultPrivate(this); + d->access = db->d->access; +} + + +QSymSQLResult::~QSymSQLResult() +{ + d->cleanup(); + delete d; +} + +bool QSymSQLResult::reset(const QString &query) +{ + if (!prepare(query)) + return false; + + return exec(); +} + +bool QSymSQLResult::prepare(const QString &query) +{ + if (!driver() || !driver()->isOpen() || driver()->isOpenError()) + return false; + + d->cleanup(); + setSelect(false); + + TInt res = d->stmt.Prepare(d->access, qt_QString2TPtrC(query)); + + if (res != KErrNone) { + setLastError(qMakeError(d->access, QCoreApplication::translate("QSymSQLResult", + "Unable to execute statement"), QSqlError::StatementError, res)); + d->finalize(); + return false; + } + + d->prepareCalled = true; + + return true; +} + +bool QSymSQLResult::exec() +{ + if (d->prepareCalled == false) { + setLastError(qMakeError(d->access, QCoreApplication::translate("QSymSQLResult", + "Statement is not prepared"), QSqlError::StatementError, KErrGeneral)); + return false; + } + + const QVector<QVariant> values = boundValues(); + + d->skippedStatus = false; + d->skipRow = false; + setAt(QSql::BeforeFirstRow); + setLastError(QSqlError()); + int res = d->stmt.Reset(); + + if (res != KErrNone) { + setLastError(qMakeError(d->access, QCoreApplication::translate("QSymSQLResult", + "Unable to reset statement"), QSqlError::StatementError, res)); + d->finalize(); + return false; + } + TPtrC tmp; + TInt paramCount = 0; + while (d->stmt.ParamName(paramCount, tmp) == KErrNone) + paramCount++; + + if (paramCount == values.count()) { + for (int i = 0; i < paramCount; ++i) { + res = KErrNone; + const QVariant value = values.at(i); + + if (value.isNull()) { + res = d->stmt.BindNull(i); //replaced i + 1 with i + } else { + switch (value.type()) { + case QVariant::ByteArray: { + const QByteArray *ba = static_cast<const QByteArray*>(value.constData()); + TPtrC8 data(reinterpret_cast<const TUint8 *>(ba->constData()), ba->length()); + res = d->stmt.BindBinary(i, data); //replaced i + 1 with i + break; } + case QVariant::Int: + res = d->stmt.BindInt(i, value.toInt()); //replaced i + 1 with i + break; + case QVariant::Double: + res = d->stmt.BindReal(i, value.toDouble()); //replaced i + 1 with i + + break; + case QVariant::UInt: + case QVariant::LongLong: + res = d->stmt.BindReal(i, value.toLongLong()); //replaced i + 1 with i + break; + + case QVariant::String: { + // lifetime of string == lifetime of its qvariant + const QString *str = static_cast<const QString*>(value.constData()); + res = d->stmt.BindText(i, qt_QString2TPtrC(*str)); // replaced i + 1 with i + break; } + default: { + QString str = value.toString(); + res = d->stmt.BindText(i, qt_QString2TPtrC(str)); //replaced i + 1 with i + break; } + } + } + if (res != KErrNone) { + setLastError(qMakeError(d->access, QCoreApplication::translate("QSymSQLResult", + "Unable to bind parameters"), QSqlError::StatementError, res)); + d->finalize(); + return false; + } + } + } else { + setLastError(QSqlError(QCoreApplication::translate("QSymSQLResult", + "Parameter count mismatch"), QString(), QSqlError::StatementError)); + return false; + } + + d->skippedStatus = d->fetchNext(true); + + if (lastError().isValid()) { + setSelect(false); + setActive(false); + return false; + } + + if (d->stmt.ColumnCount() > 0) { + //If there is something, it has to be select + setSelect(true); + } else { + //If there isn't it might be just bad query, let's check manually whether we can find SELECT + QString query = this->lastQuery(); + query = query.trimmed(); + query = query.toLower(); + + //Just check whether there is one in the beginning, don't know if this is enough + //Comments should be at the end of line if those are passed + //For some reason, case insensitive indexOf didn't work for me + if (query.indexOf(QLatin1String("select")) == 0) { + setSelect(true); + } else { + setSelect(false); + } + } + + setActive(true); + return true; +} + + +int QSymSQLResult::size() +{ + return -1; +} + +int QSymSQLResult::numRowsAffected() +{ + return -1; +} + +QVariant QSymSQLResult::lastInsertId() const +{ + if (isActive()) { + qint64 id = static_cast<qint64>(d->access.LastInsertedRowId()); + if (id) + return id; + } + + return QVariant(); +} + +QSqlRecord QSymSQLResult::record() const +{ + if (!isActive() || !isSelect()) + return QSqlRecord(); + + QSqlRecord res; + d->initColumns(res); + + return res; +} + +QVariant QSymSQLResult::handle() const +{ + return qVariantFromValue(d->stmt); +} + + +void QSymSQLResult::virtual_hook(int id, void *data) +{ + switch (id) + { + case QSqlResult::DetachFromResultSet: + d->stmt.Reset(); + break; + default: + QSqlResult::virtual_hook(id, data); + } +} + +QVariant QSymSQLResult::data(int idx) +{ + QVariant r; + + switch (d->stmt.ColumnType(idx)) { + case ESqlBinary: + { + TPtrC8 data; + d->stmt.ColumnBinary(idx, data); + return QByteArray(reinterpret_cast<const char *>(data.Ptr()), data.Length()); + break; + } + case ESqlInt: + r = QVariant(d->stmt.ColumnInt(idx)); + break; + case ESqlInt64: + r = QVariant(d->stmt.ColumnInt64(idx)); + break; + case ESqlReal: + switch(numericalPrecisionPolicy()) { + case QSql::LowPrecisionInt32: + r = QVariant(d->stmt.ColumnInt(idx)); + break; + case QSql::LowPrecisionInt64: + r = QVariant(d->stmt.ColumnInt64(idx)); + break; + case QSql::LowPrecisionDouble: + r = QVariant(d->stmt.ColumnReal(idx)); + break; + case QSql::HighPrecision: + default: + TPtrC res; + d->stmt.ColumnText(idx, res); + r = QVariant(qt_TDesC2QString(res)); + break; + }; + break; + case ESqlNull: + r = QVariant(QVariant::String); + break; + default: + TPtrC res; + d->stmt.ColumnText(idx, res); + r = QVariant(qt_TDesC2QString(res)); + break; + } + + return r; +} + +bool QSymSQLResult::isNull(int i) +{ + return d->stmt.IsNull(i); +} + +bool QSymSQLResult::fetch(int i) +{ + //Single return point modified according to review + bool retVal = true; + + if (i < 0 || !isActive()) { + retVal = false; + } else { + if (at() <= -1 || i < at()) { + d->stmt.Reset(); + setAt(-1); + d->skipRow = false; + } + + while (at() < i) { + if (!d->fetchNext(false)) { + retVal = false; + break; + } + + setAt(at() + 1); + } + } + + return retVal; +} + +bool QSymSQLResult::fetchNext() +{ + bool res = d->fetchNext(false); + if (res) { + setAt(at()+1); + } + + return res; +} + +bool QSymSQLResult::fetchPrevious() +{ + return QSqlResult::fetchPrevious(); +} + +bool QSymSQLResult::fetchFirst() +{ + return fetch(0); +} + +bool QSymSQLResult::fetchLast() +{ + if (!isActive()) + return false; + + if (at() <= -1) { + if (!fetchFirst()) + return false; + } + + TInt res; + + do { + res = d->stmt.Next(); + setAt(at()+1); + } while (res == KSqlAtRow); + + if (res != KSqlAtEnd) + return false; + + d->skippedStatus = false; + d->skipRow = false; + + return fetchPrevious(); +} +////////////////////////////////// QSymSQLDriver ////////////////////////////////////////// + +QSymSQLDriver::QSymSQLDriver(QObject * parent) + : QSqlDriver(parent) +{ + d = new QSymSQLDriverPrivate(); +} + +QSymSQLDriver::QSymSQLDriver(RSqlDatabase& connection, QObject *parent) + : QSqlDriver(parent) +{ + d = new QSymSQLDriverPrivate(); + d->access = connection; + setOpen(true); + setOpenError(false); +} + + +QSymSQLDriver::~QSymSQLDriver() +{ + d->access.Close(); + delete d; +} + +bool QSymSQLDriver::hasFeature(DriverFeature f) const +{ + switch (f) { + case BLOB: + case Transactions: + case Unicode: + case PreparedQueries: + case PositionalPlaceholders: + case SimpleLocking: + case FinishQuery: + case LowPrecisionNumbers: + case LastInsertId: + case NamedPlaceholders: + return true; + case QuerySize: + case BatchOperations: + case EventNotifications: + case MultipleResultSets: + return false; + } + return false; +} + +/*! + Converts capability string to TCapability +*/ +TCapability qMatchCapStr(QString& str) +{ + TCapability cap = ECapability_HardLimit; + + for (int i = 0; i < static_cast<int>(ECapability_Limit); i++) { + if (str.compare(QLatin1String(qCapabilityNames[i]), Qt::CaseInsensitive) == 0) { + cap = static_cast<TCapability>(i); + break; + } + } + + //Special case, we allow ECapability_None to be defined + if (cap == ECapability_HardLimit + && str.compare(QLatin1String(qCapabilityNone), Qt::CaseInsensitive) == 0) + cap = ECapability_None; + + return cap; +} + +bool qExtractSecurityPolicyFromString(const QString &string, TSecurityPolicy &policy) +{ + int startPos = string.indexOf(QLatin1Char('=')); + QStringList values; + bool ret = false; + + if (startPos == -1) { + values = string.split(QLatin1Char(','), QString::SkipEmptyParts); + } else { + values = string.mid(startPos + 1).split(QLatin1Char(','), QString::SkipEmptyParts); + } + + if (values.count() > 0) { + const QString findVid(QLatin1String("vid[")); + const QString findSid(QLatin1String("sid[")); + const int MaxCapCount = 7; + const int VidMaxCount = 3; + const int SidMaxCount = 3; + + TCapability capList[MaxCapCount] = { ECapability_None,ECapability_None,ECapability_None, + ECapability_None,ECapability_None,ECapability_None,ECapability_None }; + + bool isVID = false; + bool isSID = false; + + QString idString(QLatin1String("")); + int maxAllowed = MaxCapCount; + + if (values[0].contains(findVid, Qt::CaseInsensitive)) { + idString = values[0].remove(findVid, Qt::CaseInsensitive); + idString = idString.remove(QLatin1Char(']')); + values.removeAt(0); + isVID = true; + maxAllowed = VidMaxCount; + + } else if (values[0].contains(findSid, Qt::CaseInsensitive)) { + idString = values[0].remove(findSid, Qt::CaseInsensitive); + idString = idString.remove(QLatin1Char(']')); + values.removeAt(0); + isSID = true; + maxAllowed = SidMaxCount; + } + + if (values.count() <= maxAllowed) { + bool wasSuccesful = true; + + for (int i = 0; i < values.count(); i++) { + capList[i] = qMatchCapStr(values[i]); + + if (capList[i] == ECapability_HardLimit) { + wasSuccesful = false; + break; + } + } + + if (wasSuccesful) { + if (isVID || isSID){ + bool ok = true; + quint32 id = idString.toUInt(&ok, 16); + + if (ok) { + if (isVID) { + TVendorId vid(id); + policy = TSecurityPolicy(vid, capList[0], capList[1], capList[2]); + } else { + TSecureId sid(id); + policy = TSecurityPolicy(sid, capList[0], capList[1], capList[2]); + } + + ret = true; //Everything is fine + } + } else { + policy = TSecurityPolicy(capList[0], capList[1], capList[2], capList[3], + capList[4], capList[5], capList[6]); + + ret = true; //Everything is fine + } + } + } + } + + return ret; +} + +/*! + Opens the database connection using the given connection options. Returns true on success; otherwise returns false. + Error information can be retrieved using the lastError() function. Symbian SQL dbs have no \a user, \a password, \a host + or \a port just file names. + + \a connOpts Connection options hold definition for security policies and all parameters that does not contain "POLICY_" will be + passed to RSqlDatabase. Policy will be filled according to parsed values. + + Value in database wide parameters starts by definition which can be vendorId or secureId. These come directly from TSecurityPolicy class in Symbian. + + POLICY_DB_DEFAULT + Default security policy which will be used for the database and all database objects. POLICY_DB_DEFAULT must be + defined before any other policy definitions can be used. + POLICY_DB_READ + Read database security policy. An application with read database security policy can read from database. + POLICY_DB_WRITE: + Write database security policy. An application with write database security policy can write to database. + POLICY_DB_SCHEMA: + Schema database security policy. An application with schema database security policy can modify + the database schema, write to database, read from database. + + Format: + POLICY_DB_DEFAULT=cap1,cap2,cap3,cap4,cap5,cap6,cap7 (Up to 7 capabilities) + POLICY_DB_READ=cap1,cap2,cap3,cap4,cap5,cap6,cap7 (Up to 7 capabilities) + POLICY_DB_WRITE=vendorid,cap1,cap2,cap3 (Vendor ID and up to 3 capabilities) + POLICY_DB_SCHEMA=secureid,cap1,cap2,cap3 (Secure ID and up to 3 capabilities) + + Table policies does not support schema policy as database level does. + + Table specific parameters would be as: + POLICY_TABLE_WRITE=tablename,cap1,cap2,cap3,cap4,cap5,cap6,cap7 + POLICY_TABLE_READ=tablename,cap1,cap2,cap3,cap4,cap5,cap6,cap7 + + Vendor Id and Secure id format: + vid[0x12345678] (Hex) + sid[0x12345678] (Hex) + + Example: + \code + QSqlDatabase database = QSqlDatabase::addDatabase("QSYMSQL", "MyConnection"); + database.setConnectOptions("POLICY_DB_DEFAULT=ReadDeviceData"); + database.setDatabaseName("[12345678]myDatabase"); + bool ok = database.open(); + \encode + + \code + QSqlDatabase database = QSqlDatabase::addDatabase("QSYMSQL", "MyConnection"); + database.setConnectOptions("POLICY_DB_DEFAULT=None; POLICY_DB_WRITE=sid[0x12345678], WriteDeviceData"); + database.setDatabaseName("[12345678]myDatabase"); + bool ok = database.open(); + \encode + + FOREIGN KEY: + Enabling foreign key support from underlying SQLite + add: "foreign_keys = ON" to your connection options string. This will be passes to SQLite. + + Foreign key Example: + \code + QSqlDatabase database = QSqlDatabase::addDatabase("QSYMSQL", "MyConnection"); + database.setDatabaseName("[12345678]myDatabase"); + database.setConnectOptions("foreign_keys = ON"); + bool ok = database.open(); + \encode + + More information about Symbian Security Policy can be found from Symbian documentation. + +*/ +bool QSymSQLDriver::open(const QString & db, const QString &, const QString &, const QString &, int, const QString &conOpts) +{ + if (isOpen()) + close(); + if (db.isEmpty()) + return false; + + //Separating our parameters from Symbian ones and construct new connection options + const QString itemSeparator(QLatin1String(";")); + QRegExp isOurOption(QLatin1String("POLICY_*"), Qt::CaseInsensitive, QRegExp::Wildcard); + + QStringList optionList = conOpts.split(itemSeparator, QString::SkipEmptyParts); + QStringList symbianList; + + for (int i = optionList.count() - 1; i >= 0; i--) { + if (!optionList[i].contains(isOurOption)) { + symbianList.append(optionList[i]); + optionList.removeAt(i); + } else { + //Removing whitespace + QString formatted = optionList[i]; + formatted = formatted.remove(QLatin1Char(' ')); + formatted = formatted.remove(QLatin1Char('\t')); + formatted = formatted.remove(QLatin1Char('\n')); + formatted = formatted.remove(QLatin1Char('\r')); + optionList[i] = formatted; + } + } + + QString symbianOpt; + + for (int i = 0; i < symbianList.count(); i++) { + symbianOpt += symbianList[i]; + symbianOpt += itemSeparator; + } + + TPtrC dbName(qt_QString2TPtrC(db)); + QByteArray conOpts8 = symbianOpt.toUtf8(); + const TPtrC8 config(reinterpret_cast<const TUint8*>(conOpts8.constData()), (conOpts8.length())); + + TInt res = d->access.Open(dbName, &config); + + if (res == KErrNotFound) { + + QRegExp findDefault(QLatin1String("POLICY_DB_DEFAULT=*"), Qt::CaseInsensitive, QRegExp::Wildcard); + QRegExp findRead(QLatin1String("POLICY_DB_READ=*"), Qt::CaseInsensitive, QRegExp::Wildcard); + QRegExp findWrite(QLatin1String("POLICY_DB_WRITE=*"), Qt::CaseInsensitive, QRegExp::Wildcard); + QRegExp findSchema(QLatin1String("POLICY_DB_SCHEMA=*"), Qt::CaseInsensitive, QRegExp::Wildcard); + QRegExp findTableRead(QLatin1String("POLICY_TABLE_READ=*"), Qt::CaseInsensitive, QRegExp::Wildcard); + QRegExp findTableWrite(QLatin1String("POLICY_TABLE_WRITE=*"), Qt::CaseInsensitive, QRegExp::Wildcard); + + int policyIndex = optionList.indexOf(findDefault); + + if (policyIndex != -1) { + QString defaultPolicyString = optionList[policyIndex]; + optionList.removeAt(policyIndex); + + TSecurityPolicy policyItem; + + if (qExtractSecurityPolicyFromString(defaultPolicyString, policyItem)) { + RSqlSecurityPolicy policy; + res = policy.Create(policyItem); + + if (res == KErrNone) { + for (int i = 0; i < optionList.count(); i++) { + QString option = optionList[i]; + + if (option.contains(findRead)) { + if (qExtractSecurityPolicyFromString(option, policyItem)) { + res = policy.SetDbPolicy(RSqlSecurityPolicy::EReadPolicy, policyItem); + } else { + res = KErrArgument; + } + } else if (option.contains(findWrite)) { + if (qExtractSecurityPolicyFromString(option, policyItem)) { + res = policy.SetDbPolicy(RSqlSecurityPolicy::EWritePolicy, policyItem); + } else { + res = KErrArgument; + } + } else if (option.contains(findSchema)) { + if (qExtractSecurityPolicyFromString(option, policyItem)) { + res = policy.SetDbPolicy(RSqlSecurityPolicy::ESchemaPolicy, policyItem); + } else { + res = KErrArgument; + } + } else if (option.contains(findTableWrite)) { + QString tableOption = option.mid(option.indexOf(QLatin1Char('=')) + 1); + int firstComma = tableOption.indexOf(QLatin1Char(',')); + + if (firstComma != -1) { + QString tableName = tableOption.left(firstComma); + tableOption = tableOption.mid(firstComma + 1); + + if (qExtractSecurityPolicyFromString(tableOption, policyItem)) { + TPtrC symTableName(qt_QString2TPtrC(tableName)); + + res = policy.SetPolicy(RSqlSecurityPolicy::ETable, symTableName, + RSqlSecurityPolicy::EWritePolicy, policyItem); + } else { + res = KErrArgument; + } + } else { + res = KErrArgument; + } + } else if (option.contains(findTableRead)) { + QString tableOption = option.mid(option.indexOf(QLatin1Char('=')) + 1); + int firstComma = tableOption.indexOf(QLatin1Char(',')); + + if (firstComma != -1) { + QString tableName = tableOption.left(firstComma); + tableOption = tableOption.mid(firstComma + 1); + + if (qExtractSecurityPolicyFromString(tableOption, policyItem)) { + TPtrC symTableName(qt_QString2TPtrC(tableName)); + + res = policy.SetPolicy(RSqlSecurityPolicy::ETable, symTableName, + RSqlSecurityPolicy::EReadPolicy, policyItem); + } else { + res = KErrArgument; + } + } else { + res = KErrArgument; + } + } else { + res = KErrArgument; + } + + if (res != KErrNone) { + setLastError(gMakeErrorOpen(tr("Invalid option: ") + option, QSqlError::ConnectionError, res)); + break; + } + } + + if (res == KErrNone) { + res = d->access.Create(dbName, policy, &config); + policy.Close(); + + if (res != KErrNone) + setLastError(gMakeErrorOpen(tr("Error opening database"), QSqlError::ConnectionError, res)); + } + } + + } else { + res = KErrArgument; + setLastError(gMakeErrorOpen(tr("Invalid option: ") + defaultPolicyString, QSqlError::ConnectionError, res)); + } + + } else { + //Check whether there is some of our options, fail if so. + policyIndex = optionList.indexOf(isOurOption); + + if (policyIndex == -1) { + res = d->access.Create(dbName, &config); + + if (res != KErrNone) + setLastError(gMakeErrorOpen(tr("Error opening database"), QSqlError::ConnectionError, res)); + } else { + res = KErrArgument; + setLastError(gMakeErrorOpen(tr("POLICY_DB_DEFAULT must be defined before any other POLICY definitions can be used"), QSqlError::ConnectionError, res)); + } + } + } + + if (res == KErrNone) { + setOpen(true); + setOpenError(false); + return true; + } else { + setOpenError(true); + return false; + } +} + +void QSymSQLDriver::close() +{ + if (isOpen()) { + d->access.Close(); + setOpen(false); + setOpenError(false); + } +} + +QSqlResult *QSymSQLDriver::createResult() const +{ + return new QSymSQLResult(this); +} + +bool QSymSQLDriver::beginTransaction() +{ + if (!isOpen() || isOpenError()) + return false; + + TInt err = d->access.Exec(_L("BEGIN")); + if (err < KErrNone) { + setLastError(QSqlError(tr("Unable to begin transaction"), + qt_TDesC2QString(d->access.LastErrorMessage()), QSqlError::TransactionError, err)); + return false; + } + + return true; +} + +bool QSymSQLDriver::commitTransaction() +{ + if (!isOpen() || isOpenError()) + return false; + + TInt err = d->access.Exec(_L("COMMIT")); + if (err < KErrNone) { + setLastError(QSqlError(tr("Unable to commit transaction"), + qt_TDesC2QString(d->access.LastErrorMessage()), QSqlError::TransactionError, err)); + return false; + } + + return true; +} + +bool QSymSQLDriver::rollbackTransaction() +{ + if (!isOpen() || isOpenError()) + return false; + + TInt err = d->access.Exec(_L("ROLLBACK")); + if (err < KErrNone) { + setLastError(QSqlError(tr("Unable to rollback transaction"), + qt_TDesC2QString(d->access.LastErrorMessage()), QSqlError::TransactionError, err)); + return false; + } + + return true; +} + +QStringList QSymSQLDriver::tables(QSql::TableType type) const +{ + QStringList res; + if (!isOpen()) + return res; + + QSqlQuery q(createResult()); + q.setForwardOnly(true); + + QString sql = QLatin1String("SELECT name FROM sqlite_master WHERE %1 " + "UNION ALL SELECT name FROM sqlite_temp_master WHERE %1"); + if ((type & QSql::Tables) && (type & QSql::Views)) + sql = sql.arg(QLatin1String("type='table' OR type='view'")); + else if (type & QSql::Tables) + sql = sql.arg(QLatin1String("type='table'")); + else if (type & QSql::Views) + sql = sql.arg(QLatin1String("type='view'")); + else + sql.clear(); + + if (!sql.isEmpty() && q.exec(sql)) { + while (q.next()) + res.append(q.value(0).toString()); + } + + if (type & QSql::SystemTables) + // there are no internal tables beside this one: + res.append(QLatin1String("sqlite_master")); + + return res; +} + +static QSqlIndex qGetTableInfo(QSqlQuery &q, QString &tableName, bool onlyPIndex = false) +{ + QString dbName; + QString table(tableName); + int indexOfSeparator = tableName.indexOf(QLatin1Char('.')); + if (indexOfSeparator > -1) { + dbName = tableName.left(indexOfSeparator +1 ); + table = tableName.mid(indexOfSeparator + 1); + } + q.exec(QLatin1String("PRAGMA ") + dbName + QLatin1String("table_info (") + _q_escapeIdentifier(table) + QLatin1String(")")); + + const int NAME_IDX = 1; + const int TYPE_IDX = 2; + const int NOTNULL_IDX = 3; + const int DFLT_VALUE_IDX = 4; + const int PK_IDX = 5; + + QSqlIndex ind; + while (q.next()) { + bool isPk = q.value(PK_IDX).toInt(); + if (onlyPIndex && !isPk) + continue; + QString typeName = q.value(TYPE_IDX).toString().toLower(); + QSqlField fld(q.value(NAME_IDX).toString(), qGetColumnType(typeName)); + if (isPk && (typeName == QLatin1String("integer"))) + // INTEGER PRIMARY KEY fields are auto-generated in sqlite + // INT PRIMARY KEY is not the same as INTEGER PRIMARY KEY! + fld.setAutoValue(true); + fld.setRequired(q.value(NOTNULL_IDX).toInt() != 0); + fld.setDefaultValue(q.value(DFLT_VALUE_IDX)); + ind.append(fld); + } + return ind; +} + +QSqlIndex QSymSQLDriver::primaryIndex(const QString &tblname) const +{ + if (!isOpen()) + return QSqlIndex(); + + QString table = tblname; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + + QSqlQuery q(createResult()); + q.setForwardOnly(true); + return qGetTableInfo(q, table, true); +} + +QSqlRecord QSymSQLDriver::record(const QString &tbl) const +{ + if (!isOpen()) + return QSqlRecord(); + + QString table = tbl; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + + QSqlQuery q(createResult()); + q.setForwardOnly(true); + return qGetTableInfo(q, table); +} + +QVariant QSymSQLDriver::handle() const +{ + return qVariantFromValue(d->access); +} + +QString QSymSQLDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const +{ + Q_UNUSED(type); + return _q_escapeIdentifier(identifier); +} + +QT_END_NAMESPACE diff --git a/src/sql/drivers/symsql/qsql_symsql.h b/src/sql/drivers/symsql/qsql_symsql.h new file mode 100644 index 0000000..7fdc10f --- /dev/null +++ b/src/sql/drivers/symsql/qsql_symsql.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtSql module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSQL_SYMSQL_H +#define QSQL_SYMSQL_H + +#include <QtSql/qsqldriver.h> +#include <QtSql/qsqlresult.h> +#include <QtSql/private/qsqlcachedresult_p.h> + + + +#ifdef QT_PLUGIN +#define Q_EXPORT_SQLDRIVER_SYMSQL +#else +#define Q_EXPORT_SQLDRIVER_SYMSQL Q_SQL_EXPORT +#endif + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE +class QSymSQLDriverPrivate; +class QSymSQLResultPrivate; +class QSymSQLDriver; +class RSqlDatabase; + +class QSymSQLResult : public QSqlResult +{ + friend class QSymSQLDriver; + friend class QSymSQLResultPrivate; +public: + explicit QSymSQLResult(const QSymSQLDriver* db); + ~QSymSQLResult(); + QVariant handle() const; + +protected: + QVariant data(int field); + bool isNull(int i); + bool fetch(int i); + bool fetchNext(); + bool fetchPrevious(); + bool fetchFirst(); + bool fetchLast(); + + bool reset(const QString &query); + bool prepare(const QString &query); + bool exec(); + int size(); + int numRowsAffected(); + QSqlRecord record() const; + void virtual_hook(int id, void *data); + + QVariant lastInsertId() const; + +private: + QSymSQLResultPrivate* d; +}; + +class Q_EXPORT_SQLDRIVER_SYMSQL QSymSQLDriver : public QSqlDriver +{ + Q_OBJECT + friend class QSymSQLResult; +public: + explicit QSymSQLDriver(QObject *parent = 0); + explicit QSymSQLDriver(RSqlDatabase& connection, QObject *parent = 0); + ~QSymSQLDriver(); + bool hasFeature(DriverFeature f) const; + bool open(const QString & db, + const QString & user, + const QString & password, + const QString & host, + int port, + const QString & connOpts); + void close(); + QSqlResult *createResult() const; + bool beginTransaction(); + bool commitTransaction(); + bool rollbackTransaction(); + QStringList tables(QSql::TableType)const; + + QSqlRecord record(const QString& tablename) const; + QSqlIndex primaryIndex(const QString &table) const; + QVariant handle() const; + QString escapeIdentifier(const QString &identifier, IdentifierType) const; + +private: + QSymSQLDriverPrivate* d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSQL_SYMSQL_H diff --git a/src/sql/drivers/symsql/qsql_symsql.pri b/src/sql/drivers/symsql/qsql_symsql.pri new file mode 100644 index 0000000..e18cce9 --- /dev/null +++ b/src/sql/drivers/symsql/qsql_symsql.pri @@ -0,0 +1,5 @@ +HEADERS += $$PWD/qsql_symsql.h +SOURCES += $$PWD/qsql_symsql.cpp + +symbian::LIBS += -lsqldb + diff --git a/src/testlib/qtestxmlstreamer.h b/src/testlib/qtestxmlstreamer.h index 46318a9..d4a9079 100644 --- a/src/testlib/qtestxmlstreamer.h +++ b/src/testlib/qtestxmlstreamer.h @@ -40,7 +40,7 @@ ****************************************************************************/ #ifndef QTESTXMLSTREAMER_H -#define QTESXMLSTREAMER_H +#define QTESTXMLSTREAMER_H #include <QtTest/qtestbasicstreamer.h> diff --git a/src/xmlpatterns/schema/qnamespacesupport.cpp b/src/xmlpatterns/schema/qnamespacesupport.cpp index cb0cbf7..5e0aea6 100644 --- a/src/xmlpatterns/schema/qnamespacesupport.cpp +++ b/src/xmlpatterns/schema/qnamespacesupport.cpp @@ -59,8 +59,8 @@ NamespaceSupport::NamespaceSupport() { } -NamespaceSupport::NamespaceSupport(const NamePool::Ptr &namePool) - : m_namePool(namePool) +NamespaceSupport::NamespaceSupport(NamePool &namePool) + : m_namePool(&namePool) { // the XML namespace m_ns.insert(StandardPrefixes::xml, StandardNamespaces::xml); diff --git a/src/xmlpatterns/schema/qnamespacesupport_p.h b/src/xmlpatterns/schema/qnamespacesupport_p.h index 656026e..b61bf19 100644 --- a/src/xmlpatterns/schema/qnamespacesupport_p.h +++ b/src/xmlpatterns/schema/qnamespacesupport_p.h @@ -97,7 +97,7 @@ namespace QPatternist * * @param namePool The name pool where all processed names are stored in. */ - NamespaceSupport(const NamePool::Ptr &namePool); + NamespaceSupport(NamePool &namePool); /** * Adds a new prefix-to-namespace binding. @@ -160,7 +160,7 @@ namespace QPatternist private: typedef QHash<QXmlName::PrefixCode, QXmlName::NamespaceCode> NamespaceHash; - NamePool::Ptr m_namePool; + NamePool *m_namePool; QStack<NamespaceHash> m_nsStack; NamespaceHash m_ns; }; diff --git a/src/xmlpatterns/schema/qxsdcomplextype.cpp b/src/xmlpatterns/schema/qxsdcomplextype.cpp index 32e420a..fe97f04 100644 --- a/src/xmlpatterns/schema/qxsdcomplextype.cpp +++ b/src/xmlpatterns/schema/qxsdcomplextype.cpp @@ -130,12 +130,12 @@ QString XsdComplexType::displayName(const NamePool::Ptr &np) const void XsdComplexType::setWxsSuperType(const SchemaType::Ptr &type) { - m_superType = type; + m_superType = type.data(); } SchemaType::Ptr XsdComplexType::wxsSuperType() const { - return m_superType; + return SchemaType::Ptr(m_superType); } void XsdComplexType::setContext(const NamedSchemaComponent::Ptr &component) diff --git a/src/xmlpatterns/schema/qxsdcomplextype_p.h b/src/xmlpatterns/schema/qxsdcomplextype_p.h index 1b90e5d..f6c512e 100644 --- a/src/xmlpatterns/schema/qxsdcomplextype_p.h +++ b/src/xmlpatterns/schema/qxsdcomplextype_p.h @@ -385,7 +385,7 @@ namespace QPatternist virtual bool isDefinedBySchema() const; private: - SchemaType::Ptr m_superType; + SchemaType *m_superType; NamedSchemaComponent *m_context; DerivationMethod m_derivationMethod; bool m_isAbstract; diff --git a/src/xmlpatterns/schema/qxsdelement.cpp b/src/xmlpatterns/schema/qxsdelement.cpp index dda0f54..ab2b873 100644 --- a/src/xmlpatterns/schema/qxsdelement.cpp +++ b/src/xmlpatterns/schema/qxsdelement.cpp @@ -128,12 +128,12 @@ bool XsdElement::isElement() const void XsdElement::setType(const SchemaType::Ptr &type) { - m_type = type; + m_type = type.data(); } SchemaType::Ptr XsdElement::type() const { - return m_type; + return SchemaType::Ptr(m_type); } void XsdElement::setScope(const Scope::Ptr &scope) diff --git a/src/xmlpatterns/schema/qxsdelement_p.h b/src/xmlpatterns/schema/qxsdelement_p.h index 3b9dd88..69fa769 100644 --- a/src/xmlpatterns/schema/qxsdelement_p.h +++ b/src/xmlpatterns/schema/qxsdelement_p.h @@ -382,7 +382,7 @@ namespace QPatternist XsdElement::WeakList substitutionGroups() const; private: - SchemaType::Ptr m_type; + SchemaType *m_type; Scope::Ptr m_scope; ValueConstraint::Ptr m_valueConstraint; TypeTable::Ptr m_typeTable; diff --git a/src/xmlpatterns/schema/qxsdschemaparser.cpp b/src/xmlpatterns/schema/qxsdschemaparser.cpp index 4281a41..0cb0153 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser.cpp +++ b/src/xmlpatterns/schema/qxsdschemaparser.cpp @@ -251,13 +251,13 @@ inline static bool isValidUri(const QString &string) XsdSchemaParser::XsdSchemaParser(const XsdSchemaContext::Ptr &context, const XsdSchemaParserContext::Ptr &parserContext, QIODevice *device) : MaintainingReader<XsdSchemaToken, XsdTagScope::Type>(parserContext->elementDescriptions(), QSet<XsdSchemaToken::NodeName>(), context, device) - , m_context(context) - , m_parserContext(parserContext) - , m_namePool(m_parserContext->namePool()) - , m_namespaceSupport(m_namePool) + , m_context(context.data()) + , m_parserContext(parserContext.data()) + , m_namePool(m_parserContext->namePool().data()) + , m_namespaceSupport(*m_namePool) { - m_schema = m_parserContext->schema(); - m_schemaResolver = m_parserContext->resolver(); + m_schema = m_parserContext->schema().data(); + m_schemaResolver = m_parserContext->resolver().data(); m_idCache = XsdIdCache::Ptr(new XsdIdCache()); setupStateMachines(); @@ -365,7 +365,7 @@ void XsdSchemaParser::attributeContentError(const char *attributeName, const cha .arg(formatAttribute(attributeName)) .arg(formatElement(elementName)) .arg(formatData(value)) - .arg(formatType(m_namePool, type))); + .arg(formatType(NamePool::Ptr(m_namePool), type))); } else { error(QtXmlPatterns::tr("%1 attribute of %2 element contains invalid content: {%3}.") .arg(formatAttribute(attributeName)) @@ -520,7 +520,7 @@ void XsdSchemaParser::parseSchema(ParserType parserType) validateIdAttribute("schema"); - TagValidationHandler tagValidator(XsdTagScope::Schema, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Schema, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -601,10 +601,10 @@ void XsdSchemaParser::parseInclude() m_includedSchemas.insert(url); const AutoPtr<QNetworkReply> reply(AccelTreeResourceLoader::load(url, m_context->networkAccessManager(), - m_context, AccelTreeResourceLoader::ContinueOnError)); + XsdSchemaContext::Ptr(m_context), AccelTreeResourceLoader::ContinueOnError)); if (reply) { // parse the included schema by a different parser but with the same context - XsdSchemaParser parser(m_context, m_parserContext, reply.data()); + XsdSchemaParser parser(XsdSchemaContext::Ptr(m_context), XsdSchemaParserContext::Ptr(m_parserContext), reply.data()); parser.setDocumentURI(url); parser.setTargetNamespaceExtended(m_targetNamespace); parser.setIncludedSchemas(m_includedSchemas); @@ -623,7 +623,7 @@ void XsdSchemaParser::parseInclude() validateIdAttribute("include"); - TagValidationHandler tagValidator(XsdTagScope::Include, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Include, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -697,10 +697,10 @@ void XsdSchemaParser::parseImport() m_importedSchemas.insert(importNamespace); AutoPtr<QNetworkReply> reply(AccelTreeResourceLoader::load(url, m_context->networkAccessManager(), - m_context, AccelTreeResourceLoader::ContinueOnError)); + XsdSchemaContext::Ptr(m_context), AccelTreeResourceLoader::ContinueOnError)); if (reply) { // parse the included schema by a different parser but with the same context - XsdSchemaParser parser(m_context, m_parserContext, reply.data()); + XsdSchemaParser parser(XsdSchemaContext::Ptr(m_context), XsdSchemaParserContext::Ptr(m_parserContext), reply.data()); parser.setDocumentURI(url); parser.setTargetNamespace(importNamespace); parser.setIncludedSchemas(m_includedSchemas); @@ -724,7 +724,7 @@ void XsdSchemaParser::parseImport() QFile file(QString::fromLatin1(":") + importNamespace); if (file.open(QIODevice::ReadOnly)) { - XsdSchemaParser parser(m_context, m_parserContext, &file); + XsdSchemaParser parser(XsdSchemaContext::Ptr(m_context), XsdSchemaParserContext::Ptr(m_parserContext), &file); parser.setDocumentURI(importNamespace); parser.setTargetNamespace(importNamespace); parser.setIncludedSchemas(m_includedSchemas); @@ -747,7 +747,7 @@ void XsdSchemaParser::parseImport() validateIdAttribute("import"); - TagValidationHandler tagValidator(XsdTagScope::Import, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Import, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -785,7 +785,7 @@ void XsdSchemaParser::parseRedefine() const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation")); - TagValidationHandler tagValidator(XsdTagScope::Redefine, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Redefine, this, NamePool::Ptr(m_namePool)); XsdSimpleType::List redefinedSimpleTypes; XsdComplexType::List redefinedComplexTypes; @@ -812,8 +812,8 @@ void XsdSchemaParser::parseRedefine() redefinedSimpleTypes.append(type); const QXmlName baseTypeName = m_parserContext->resolver()->baseTypeNameOfType(type); - if (baseTypeName != type->name(m_namePool)) { - error(QString::fromLatin1("redefined simple type %1 must have itself as base type").arg(formatType(m_namePool, type))); + if (baseTypeName != type->name(NamePool::Ptr(m_namePool))) { + error(QString::fromLatin1("redefined simple type %1 must have itself as base type").arg(formatType(NamePool::Ptr(m_namePool), type))); return; } } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) { @@ -824,8 +824,8 @@ void XsdSchemaParser::parseRedefine() // 5 const QXmlName baseTypeName = m_parserContext->resolver()->baseTypeNameOfType(type); - if (baseTypeName != type->name(m_namePool)) { - error(QString::fromLatin1("redefined complex type %1 must have itself as base type").arg(formatType(m_namePool, type))); + if (baseTypeName != type->name(NamePool::Ptr(m_namePool))) { + error(QString::fromLatin1("redefined complex type %1 must have itself as base type").arg(formatType(NamePool::Ptr(m_namePool), type))); return; } } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) { @@ -855,7 +855,7 @@ void XsdSchemaParser::parseRedefine() } // we parse the schema given in the redefine tag into its own context - const XsdSchemaParserContext::Ptr redefinedContext(new XsdSchemaParserContext(m_namePool, m_context)); + const XsdSchemaParserContext::Ptr redefinedContext(new XsdSchemaParserContext(NamePool::Ptr(m_namePool), XsdSchemaContext::Ptr(m_context))); if (m_redefinedSchemas.contains(url)) { // we have redefined that file already, according to the schema spec we are @@ -863,11 +863,11 @@ void XsdSchemaParser::parseRedefine() } else { m_redefinedSchemas.insert(url); QNetworkReply *reply = AccelTreeResourceLoader::load(url, m_context->networkAccessManager(), - m_context, + XsdSchemaContext::Ptr(m_context), (locationMustResolve ? AccelTreeResourceLoader::FailOnError : AccelTreeResourceLoader::ContinueOnError)); if (reply) { // parse the included schema by a different parser but with the same context - XsdSchemaParser parser(m_context, redefinedContext, reply); + XsdSchemaParser parser(XsdSchemaContext::Ptr(m_context), redefinedContext, reply); parser.setDocumentURI(url); parser.setTargetNamespaceExtended(m_targetNamespace); parser.setIncludedSchemas(m_includedSchemas); @@ -904,7 +904,7 @@ void XsdSchemaParser::parseRedefine() for (int j = 0; j < contextSimpleTypes.count(); ++j) { XsdSimpleType::Ptr contextType = contextSimpleTypes.at(j); - if (redefinedType->name(m_namePool) == contextType->name(m_namePool)) { // we found the right type + if (redefinedType->name(NamePool::Ptr(m_namePool)) == contextType->name(NamePool::Ptr(m_namePool))) { // we found the right type found = true; // 1) set name of context type to empty name @@ -932,7 +932,7 @@ void XsdSchemaParser::parseRedefine() } if (!found) { - error(QString::fromLatin1("no matching type found to redefine simple type %1").arg(formatType(m_namePool, redefinedType))); + error(QString::fromLatin1("no matching type found to redefine simple type %1").arg(formatType(NamePool::Ptr(m_namePool), redefinedType))); return; } } @@ -953,7 +953,7 @@ void XsdSchemaParser::parseRedefine() for (int j = 0; j < contextComplexTypes.count(); ++j) { XsdComplexType::Ptr contextType = contextComplexTypes.at(j); - if (redefinedType->name(m_namePool) == contextType->name(m_namePool)) { // we found the right type + if (redefinedType->name(NamePool::Ptr(m_namePool)) == contextType->name(NamePool::Ptr(m_namePool))) { // we found the right type found = true; // 1) set name of context type to empty name @@ -981,7 +981,7 @@ void XsdSchemaParser::parseRedefine() } if (!found) { - error(QString::fromLatin1("no matching type found to redefine complex type %1").arg(formatType(m_namePool, redefinedType))); + error(QString::fromLatin1("no matching type found to redefine complex type %1").arg(formatType(NamePool::Ptr(m_namePool), redefinedType))); return; } } @@ -998,11 +998,11 @@ void XsdSchemaParser::parseRedefine() int sameNameCounter = 0; for (int i = 0; i < particles.count(); ++i) { const XsdReference::Ptr ref(particles.at(i)->term()); - if (ref->referenceName() == group->name(m_namePool)) { + if (ref->referenceName() == group->name(NamePool::Ptr(m_namePool))) { referencedParticle = particles.at(i); if (referencedParticle->minimumOccurs() != 1 || referencedParticle->maximumOccurs() != 1 || referencedParticle->maximumOccursUnbounded()) { // 6.1.2 - error(QString::fromLatin1("redefined group %1 can not contain reference to itself with minOccurs or maxOccurs != 1").arg(formatKeyword(group->displayName(m_namePool)))); + error(QString::fromLatin1("redefined group %1 can not contain reference to itself with minOccurs or maxOccurs != 1").arg(formatKeyword(group->displayName(NamePool::Ptr(m_namePool))))); return; } sameNameCounter++; @@ -1011,21 +1011,21 @@ void XsdSchemaParser::parseRedefine() // 6.1.1 if (sameNameCounter > 1) { - error(QString::fromLatin1("redefined group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(m_namePool)))); + error(QString::fromLatin1("redefined group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(NamePool::Ptr(m_namePool))))); return; } // search the group definition in the included schema (S2) XsdModelGroup::Ptr contextGroup; for (int j = 0; j < contextGroups.count(); ++j) { - if (group->name(m_namePool) == contextGroups.at(j)->name(m_namePool)) { + if (group->name(NamePool::Ptr(m_namePool)) == contextGroups.at(j)->name(NamePool::Ptr(m_namePool))) { contextGroup = contextGroups.at(j); break; } } if (!contextGroup) { // 6.2.1 - error(QString::fromLatin1("redefined group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(m_namePool)))); + error(QString::fromLatin1("redefined group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(NamePool::Ptr(m_namePool))))); return; } @@ -1034,7 +1034,7 @@ void XsdSchemaParser::parseRedefine() // group from the included schema // set a anonymous name to the group of the included schema - contextGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(contextGroup->name(m_namePool).namespaceURI()))); + contextGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(contextGroup->name(NamePool::Ptr(m_namePool)).namespaceURI()))); // replace the self-reference with the group from the included schema referencedParticle->setTerm(contextGroup); @@ -1050,7 +1050,7 @@ void XsdSchemaParser::parseRedefine() addElementGroup(group); // we have to add them, otherwise it is not resolved and we can't validate it later - contextGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(contextGroup->name(m_namePool).namespaceURI()))); + contextGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(contextGroup->name(NamePool::Ptr(m_namePool)).namespaceURI()))); addElementGroup(contextGroup); m_schemaResolver->addRedefinedGroups(group, contextGroup); @@ -1075,13 +1075,13 @@ void XsdSchemaParser::parseRedefine() if (attributeUse->isReference()) { const XsdAttributeReference::Ptr reference(attributeUse); if (reference->type() == XsdAttributeReference::AttributeGroup) { - if (group->name(m_namePool) == reference->referenceName()) + if (group->name(NamePool::Ptr(m_namePool)) == reference->referenceName()) sameNameCounter++; } } } if (sameNameCounter > 1) { - error(QString::fromLatin1("redefined attribute group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(m_namePool)))); + error(QString::fromLatin1("redefined attribute group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(NamePool::Ptr(m_namePool))))); return; } @@ -1089,14 +1089,14 @@ void XsdSchemaParser::parseRedefine() XsdAttributeGroup::Ptr baseGroup; for (int j = 0; j < contextAttributeGroups.count(); ++j) { const XsdAttributeGroup::Ptr contextGroup(contextAttributeGroups.at(j)); - if (group->name(m_namePool) == contextGroup->name(m_namePool)) { + if (group->name(NamePool::Ptr(m_namePool)) == contextGroup->name(NamePool::Ptr(m_namePool))) { baseGroup = contextGroup; break; } } if (!baseGroup) { // 7.2.1 - error(QString::fromLatin1("redefined attribute group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(m_namePool)))); + error(QString::fromLatin1("redefined attribute group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(NamePool::Ptr(m_namePool))))); return; } @@ -1104,7 +1104,7 @@ void XsdSchemaParser::parseRedefine() // first set an anonymous name to the attribute group from the included // schema - baseGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(baseGroup->name(m_namePool).namespaceURI()))); + baseGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(baseGroup->name(NamePool::Ptr(m_namePool)).namespaceURI()))); // iterate over the attribute uses of the redefined attribute group // and replace the self-reference with the attribute group from the @@ -1114,8 +1114,8 @@ void XsdSchemaParser::parseRedefine() if (attributeUse->isReference()) { const XsdAttributeReference::Ptr reference(attributeUse); if (reference->type() == XsdAttributeReference::AttributeGroup) { - if (group->name(m_namePool) == reference->referenceName()) { - reference->setReferenceName(baseGroup->name(m_namePool)); + if (group->name(NamePool::Ptr(m_namePool)) == reference->referenceName()) { + reference->setReferenceName(baseGroup->name(NamePool::Ptr(m_namePool))); break; } } @@ -1132,7 +1132,7 @@ void XsdSchemaParser::parseRedefine() if (sameNameCounter == 0) { // 7.2 // we have to add them, otherwise it is not resolved and we can't validate it later - baseGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(baseGroup->name(m_namePool).namespaceURI()))); + baseGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(baseGroup->name(NamePool::Ptr(m_namePool)).namespaceURI()))); addAttributeGroup(baseGroup); m_schemaResolver->addRedefinedAttributeGroups(group, baseGroup); @@ -1191,7 +1191,7 @@ XsdAnnotation::Ptr XsdSchemaParser::parseAnnotation() // parse attributes validateIdAttribute("annotation"); - TagValidationHandler tagValidator(XsdTagScope::Annotation, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Annotation, this, NamePool::Ptr(m_namePool)); const XsdAnnotation::Ptr annotation(new XsdAnnotation()); @@ -1344,7 +1344,7 @@ void XsdSchemaParser::parseDefaultOpenContent() validateIdAttribute("defaultOpenContent"); - TagValidationHandler tagValidator(XsdTagScope::DefaultOpenContent, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::DefaultOpenContent, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -1392,7 +1392,7 @@ XsdSimpleType::Ptr XsdSchemaParser::parseGlobalSimpleType() validateIdAttribute("simpleType"); - TagValidationHandler tagValidator(XsdTagScope::GlobalSimpleType, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::GlobalSimpleType, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -1438,7 +1438,7 @@ XsdSimpleType::Ptr XsdSchemaParser::parseLocalSimpleType() validateIdAttribute("simpleType"); - TagValidationHandler tagValidator(XsdTagScope::LocalSimpleType, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::LocalSimpleType, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -1501,7 +1501,7 @@ void XsdSchemaParser::parseSimpleRestriction(const XsdSimpleType::Ptr &ptr) QList<XsdFacet::Ptr> enumerationFacets; QList<XsdFacet::Ptr> assertionFacets; - TagValidationHandler tagValidator(XsdTagScope::SimpleRestriction, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::SimpleRestriction, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -1659,7 +1659,7 @@ void XsdSchemaParser::parseList(const XsdSimpleType::Ptr &ptr) validateIdAttribute("list"); - TagValidationHandler tagValidator(XsdTagScope::List, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::List, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -1713,7 +1713,7 @@ void XsdSchemaParser::parseList(const XsdSimpleType::Ptr &ptr) const XsdFacet::Ptr defaultFacet(new XsdFacet()); defaultFacet->setType(XsdFacet::WhiteSpace); defaultFacet->setFixed(true); - defaultFacet->setValue(DerivedString<TypeString>::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse))); + defaultFacet->setValue(DerivedString<TypeString>::fromLexical(NamePool::Ptr(m_namePool), XsdSchemaToken::toString(XsdSchemaToken::Collapse))); XsdFacet::Hash facets; facets.insert(defaultFacet->type(), defaultFacet); ptr->setFacets(facets); @@ -1756,7 +1756,7 @@ void XsdSchemaParser::parseUnion(const XsdSimpleType::Ptr &ptr) AnySimpleType::List memberTypes; - TagValidationHandler tagValidator(XsdTagScope::Union, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Union, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -1828,7 +1828,7 @@ XsdFacet::Ptr XsdSchemaParser::parseMinExclusiveFacet() // as minExclusive can have a value of type anySimpleType, we just read // the string here and store it for later intepretation const QString value = readAttribute(QString::fromLatin1("value")); - DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value); + DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(NamePool::Ptr(m_namePool), value); if (string->hasError()) { attributeContentError("value", "minExclusive", value, BuiltinTypes::xsAnySimpleType); return facet; @@ -1838,7 +1838,7 @@ XsdFacet::Ptr XsdSchemaParser::parseMinExclusiveFacet() validateIdAttribute("minExclusive"); - TagValidationHandler tagValidator(XsdTagScope::MinExclusiveFacet, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::MinExclusiveFacet, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -1892,7 +1892,7 @@ XsdFacet::Ptr XsdSchemaParser::parseMinInclusiveFacet() // as minInclusive can have a value of type anySimpleType, we just read // the string here and store it for later intepretation const QString value = readAttribute(QString::fromLatin1("value")); - DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value); + DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(NamePool::Ptr(m_namePool), value); if (string->hasError()) { attributeContentError("value", "minInclusive", value, BuiltinTypes::xsAnySimpleType); return facet; @@ -1902,7 +1902,7 @@ XsdFacet::Ptr XsdSchemaParser::parseMinInclusiveFacet() validateIdAttribute("minInclusive"); - TagValidationHandler tagValidator(XsdTagScope::MinInclusiveFacet, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::MinInclusiveFacet, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -1956,7 +1956,7 @@ XsdFacet::Ptr XsdSchemaParser::parseMaxExclusiveFacet() // as maxExclusive can have a value of type anySimpleType, we just read // the string here and store it for later intepretation const QString value = readAttribute(QString::fromLatin1("value")); - DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value); + DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(NamePool::Ptr(m_namePool), value); if (string->hasError()) { attributeContentError("value", "maxExclusive", value, BuiltinTypes::xsAnySimpleType); return facet; @@ -1966,7 +1966,7 @@ XsdFacet::Ptr XsdSchemaParser::parseMaxExclusiveFacet() validateIdAttribute("maxExclusive"); - TagValidationHandler tagValidator(XsdTagScope::MaxExclusiveFacet, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::MaxExclusiveFacet, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -2020,7 +2020,7 @@ XsdFacet::Ptr XsdSchemaParser::parseMaxInclusiveFacet() // as maxInclusive can have a value of type anySimpleType, we just read // the string here and store it for later intepretation const QString value = readAttribute(QString::fromLatin1("value")); - DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value); + DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(NamePool::Ptr(m_namePool), value); if (string->hasError()) { attributeContentError("value", "maxInclusive", value, BuiltinTypes::xsAnySimpleType); return facet; @@ -2030,7 +2030,7 @@ XsdFacet::Ptr XsdSchemaParser::parseMaxInclusiveFacet() validateIdAttribute("maxInclusive"); - TagValidationHandler tagValidator(XsdTagScope::MaxInclusiveFacet, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::MaxInclusiveFacet, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -2082,7 +2082,7 @@ XsdFacet::Ptr XsdSchemaParser::parseTotalDigitsFacet() } const QString value = readAttribute(QString::fromLatin1("value")); - DerivedInteger<TypePositiveInteger>::Ptr integer = DerivedInteger<TypePositiveInteger>::fromLexical(m_namePool, value); + DerivedInteger<TypePositiveInteger>::Ptr integer = DerivedInteger<TypePositiveInteger>::fromLexical(NamePool::Ptr(m_namePool), value); if (integer->hasError()) { attributeContentError("value", "totalDigits", value, BuiltinTypes::xsPositiveInteger); return facet; @@ -2092,7 +2092,7 @@ XsdFacet::Ptr XsdSchemaParser::parseTotalDigitsFacet() validateIdAttribute("totalDigits"); - TagValidationHandler tagValidator(XsdTagScope::TotalDigitsFacet, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::TotalDigitsFacet, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -2144,7 +2144,7 @@ XsdFacet::Ptr XsdSchemaParser::parseFractionDigitsFacet() } const QString value = readAttribute(QString::fromLatin1("value")); - DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value); + DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(NamePool::Ptr(m_namePool), value); if (integer->hasError()) { attributeContentError("value", "fractionDigits", value, BuiltinTypes::xsNonNegativeInteger); return facet; @@ -2154,7 +2154,7 @@ XsdFacet::Ptr XsdSchemaParser::parseFractionDigitsFacet() validateIdAttribute("fractionDigits"); - TagValidationHandler tagValidator(XsdTagScope::FractionDigitsFacet, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::FractionDigitsFacet, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -2206,7 +2206,7 @@ XsdFacet::Ptr XsdSchemaParser::parseLengthFacet() } const QString value = readAttribute(QString::fromLatin1("value")); - DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value); + DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(NamePool::Ptr(m_namePool), value); if (integer->hasError()) { attributeContentError("value", "length", value, BuiltinTypes::xsNonNegativeInteger); return facet; @@ -2216,7 +2216,7 @@ XsdFacet::Ptr XsdSchemaParser::parseLengthFacet() validateIdAttribute("length"); - TagValidationHandler tagValidator(XsdTagScope::LengthFacet, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::LengthFacet, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -2268,7 +2268,7 @@ XsdFacet::Ptr XsdSchemaParser::parseMinLengthFacet() } const QString value = readAttribute(QString::fromLatin1("value")); - DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value); + DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(NamePool::Ptr(m_namePool), value); if (integer->hasError()) { attributeContentError("value", "minLength", value, BuiltinTypes::xsNonNegativeInteger); return facet; @@ -2278,7 +2278,7 @@ XsdFacet::Ptr XsdSchemaParser::parseMinLengthFacet() validateIdAttribute("minLength"); - TagValidationHandler tagValidator(XsdTagScope::MinLengthFacet, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::MinLengthFacet, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -2330,7 +2330,7 @@ XsdFacet::Ptr XsdSchemaParser::parseMaxLengthFacet() } const QString value = readAttribute(QString::fromLatin1("value")); - DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value); + DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(NamePool::Ptr(m_namePool), value); if (integer->hasError()) { attributeContentError("value", "maxLength", value, BuiltinTypes::xsNonNegativeInteger); return facet; @@ -2340,7 +2340,7 @@ XsdFacet::Ptr XsdSchemaParser::parseMaxLengthFacet() validateIdAttribute("maxLength"); - TagValidationHandler tagValidator(XsdTagScope::MaxLengthFacet, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::MaxLengthFacet, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -2384,7 +2384,7 @@ XsdFacet::Ptr XsdSchemaParser::parseEnumerationFacet() // as enumeration can have a value of type anySimpleType, we just read // the string here and store it for later intepretation - DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value); + DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(NamePool::Ptr(m_namePool), value); if (string->hasError()) { attributeContentError("value", "enumeration", value); return facet; @@ -2397,7 +2397,7 @@ XsdFacet::Ptr XsdSchemaParser::parseEnumerationFacet() validateIdAttribute("enumeration"); - TagValidationHandler tagValidator(XsdTagScope::EnumerationFacet, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::EnumerationFacet, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -2455,7 +2455,7 @@ XsdFacet::Ptr XsdSchemaParser::parseWhiteSpaceFacet() attributeContentError("value", "whiteSpace", value); return facet; } else { - DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value); + DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(NamePool::Ptr(m_namePool), value); if (string->hasError()) { attributeContentError("value", "whiteSpace", value); return facet; @@ -2466,7 +2466,7 @@ XsdFacet::Ptr XsdSchemaParser::parseWhiteSpaceFacet() validateIdAttribute("whiteSpace"); - TagValidationHandler tagValidator(XsdTagScope::WhiteSpaceFacet, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::WhiteSpaceFacet, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -2508,7 +2508,7 @@ XsdFacet::Ptr XsdSchemaParser::parsePatternFacet() // as pattern can have a value of type anySimpleType, we just read // the string here and store it for later intepretation const QString value = readAttribute(QString::fromLatin1("value")); - DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(m_namePool, value); + DerivedString<TypeString>::Ptr string = DerivedString<TypeString>::fromLexical(NamePool::Ptr(m_namePool), value); if (string->hasError()) { attributeContentError("value", "pattern", value); return facet; @@ -2520,7 +2520,7 @@ XsdFacet::Ptr XsdSchemaParser::parsePatternFacet() validateIdAttribute("pattern"); - TagValidationHandler tagValidator(XsdTagScope::PatternFacet, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::PatternFacet, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -2608,7 +2608,7 @@ XsdComplexType::Ptr XsdSchemaParser::parseGlobalComplexType() validateIdAttribute("complexType"); - TagValidationHandler tagValidator(XsdTagScope::GlobalComplexType, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::GlobalComplexType, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -2763,7 +2763,7 @@ XsdComplexType::Ptr XsdSchemaParser::parseLocalComplexType() validateIdAttribute("complexType"); - TagValidationHandler tagValidator(XsdTagScope::LocalComplexType, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::LocalComplexType, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -2926,7 +2926,7 @@ void XsdSchemaParser::parseSimpleContent(const XsdComplexType::Ptr &complexType) // parse attributes validateIdAttribute("simpleContent"); - TagValidationHandler tagValidator(XsdTagScope::SimpleContent, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::SimpleContent, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -2976,7 +2976,7 @@ void XsdSchemaParser::parseSimpleContentRestriction(const XsdComplexType::Ptr &c QList<XsdFacet::Ptr> enumerationFacets; QList<XsdFacet::Ptr> assertionFacets; - TagValidationHandler tagValidator(XsdTagScope::SimpleContentRestriction, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::SimpleContentRestriction, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -3117,7 +3117,7 @@ void XsdSchemaParser::parseSimpleContentExtension(const XsdComplexType::Ptr &com validateIdAttribute("extension"); - TagValidationHandler tagValidator(XsdTagScope::SimpleContentExtension, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::SimpleContentExtension, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -3180,7 +3180,7 @@ void XsdSchemaParser::parseComplexContent(const XsdComplexType::Ptr &complexType validateIdAttribute("complexContent"); - TagValidationHandler tagValidator(XsdTagScope::ComplexContent, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::ComplexContent, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -3226,7 +3226,7 @@ void XsdSchemaParser::parseComplexContentRestriction(const XsdComplexType::Ptr & validateIdAttribute("restriction"); - TagValidationHandler tagValidator(XsdTagScope::ComplexContentRestriction, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::ComplexContentRestriction, this, NamePool::Ptr(m_namePool)); bool hasContent = false; while (!atEnd()) { @@ -3312,7 +3312,7 @@ void XsdSchemaParser::parseComplexContentExtension(const XsdComplexType::Ptr &co validateIdAttribute("extension"); - TagValidationHandler tagValidator(XsdTagScope::ComplexContentExtension, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::ComplexContentExtension, this, NamePool::Ptr(m_namePool)); bool hasContent = false; while (!atEnd()) { @@ -3401,7 +3401,7 @@ XsdAssertion::Ptr XsdSchemaParser::parseAssertion(const XsdSchemaToken::NodeName validateIdAttribute("assertion"); - TagValidationHandler tagValidator(tag, this, m_namePool); + TagValidationHandler tagValidator(tag, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -3456,7 +3456,7 @@ XsdComplexType::OpenContent::Ptr XsdSchemaParser::parseOpenContent() validateIdAttribute("openContent"); - TagValidationHandler tagValidator(XsdTagScope::OpenContent, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::OpenContent, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -3504,7 +3504,7 @@ XsdModelGroup::Ptr XsdSchemaParser::parseNamedGroup() validateIdAttribute("group"); - TagValidationHandler tagValidator(XsdTagScope::NamedGroup, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::NamedGroup, this, NamePool::Ptr(m_namePool)); XsdAnnotation::Ptr annotation; @@ -3566,7 +3566,7 @@ XsdTerm::Ptr XsdSchemaParser::parseReferredGroup(const XsdParticle::Ptr &particl validateIdAttribute("group"); - TagValidationHandler tagValidator(XsdTagScope::ReferredGroup, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::ReferredGroup, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -3605,7 +3605,7 @@ XsdModelGroup::Ptr XsdSchemaParser::parseAll(const NamedSchemaComponent::Ptr &pa validateIdAttribute("all"); - TagValidationHandler tagValidator(XsdTagScope::All, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::All, this, NamePool::Ptr(m_namePool)); XsdParticle::List particles; while (!atEnd()) { @@ -3682,7 +3682,7 @@ XsdModelGroup::Ptr XsdSchemaParser::parseLocalAll(const XsdParticle::Ptr &partic validateIdAttribute("all"); - TagValidationHandler tagValidator(XsdTagScope::LocalAll, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::LocalAll, this, NamePool::Ptr(m_namePool)); XsdParticle::List particles; while (!atEnd()) { @@ -3741,7 +3741,7 @@ XsdModelGroup::Ptr XsdSchemaParser::parseChoice(const NamedSchemaComponent::Ptr XsdParticle::List particles; - TagValidationHandler tagValidator(XsdTagScope::Choice, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Choice, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -3815,7 +3815,7 @@ XsdModelGroup::Ptr XsdSchemaParser::parseLocalChoice(const XsdParticle::Ptr &par XsdParticle::List particles; - TagValidationHandler tagValidator(XsdTagScope::LocalChoice, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::LocalChoice, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -3884,7 +3884,7 @@ XsdModelGroup::Ptr XsdSchemaParser::parseSequence(const NamedSchemaComponent::Pt XsdParticle::List particles; - TagValidationHandler tagValidator(XsdTagScope::Sequence, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Sequence, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -3958,7 +3958,7 @@ XsdModelGroup::Ptr XsdSchemaParser::parseLocalSequence(const XsdParticle::Ptr &p XsdParticle::List particles; - TagValidationHandler tagValidator(XsdTagScope::LocalSequence, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::LocalSequence, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -4082,7 +4082,7 @@ XsdAttribute::Ptr XsdSchemaParser::parseGlobalAttribute() validateIdAttribute("attribute"); - TagValidationHandler tagValidator(XsdTagScope::GlobalAttribute, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::GlobalAttribute, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -4314,7 +4314,7 @@ XsdAttributeUse::Ptr XsdSchemaParser::parseLocalAttribute(const NamedSchemaCompo validateIdAttribute("attribute"); - TagValidationHandler tagValidator(XsdTagScope::LocalAttribute, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::LocalAttribute, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -4383,7 +4383,7 @@ XsdAttributeGroup::Ptr XsdSchemaParser::parseNamedAttributeGroup() validateIdAttribute("attributeGroup"); - TagValidationHandler tagValidator(XsdTagScope::NamedAttributeGroup, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::NamedAttributeGroup, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -4443,7 +4443,7 @@ XsdAttributeUse::Ptr XsdSchemaParser::parseReferredAttributeGroup() validateIdAttribute("attributeGroup"); - TagValidationHandler tagValidator(XsdTagScope::ReferredAttributeGroup, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::ReferredAttributeGroup, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -4581,7 +4581,7 @@ XsdElement::Ptr XsdSchemaParser::parseGlobalElement() XsdAlternative::List alternatives; - TagValidationHandler tagValidator(XsdTagScope::GlobalElement, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::GlobalElement, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -4856,7 +4856,7 @@ XsdTerm::Ptr XsdSchemaParser::parseLocalElement(const XsdParticle::Ptr &particle XsdAlternative::List alternatives; - TagValidationHandler tagValidator(XsdTagScope::LocalElement, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::LocalElement, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -5015,7 +5015,7 @@ XsdIdentityConstraint::Ptr XsdSchemaParser::parseUnique() validateIdAttribute("unique"); - TagValidationHandler tagValidator(XsdTagScope::Unique, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Unique, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -5065,7 +5065,7 @@ XsdIdentityConstraint::Ptr XsdSchemaParser::parseKey() validateIdAttribute("key"); - TagValidationHandler tagValidator(XsdTagScope::Key, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Key, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -5120,7 +5120,7 @@ XsdIdentityConstraint::Ptr XsdSchemaParser::parseKeyRef(const XsdElement::Ptr &e validateIdAttribute("keyref"); - TagValidationHandler tagValidator(XsdTagScope::KeyRef, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::KeyRef, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -5171,7 +5171,7 @@ void XsdSchemaParser::parseSelector(const XsdIdentityConstraint::Ptr &ptr) validateIdAttribute("selector"); - TagValidationHandler tagValidator(XsdTagScope::Selector, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Selector, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -5213,7 +5213,7 @@ void XsdSchemaParser::parseField(const XsdIdentityConstraint::Ptr &ptr) validateIdAttribute("field"); - TagValidationHandler tagValidator(XsdTagScope::Field, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Field, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -5269,7 +5269,7 @@ XsdAlternative::Ptr XsdSchemaParser::parseAlternative() validateIdAttribute("alternative"); - TagValidationHandler tagValidator(XsdTagScope::Alternative, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Alternative, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -5339,7 +5339,7 @@ XsdNotation::Ptr XsdSchemaParser::parseNotation() if (hasAttribute(QString::fromLatin1("public"))) { const QString value = readAttribute(QString::fromLatin1("public")); if (!value.isEmpty()) { - const DerivedString<TypeToken>::Ptr publicId = DerivedString<TypeToken>::fromLexical(m_namePool, value); + const DerivedString<TypeToken>::Ptr publicId = DerivedString<TypeToken>::fromLexical(NamePool::Ptr(m_namePool), value); if (publicId->hasError()) { attributeContentError("public", "notation", value, BuiltinTypes::xsToken); return notation; @@ -5375,7 +5375,7 @@ XsdNotation::Ptr XsdSchemaParser::parseNotation() validateIdAttribute("notation"); - TagValidationHandler tagValidator(XsdTagScope::Notation, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Notation, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -5498,7 +5498,7 @@ XsdWildcard::Ptr XsdSchemaParser::parseAny(const XsdParticle::Ptr &particle) validateIdAttribute("any"); - TagValidationHandler tagValidator(XsdTagScope::Any, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::Any, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -5610,7 +5610,7 @@ XsdWildcard::Ptr XsdSchemaParser::parseAnyAttribute() validateIdAttribute("anyAttribute"); - TagValidationHandler tagValidator(XsdTagScope::AnyAttribute, this, m_namePool); + TagValidationHandler tagValidator(XsdTagScope::AnyAttribute, this, NamePool::Ptr(m_namePool)); while (!atEnd()) { readNext(); @@ -5684,7 +5684,7 @@ bool XsdSchemaParser::parseMinMaxConstraint(const XsdParticle::Ptr &particle, co if (hasAttribute(QString::fromLatin1("minOccurs"))) { const QString value = readAttribute(QString::fromLatin1("minOccurs")); - DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value); + DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(NamePool::Ptr(m_namePool), value); if (integer->hasError()) { attributeContentError("minOccurs", elementName, value, BuiltinTypes::xsNonNegativeInteger); return false; @@ -5702,7 +5702,7 @@ bool XsdSchemaParser::parseMinMaxConstraint(const XsdParticle::Ptr &particle, co particle->setMaximumOccursUnbounded(true); } else { particle->setMaximumOccursUnbounded(false); - DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(m_namePool, value); + DerivedInteger<TypeNonNegativeInteger>::Ptr integer = DerivedInteger<TypeNonNegativeInteger>::fromLexical(NamePool::Ptr(m_namePool), value); if (integer->hasError()) { attributeContentError("maxOccurs", elementName, value, BuiltinTypes::xsNonNegativeInteger); return false; @@ -5963,7 +5963,7 @@ QString XsdSchemaParser::readXPathAttribute(const QString &attributeName, XPathT return QString(); } - QXmlNamePool namePool(m_namePool.data()); + QXmlNamePool namePool(NamePool::Ptr(m_namePool).data()); QXmlQuery::QueryLanguage language = QXmlQuery::XPath20; switch (type) { @@ -5994,7 +5994,7 @@ void XsdSchemaParser::validateIdAttribute(const char *elementName) { if (hasAttribute(QString::fromLatin1("id"))) { const QString value = readAttribute(QString::fromLatin1("id")); - DerivedString<TypeID>::Ptr id = DerivedString<TypeID>::fromLexical(m_namePool, value); + DerivedString<TypeID>::Ptr id = DerivedString<TypeID>::fromLexical(NamePool::Ptr(m_namePool), value); if (id->hasError()) { attributeContentError("id", elementName, value, BuiltinTypes::xsID); } else { @@ -6014,7 +6014,7 @@ bool XsdSchemaParser::isSchemaTag(XsdSchemaToken::NodeName tag, XsdSchemaToken:: void XsdSchemaParser::addElement(const XsdElement::Ptr &element) { - const QXmlName objectName = element->name(m_namePool); + const QXmlName objectName = element->name(NamePool::Ptr(m_namePool)); if (m_schema->element(objectName)) { error(QtXmlPatterns::tr("Element %1 already defined.").arg(formatElement(m_namePool->displayName(objectName)))); } else { @@ -6025,7 +6025,7 @@ void XsdSchemaParser::addElement(const XsdElement::Ptr &element) void XsdSchemaParser::addAttribute(const XsdAttribute::Ptr &attribute) { - const QXmlName objectName = attribute->name(m_namePool); + const QXmlName objectName = attribute->name(NamePool::Ptr(m_namePool)); if (m_schema->attribute(objectName)) { error(QtXmlPatterns::tr("Attribute %1 already defined.").arg(formatAttribute(m_namePool->displayName(objectName)))); } else { @@ -6037,12 +6037,12 @@ void XsdSchemaParser::addAttribute(const XsdAttribute::Ptr &attribute) void XsdSchemaParser::addType(const SchemaType::Ptr &type) { // we don't import redefinitions of builtin types, that just causes problems - if (m_builtinTypeNames.contains(type->name(m_namePool))) + if (m_builtinTypeNames.contains(type->name(NamePool::Ptr(m_namePool)))) return; - const QXmlName objectName = type->name(m_namePool); + const QXmlName objectName = type->name(NamePool::Ptr(m_namePool)); if (m_schema->type(objectName)) { - error(QtXmlPatterns::tr("Type %1 already defined.").arg(formatType(m_namePool, objectName))); + error(QtXmlPatterns::tr("Type %1 already defined.").arg(formatType(NamePool::Ptr(m_namePool), objectName))); } else { m_schema->addType(type); if (type->isSimpleType()) @@ -6063,9 +6063,9 @@ void XsdSchemaParser::addAnonymousType(const SchemaType::Ptr &type) void XsdSchemaParser::addAttributeGroup(const XsdAttributeGroup::Ptr &group) { - const QXmlName objectName = group->name(m_namePool); + const QXmlName objectName = group->name(NamePool::Ptr(m_namePool)); if (m_schema->attributeGroup(objectName)) { - error(QtXmlPatterns::tr("Attribute group %1 already defined.").arg(formatKeyword(m_namePool, objectName))); + error(QtXmlPatterns::tr("Attribute group %1 already defined.").arg(formatKeyword(NamePool::Ptr(m_namePool), objectName))); } else { m_schema->addAttributeGroup(group); m_componentLocationHash.insert(group, currentSourceLocation()); @@ -6074,9 +6074,9 @@ void XsdSchemaParser::addAttributeGroup(const XsdAttributeGroup::Ptr &group) void XsdSchemaParser::addElementGroup(const XsdModelGroup::Ptr &group) { - const QXmlName objectName = group->name(m_namePool); + const QXmlName objectName = group->name(NamePool::Ptr(m_namePool)); if (m_schema->elementGroup(objectName)) { - error(QtXmlPatterns::tr("Element group %1 already defined.").arg(formatKeyword(m_namePool, objectName))); + error(QtXmlPatterns::tr("Element group %1 already defined.").arg(formatKeyword(NamePool::Ptr(m_namePool), objectName))); } else { m_schema->addElementGroup(group); m_componentLocationHash.insert(group, currentSourceLocation()); @@ -6085,9 +6085,9 @@ void XsdSchemaParser::addElementGroup(const XsdModelGroup::Ptr &group) void XsdSchemaParser::addNotation(const XsdNotation::Ptr ¬ation) { - const QXmlName objectName = notation->name(m_namePool); + const QXmlName objectName = notation->name(NamePool::Ptr(m_namePool)); if (m_schema->notation(objectName)) { - error(QtXmlPatterns::tr("Notation %1 already defined.").arg(formatKeyword(m_namePool, objectName))); + error(QtXmlPatterns::tr("Notation %1 already defined.").arg(formatKeyword(NamePool::Ptr(m_namePool), objectName))); } else { m_schema->addNotation(notation); m_componentLocationHash.insert(notation, currentSourceLocation()); @@ -6096,9 +6096,9 @@ void XsdSchemaParser::addNotation(const XsdNotation::Ptr ¬ation) void XsdSchemaParser::addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint) { - const QXmlName objectName = constraint->name(m_namePool); + const QXmlName objectName = constraint->name(NamePool::Ptr(m_namePool)); if (m_schema->identityConstraint(objectName)) { - error(QtXmlPatterns::tr("Identity constraint %1 already defined.").arg(formatKeyword(m_namePool, objectName))); + error(QtXmlPatterns::tr("Identity constraint %1 already defined.").arg(formatKeyword(NamePool::Ptr(m_namePool), objectName))); } else { m_schema->addIdentityConstraint(constraint); m_componentLocationHash.insert(constraint, currentSourceLocation()); @@ -6109,7 +6109,7 @@ void XsdSchemaParser::addFacet(const XsdFacet::Ptr &facet, XsdFacet::Hash &facet { // @see http://www.w3.org/TR/xmlschema-2/#src-single-facet-value if (facets.contains(facet->type())) { - error(QtXmlPatterns::tr("Duplicated facets in simple type %1.").arg(formatType(m_namePool, type))); + error(QtXmlPatterns::tr("Duplicated facets in simple type %1.").arg(formatType(NamePool::Ptr(m_namePool), type))); return; } diff --git a/src/xmlpatterns/schema/qxsdschemaparser_p.h b/src/xmlpatterns/schema/qxsdschemaparser_p.h index 7054b87..93163de 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser_p.h +++ b/src/xmlpatterns/schema/qxsdschemaparser_p.h @@ -704,12 +704,12 @@ namespace QPatternist */ inline bool isSchemaTag(XsdSchemaToken::NodeName tag, XsdSchemaToken::NodeName token, XsdSchemaToken::NodeName namespaceToken) const; - XsdSchemaContext::Ptr m_context; - XsdSchemaParserContext::Ptr m_parserContext; - NamePool::Ptr m_namePool; + XsdSchemaContext *m_context; + XsdSchemaParserContext *m_parserContext; + NamePool *m_namePool; NamespaceSupport m_namespaceSupport; - XsdSchemaResolver::Ptr m_schemaResolver; - XsdSchema::Ptr m_schema; + XsdSchemaResolver *m_schemaResolver; + XsdSchema *m_schema; QString m_targetNamespace; QString m_attributeFormDefault; diff --git a/src/xmlpatterns/schema/qxsdschemaparser_setup.cpp b/src/xmlpatterns/schema/qxsdschemaparser_setup.cpp index 35ededd..1757d25 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser_setup.cpp +++ b/src/xmlpatterns/schema/qxsdschemaparser_setup.cpp @@ -260,8 +260,9 @@ using namespace QPatternist; void XsdSchemaParser::setupStateMachines() { + NamePool::Ptr namePool(m_namePool); { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, simpleType?) : attribute const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -277,7 +278,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, ((simpleType | complexType)?, alternative*, (unique | key | keyref)*)) : element const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -320,7 +321,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, (simpleContent | complexContent | (openContent?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?), assert*))) : complexType const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -385,7 +386,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, (restriction | extension)) : simpleContent/complexContent const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartState); @@ -404,7 +405,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern | assertion)*)?, ((attribute | attributeGroup)*, anyAttribute?), assert*) : simpleContent restriction const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -503,7 +504,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, ((attribute | attributeGroup)*, anyAttribute?), assert*) : simple content extension const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -536,7 +537,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, openContent?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?), assert*)) : complex content restriction/complex content extension const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -596,7 +597,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, ((attribute | attributeGroup)*, anyAttribute?)) : named attribute group const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -621,7 +622,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, (all | choice | sequence)?) : group const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -642,7 +643,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, (element | any)*) : all const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -664,7 +665,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, (element | group | choice | sequence | any)*) : choice sequence const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -697,7 +698,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?) : any/selector/field/notation/include/import/referred attribute group/anyAttribute/all facets/assert const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -730,7 +731,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, (selector, field+)) : unique/key/keyref const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartState); @@ -751,7 +752,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, (simpleType | complexType)?) : alternative const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -769,7 +770,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (appinfo | documentation)* : annotation const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -785,7 +786,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, (restriction | list | union)) : simpleType const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartState); @@ -806,7 +807,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern | assertion)*)) : simple type restriction const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -877,7 +878,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, simpleType?) : list const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -893,7 +894,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, simpleType*) : union const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -910,7 +911,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for ((include | import | redefine |i override | annotation)*, (defaultOpenContent, annotation*)?, (((simpleType | complexType | group | attributeGroup) | element | attribute | notation), annotation*)*) : schema const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -987,7 +988,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation?, any) : defaultOpenContent const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -1003,7 +1004,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation | (simpleType | complexType | group | attributeGroup))* : redefine const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -1025,7 +1026,7 @@ void XsdSchemaParser::setupStateMachines() } { - XsdStateMachine<XsdSchemaToken::NodeName> machine(m_namePool); + XsdStateMachine<XsdSchemaToken::NodeName> machine(namePool); // setup state machine for (annotation | (simpleType | complexType | group | attributeGroup | element | attribute | notation))* : override const XsdStateMachine<XsdSchemaToken::NodeName>::StateId startState = machine.addState(XsdStateMachine<XsdSchemaToken::NodeName>::StartEndState); @@ -1055,56 +1056,57 @@ void XsdSchemaParser::setupStateMachines() void XsdSchemaParser::setupBuiltinTypeNames() { + NamePool::Ptr namePool(m_namePool); m_builtinTypeNames.reserve(48); - m_builtinTypeNames.insert(BuiltinTypes::xsAnyType->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsAnySimpleType->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsUntyped->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsAnyAtomicType->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsUntypedAtomic->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsDateTime->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsDate->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsTime->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsDuration->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsYearMonthDuration->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsDayTimeDuration->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsFloat->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsDouble->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsInteger->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsDecimal->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsNonPositiveInteger->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsNegativeInteger->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsLong->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsInt->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsShort->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsByte->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsNonNegativeInteger->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedLong->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedInt->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedShort->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedByte->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsPositiveInteger->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsGYearMonth->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsGYear->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsGMonthDay->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsGDay->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsGMonth->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsBoolean->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsBase64Binary->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsHexBinary->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsAnyURI->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsQName->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsString->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsNormalizedString->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsToken->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsLanguage->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsNMTOKEN->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsName->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsNCName->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsID->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsIDREF->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsENTITY->name(m_namePool)); - m_builtinTypeNames.insert(BuiltinTypes::xsNOTATION->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsAnyType->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsAnySimpleType->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsUntyped->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsAnyAtomicType->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsUntypedAtomic->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsDateTime->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsDate->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsTime->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsDuration->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsYearMonthDuration->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsDayTimeDuration->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsFloat->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsDouble->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsInteger->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsDecimal->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNonPositiveInteger->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNegativeInteger->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsLong->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsInt->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsShort->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsByte->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNonNegativeInteger->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedLong->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedInt->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedShort->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedByte->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsPositiveInteger->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsGYearMonth->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsGYear->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsGMonthDay->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsGDay->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsGMonth->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsBoolean->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsBase64Binary->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsHexBinary->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsAnyURI->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsQName->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsString->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNormalizedString->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsToken->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsLanguage->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNMTOKEN->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsName->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNCName->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsID->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsIDREF->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsENTITY->name(namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNOTATION->name(namePool)); } QT_END_NAMESPACE diff --git a/tests/auto/collections/tst_collections.cpp b/tests/auto/collections/tst_collections.cpp index 00cdec3..e13e1d9 100644 --- a/tests/auto/collections/tst_collections.cpp +++ b/tests/auto/collections/tst_collections.cpp @@ -2442,6 +2442,7 @@ void tst_Collections::cache() QVERIFY(!cache.contains(2)); delete cache.take(10); } +#if 0 { QCache<int, QString> cache(120); int i; @@ -2455,6 +2456,7 @@ void tst_Collections::cache() QVERIFY(!cache.contains(3)); QVERIFY(cache.contains(2)); } +#endif { QCache<int, int> cache(100); cache.insert(2, new int(2)); @@ -3505,7 +3507,7 @@ void testVectorAlignment() for (int i = 0; i < 200; ++i) container.append(Aligned()); - + for (int i = 0; i < container.size(); ++i) QVERIFY(container.at(i).checkAligned()); } diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index fde0588..33f74a9 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -147,6 +147,8 @@ private slots: void pastingRichText_QTBUG_14003(); void implicitSize_data(); void implicitSize(); + void implicitSizePreedit_data(); + void implicitSizePreedit(); void testQtQuick11Attributes(); void testQtQuick11Attributes_data(); @@ -2368,6 +2370,48 @@ void tst_qdeclarativetextedit::implicitSize() QVERIFY(textObject->height() == textObject->implicitHeight()); } +void tst_qdeclarativetextedit::implicitSizePreedit_data() +{ + QTest::addColumn<QString>("text"); + QTest::addColumn<QString>("wrap"); + QTest::addColumn<bool>("wrapped"); + QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap" << false; + QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap" << true; + +} + +void tst_qdeclarativetextedit::implicitSizePreedit() +{ + QFETCH(QString, text); + QFETCH(QString, wrap); + QFETCH(bool, wrapped); + + QString componentStr = "import QtQuick 1.1\nTextEdit { focus: true; width: 50; wrapMode: " + wrap + " }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeTextEdit *textObject = qobject_cast<QDeclarativeTextEdit*>(textComponent.create()); + + QGraphicsScene scene; + QGraphicsView view(&scene); + scene.addItem(textObject); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view)); + + QInputMethodEvent event(text, QList<QInputMethodEvent::Attribute>()); + QCoreApplication::sendEvent(&view, &event); + + QVERIFY(textObject->width() < textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); + qreal wrappedHeight = textObject->height(); + + textObject->resetWidth(); + QVERIFY(textObject->width() == textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); + QCOMPARE(textObject->height() < wrappedHeight, wrapped); +} + void tst_qdeclarativetextedit::testQtQuick11Attributes() { QFETCH(QString, code); diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 419eaae..9693480 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -1133,6 +1133,11 @@ void tst_QDir::absolutePath_data() QTest::newRow("4") << "c:/machine/share/dir1" << "c:/machine/share/dir1"; QTest::newRow("5") << "c:\\machine\\share\\dir1" << "c:/machine/share/dir1"; #endif + //test dirty paths are cleaned (QTBUG-19995) + QTest::newRow("/home/qt/.") << QDir::rootPath() + "home/qt/." << QDir::rootPath() + "home/qt"; + QTest::newRow("/system/data/../config") << QDir::rootPath() + "system/data/../config" << QDir::rootPath() + "system/config"; + QTest::newRow("//home//qt/") << QDir::rootPath() + "/home//qt/" << QDir::rootPath() + "home/qt"; + QTest::newRow("foo/../bar") << "foo/../bar" << QDir::currentPath() + "/bar"; QTest::newRow("resource") << ":/prefix/foo.bar" << ":/prefix/foo.bar"; } @@ -1942,6 +1947,34 @@ void tst_QDir::equalityOperator_data() << "./entrylist" << "*.cpp" << int(QDir::Name) << int(QDir::Files) << true; + QTest::newRow("QTBUG-20495") << QDir::currentPath() + "/entrylist/.." << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << "." << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << true; + + //need a path in the root directory that is unlikely to be a symbolic link. +#if defined (Q_OS_WIN) + QString pathinroot("c:/windows/.."); +#elif defined (Q_OS_SYMBIAN) + QString pathinroot("c:/data/.."); +#else + QString pathinroot("/sbin/.."); +#endif + QTest::newRow("QTBUG-20495-root") << pathinroot << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << QDir::rootPath() << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << true; + + QTest::newRow("slashdot") << QDir::rootPath() + "." << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << QDir::rootPath() << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << true; + + QTest::newRow("slashdotslash") << QDir::rootPath() + "./" << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << QDir::rootPath() << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << true; + + QTest::newRow("nonexistantpaths") << "dir-that-dont-exist" << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << "another-dir-that-dont-exist" << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << false; + QTest::newRow("diff-filters") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files) << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Dirs) << false; diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index c7d9979..d7d57f6 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -482,6 +482,11 @@ void tst_QFileInfo::absolutePath_data() QTest::newRow("c:\\autoexec.bat") << "c:\\autoexec.bat" << "C:/" << "autoexec.bat"; #endif + QTest::newRow("QTBUG-19995.1") << drivePrefix + "/System/Library/StartupItems/../Frameworks" + << drivePrefix + "/System/Library" + << "Frameworks"; + QTest::newRow("QTBUG-19995.2") << drivePrefix + "/System/Library/StartupItems/../Frameworks/" + << drivePrefix + "/System/Library/Frameworks" << ""; } void tst_QFileInfo::absolutePath() @@ -503,6 +508,7 @@ void tst_QFileInfo::absFilePath_data() QTest::newRow("relativeFile") << "tmp.txt" << QDir::currentPath() + "/tmp.txt"; QTest::newRow("relativeFileInSubDir") << "temp/tmp.txt" << QDir::currentPath() + "/" + "temp/tmp.txt"; + QString drivePrefix; #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN) QString curr = QDir::currentPath(); @@ -511,7 +517,7 @@ void tst_QFileInfo::absFilePath_data() QTest::newRow("absFilePath") << "c:\\home\\andy\\tmp.txt" << "C:/home/andy/tmp.txt"; // Make sure drive-relative paths return correct absolute paths (task 255326) - QString drivePrefix = QDir::currentPath().left(2); + drivePrefix = QDir::currentPath().left(2); QString nonCurrentDrivePrefix = drivePrefix.left(1).compare("X", Qt::CaseInsensitive) == 0 ? QString("Y:") : QString("X:"); @@ -521,6 +527,8 @@ void tst_QFileInfo::absFilePath_data() #else QTest::newRow("absFilePath") << "/home/andy/tmp.txt" << "/home/andy/tmp.txt"; #endif + QTest::newRow("QTBUG-19995") << drivePrefix + "/System/Library/StartupItems/../Frameworks" + << drivePrefix + "/System/Library/Frameworks"; } void tst_QFileInfo::absFilePath() @@ -1395,7 +1403,7 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data() wchar_t errstr[0x100]; DWORD count = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 0, err, 0, errstr, 0x100, 0); - QString error(QString::fromUtf16(errstr, count)); + QString error(QString::fromWCharArray (errstr, count)); qWarning() << error; //we need at least one data set for the test not to assert fail when skipping _data function QDir target("target"); diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp index 016bcbf..2daabee 100644 --- a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -68,6 +68,8 @@ private slots: void absoluteOrRelative_data(); void absoluteOrRelative(); #endif + void isClean_data(); + void isClean(); }; #if defined(WIN_STUFF) @@ -383,5 +385,35 @@ void tst_QFileSystemEntry::absoluteOrRelative() } #endif +void tst_QFileSystemEntry::isClean_data() +{ + QTest::addColumn<QString>("path"); + QTest::addColumn<bool>("isClean"); + + QTest::newRow("simple") << "foo" << true; + QTest::newRow("complex") << "/foo/bar/bz" << true; + QTest::newRow(".file") << "/foo/.file" << true; + QTest::newRow("..file") << "/foo/..file" << true; + QTest::newRow("...") << "/foo/.../bar" << true; + QTest::newRow("./") << "./" << false; + QTest::newRow("../") << "../" << false; + QTest::newRow(".") << "." << false; + QTest::newRow("..") << ".." << false; + QTest::newRow("/.") << "/." << false; + QTest::newRow("/..") << "/.." << false; + QTest::newRow("/../") << "foo/../bar" << false; + QTest::newRow("/./") << "foo/./bar" << false; + QTest::newRow("//") << "foo//bar" << false; +} + +void tst_QFileSystemEntry::isClean() +{ + QFETCH(QString, path); + QFETCH(bool, isClean); + + QFileSystemEntry fi(path); + QCOMPARE(fi.isClean(), isClean); +} + QTEST_MAIN(tst_QFileSystemEntry) #include <tst_qfilesystementry.moc> diff --git a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp index 1f5563c..9c189cb 100644 --- a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp @@ -78,6 +78,8 @@ private slots: void dropShadowClipping(); void childrenVisibilityShouldInvalidateCache(); void prepareGeometryChangeInvalidateCache(); + void graphicsEffectUpdateShouldNotInvalidateGraphicsItemCache(); + void graphicsEffectUpdateShouldInvalidateParentGraphicsEffect(); void itemHasNoContents(); }; @@ -732,6 +734,99 @@ void tst_QGraphicsEffect::prepareGeometryChangeInvalidateCache() QCOMPARE(item->nbPaint, 0); } +class MyGraphicsEffect : public QGraphicsEffect +{ + public: + MyGraphicsEffect(QObject *parent = 0) : + QGraphicsEffect(parent), nbSourceInvalidations(0) + {} + int nbSourceInvalidations; + protected: + void draw(QPainter *painter) + { + drawSource(painter); + } + + void sourceChanged(ChangeFlags flags) + { + if (flags == SourceInvalidated) + nbSourceInvalidations++; + } +}; + +void tst_QGraphicsEffect::graphicsEffectUpdateShouldNotInvalidateGraphicsItemCache() +{ + QGraphicsScene scene; + MyGraphicsItem parent; + parent.resize(200, 200); + parent.setCacheMode(QGraphicsItem::ItemCoordinateCache); + scene.addItem(&parent); + + QGraphicsView view(&scene); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(parent.nbPaint, 1); + + //we set an effect on the parent + MyGraphicsEffect* opacityEffect = new MyGraphicsEffect(&parent); + opacityEffect->update(); + parent.setGraphicsEffect(opacityEffect); + //flush the events + QApplication::processEvents(); + //new effect applied->repaint + QCOMPARE(parent.nbPaint, 1); + + opacityEffect->update(); + //flush the events + QApplication::processEvents(); + //A change to the effect shouldn't invalidate the graphicsitem's cache + // => it shouldn't trigger a paint + QCOMPARE(parent.nbPaint, 1); +} + +void tst_QGraphicsEffect::graphicsEffectUpdateShouldInvalidateParentGraphicsEffect() +{ + QGraphicsScene scene; + // Add the parent + MyGraphicsItem parent; + parent.resize(200, 200); + scene.addItem(&parent); + // Add a child to the parent + MyGraphicsItem child(&parent); + child.resize(100, 100); + + QGraphicsView view(&scene); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + //flush the events + QApplication::processEvents(); + QTRY_COMPARE(parent.nbPaint, 1); + QTRY_COMPARE(child.nbPaint, 1); + + //we set an effect on the parent and the child + MyGraphicsEffect* effectForParent = new MyGraphicsEffect(&parent); + parent.setGraphicsEffect(effectForParent); + + MyGraphicsEffect* effectForChild = new MyGraphicsEffect(&child); + child.setGraphicsEffect(effectForChild); + //flush the events + QApplication::processEvents(); + // Both effects should start with no source invalidations + QCOMPARE(effectForParent->nbSourceInvalidations, 0); + QCOMPARE(effectForChild->nbSourceInvalidations, 0); + + // Trigger an update of the child graphics effect + effectForChild->update(); + //flush the events + QApplication::processEvents(); + // An update of the effect on the child shouldn't tell that effect that its source has been invalidated + QCOMPARE(effectForChild->nbSourceInvalidations, 0); + // The effect on the parent should however be notified of an invalidated source + QCOMPARE(effectForParent->nbSourceInvalidations, 1); +} + void tst_QGraphicsEffect::itemHasNoContents() { QGraphicsRectItem *parent = new QGraphicsRectItem; diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index b8741fe..8a26323 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -290,6 +290,7 @@ private slots: void taskQT_3674_doNotCrash(); void taskQTBUG_15977_renderWithDeviceCoordinateCache(); void taskQTBUG_16401_focusItem(); + void taskQTBUG_19680_tabWidgetFocus(); }; void tst_QGraphicsScene::initTestCase() @@ -4711,5 +4712,72 @@ void tst_QGraphicsScene::taskQTBUG_16401_focusItem() QVERIFY(!scene.focusItem()); } +void tst_QGraphicsScene::taskQTBUG_19680_tabWidgetFocus() +{ + QTabWidget tabWidget; + QGraphicsScene scene1; + QGraphicsScene scene2; + QGraphicsView view1(&scene1); + QGraphicsView view2(&scene2); + + tabWidget.show(); + + tabWidget.addTab(&view1, "view1"); + tabWidget.setCurrentWidget(&view1); + + QGraphicsTextItem *textItem1 = scene1.addText("Text1"); + textItem1->setFlags(QGraphicsItem::ItemIsFocusable); + textItem1->setTextInteractionFlags(Qt::TextEditorInteraction); + textItem1->setEnabled(true); + textItem1->setFocus(); + + tabWidget.addTab(&view2, "view2"); + tabWidget.setCurrentWidget(&view2); + + QGraphicsTextItem *textItem2 = scene2.addText("Text2"); + textItem2->setFlags(QGraphicsItem::ItemIsFocusable); + textItem2->setTextInteractionFlags(Qt::TextEditorInteraction); + textItem2->setEnabled(true); + textItem2->setFocus(); + + scene2.clearFocus(); + + view2.clearFocus(); + view2.setEnabled(false); + view2.setInteractive(false); + view2.setVisible(false); + view2.setShown(false); + view2.hide(); + + tabWidget.clearFocus(); + tabWidget.setEnabled(false); + tabWidget.setShown(false); + tabWidget.setVisible(false); + tabWidget.hide(); + + tabWidget.setFocus(); + tabWidget.setEnabled(true); + tabWidget.activateWindow(); + tabWidget.setShown(true); + tabWidget.setVisible(true); + tabWidget.show(); + + view2.setFocus(); + view2.setEnabled(true); + view2.activateWindow(); + view2.setInteractive(true); + view2.setVisible(true); + view2.setShown(true); + view2.show(); + + QTest::qWaitForWindowShown(&view2); + QApplication::setActiveWindow(&tabWidget); + + textItem2->setFocus(); + + QVERIFY(scene2.isActive()); + QVERIFY(textItem2->hasFocus()); +} + QTEST_MAIN(tst_QGraphicsScene) #include "tst_qgraphicsscene.moc" diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 1df9d38..7b273d2 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -124,6 +124,8 @@ private slots: void layout(); void layoutDirection_data(); void layoutDirection(); + void recursiveLayoutDirection_data(); + void recursiveLayoutDirection(); void paint_data(); void paint(); void palettePropagation(); @@ -1213,14 +1215,20 @@ void tst_QGraphicsWidget::layout() void tst_QGraphicsWidget::layoutDirection_data() { QTest::addColumn<Qt::LayoutDirection>("layoutDirection"); - QTest::newRow("rtl") << Qt::RightToLeft; - QTest::newRow("ltr") << Qt::LeftToRight; + QTest::addColumn<bool>("setDirectionBeforeAddingWidget"); + + QTest::newRow("rtl, setting direction before adding widget") << Qt::RightToLeft << true; + QTest::newRow("ltr, setting direction before adding widget") << Qt::LeftToRight << true; + QTest::newRow("rtl, setting direction after adding widget") << Qt::RightToLeft << false; + QTest::newRow("ltr, setting direction after adding widget") << Qt::LeftToRight << false; + } // Qt::LayoutDirection layoutDirection() const public void tst_QGraphicsWidget::layoutDirection() { QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(bool, setDirectionBeforeAddingWidget); QGraphicsScene scene; QGraphicsView *view = new QGraphicsView(&scene); SubQGraphicsWidget widget; @@ -1228,13 +1236,16 @@ void tst_QGraphicsWidget::layoutDirection() QCOMPARE(widget.layoutDirection(), Qt::LeftToRight); QCOMPARE(widget.testAttribute(Qt::WA_SetLayoutDirection), false); + if (setDirectionBeforeAddingWidget) + widget.setLayoutDirection(layoutDirection); QList<SubQGraphicsWidget*> children; for (int i = 0; i < 10; ++i) { SubQGraphicsWidget *item = new SubQGraphicsWidget(&widget); children.append(item); QCOMPARE(item->testAttribute(Qt::WA_SetLayoutDirection), false); } - widget.setLayoutDirection(layoutDirection); + if (!setDirectionBeforeAddingWidget) + widget.setLayoutDirection(layoutDirection); QCOMPARE(widget.testAttribute(Qt::WA_SetLayoutDirection), true); view->show(); QTest::qWaitForWindowShown(view); @@ -1247,6 +1258,42 @@ void tst_QGraphicsWidget::layoutDirection() delete view; } +void tst_QGraphicsWidget::recursiveLayoutDirection_data() +{ + QTest::addColumn<Qt::LayoutDirection>("layoutDirection"); + QTest::addColumn<bool>("setDirectionBeforeAddingWidget"); + + QTest::newRow("rtl, setting direction before adding widget") << Qt::RightToLeft << true; + QTest::newRow("ltr, setting direction before adding widget") << Qt::LeftToRight << true; + QTest::newRow("rtl, setting direction after adding widget") << Qt::RightToLeft << false; + QTest::newRow("ltr, setting direction after adding widget") << Qt::LeftToRight << false; +} + +void tst_QGraphicsWidget::recursiveLayoutDirection() +{ + QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(bool, setDirectionBeforeAddingWidget); + QGraphicsWidget *widget = new QGraphicsWidget; + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(widget); + QGraphicsWidget *widget2 = new QGraphicsWidget; + QGraphicsLinearLayout *layout2 = new QGraphicsLinearLayout(widget2); + QGraphicsWidget *widget3 = new QGraphicsWidget; + QGraphicsLinearLayout *layout3 = new QGraphicsLinearLayout(widget3); + + if (setDirectionBeforeAddingWidget) + widget->setLayoutDirection(layoutDirection); + layout->addItem(widget2); + layout2->addItem(widget3); + if (!setDirectionBeforeAddingWidget) + widget->setLayoutDirection(layoutDirection); + + QCOMPARE(widget->layoutDirection(), layoutDirection); + QCOMPARE(widget2->layoutDirection(), layoutDirection); + QCOMPARE(widget3->layoutDirection(), layoutDirection); + + delete widget; +} + void tst_QGraphicsWidget::paint_data() { // currently QGraphicsWidget doesn't paint or do anything ... diff --git a/tests/auto/qmdiarea/tst_qmdiarea.cpp b/tests/auto/qmdiarea/tst_qmdiarea.cpp index c752362..f782bf8 100644 --- a/tests/auto/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/qmdiarea/tst_qmdiarea.cpp @@ -661,7 +661,7 @@ void tst_QMdiArea::changeWindowTitle() #else widget->setWindowState(Qt::WindowMaximized); #endif -#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) +#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QTRY_COMPARE( mw->windowTitle(), QString::fromLatin1("%1 - [%2]").arg(mwc).arg(wc) ); #endif @@ -671,7 +671,7 @@ void tst_QMdiArea::changeWindowTitle() qApp->processEvents(); QTest::qWaitForWindowShown(mw); -#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) +#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QTRY_COMPARE( mw->windowTitle(), QString::fromLatin1("%1 - [%2]").arg(mwc).arg(wc) ); #endif @@ -689,7 +689,7 @@ void tst_QMdiArea::changeWindowTitle() widget->setWindowState(Qt::WindowMaximized); #endif qApp->processEvents(); -#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) +#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QTRY_COMPARE( mw->windowTitle(), QString::fromLatin1("%1 - [%2]").arg(mwc).arg(wc) ); widget->setWindowTitle( wc2 ); QCOMPARE( mw->windowTitle(), QString::fromLatin1("%1 - [%2]").arg(mwc).arg(wc2) ); @@ -707,7 +707,7 @@ void tst_QMdiArea::changeWindowTitle() #endif qApp->processEvents(); -#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) +#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QCOMPARE( mw->windowTitle(), QString::fromLatin1("%1 - [%2]").arg(mwc2).arg(wc2) ); #endif #ifdef USE_SHOW @@ -716,7 +716,7 @@ void tst_QMdiArea::changeWindowTitle() widget->setWindowState(Qt::WindowNoState); #endif qApp->processEvents(); -#if defined(Q_WS_MAC) || defined(Q_OS_WINCE) +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) QCOMPARE(mw->windowTitle(), mwc); #else QCOMPARE( mw->windowTitle(), mwc2 ); @@ -728,7 +728,7 @@ void tst_QMdiArea::changeWindowTitle() widget->setWindowState(Qt::WindowMaximized); #endif qApp->processEvents(); -#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) +#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QCOMPARE( mw->windowTitle(), QString::fromLatin1("%1 - [%2]").arg(mwc2).arg(wc2) ); #endif @@ -777,7 +777,7 @@ void tst_QMdiArea::changeModified() QCOMPARE( mw->isWindowModified(), false); QCOMPARE( widget->isWindowModified(), true); widget->setWindowState(Qt::WindowMaximized); -#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) +#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QCOMPARE( mw->isWindowModified(), true); #endif QCOMPARE( widget->isWindowModified(), true); @@ -787,7 +787,7 @@ void tst_QMdiArea::changeModified() QCOMPARE( widget->isWindowModified(), true); widget->setWindowState(Qt::WindowMaximized); -#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) +#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QCOMPARE( mw->isWindowModified(), true); #endif QCOMPARE( widget->isWindowModified(), true); @@ -797,7 +797,7 @@ void tst_QMdiArea::changeModified() QCOMPARE( widget->isWindowModified(), false); widget->setWindowModified(true); -#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) +#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QCOMPARE( mw->isWindowModified(), true); #endif QCOMPARE( widget->isWindowModified(), true); @@ -2046,7 +2046,7 @@ void tst_QMdiArea::delayedPlacement() void tst_QMdiArea::iconGeometryInMenuBar() { -#if !defined (Q_WS_MAC) && !defined(Q_OS_WINCE) +#if !defined (Q_WS_MAC) && !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QMainWindow mainWindow; QMenuBar *menuBar = mainWindow.menuBar(); QMdiArea *mdiArea = new QMdiArea; diff --git a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp index 9f7192d..b36cf98 100644 --- a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp +++ b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp @@ -72,6 +72,7 @@ private slots: void clear(); void pixmapKey(); void noLeak(); + void strictCacheLimit(); }; static QPixmapCache::KeyData* getPrivate(QPixmapCache::Key &key) @@ -517,5 +518,29 @@ void tst_QPixmapCache::noLeak() QCOMPARE(oldSize, newSize); } + +void tst_QPixmapCache::strictCacheLimit() +{ + const int limit = 1024; // 1024 KB + + QPixmapCache::clear(); + QPixmapCache::setCacheLimit(limit); + + // insert 200 64x64 pixmaps + // 3200 KB for 32-bit depths + // 1600 KB for 16-bit depths + // not counting the duplicate entries + for (int i = 0; i < 200; ++i) { + QPixmap pixmap(64, 64); + pixmap.fill(Qt::transparent); + + QString id = QString::number(i); + QPixmapCache::insert(id + "-a", pixmap); + QPixmapCache::insert(id + "-b", pixmap); + } + + QVERIFY(QPixmapCache::totalUsed() <= limit); +} + QTEST_MAIN(tst_QPixmapCache) #include "tst_qpixmapcache.moc" diff --git a/tests/auto/qpluginloader/tst_qpluginloader.cpp b/tests/auto/qpluginloader/tst_qpluginloader.cpp index d2d92a5..152d1f4 100644 --- a/tests/auto/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/qpluginloader/tst_qpluginloader.cpp @@ -272,10 +272,10 @@ void tst_QPluginLoader::loadHints() void tst_QPluginLoader::deleteinstanceOnUnload() { - for (int pass = 0; pass < 2; ++pass) { + for (int pass = 0; pass < 4; ++pass) { QPluginLoader loader1; loader1.setFileName( sys_qualifiedLibraryName("theplugin")); //a plugin - if (pass == 0) + if (pass < 2) loader1.load(); // not recommended, instance() should do the job. PluginInterface *instance1 = qobject_cast<PluginInterface*>(loader1.instance()); QVERIFY(instance1); @@ -283,21 +283,32 @@ void tst_QPluginLoader::deleteinstanceOnUnload() QPluginLoader loader2; loader2.setFileName( sys_qualifiedLibraryName("theplugin")); //a plugin - if (pass == 0) + if (pass < 2) loader2.load(); // not recommended, instance() should do the job. PluginInterface *instance2 = qobject_cast<PluginInterface*>(loader2.instance()); QCOMPARE(instance2->pluginName(), QLatin1String("Plugin ok")); QSignalSpy spy1(loader1.instance(), SIGNAL(destroyed())); QSignalSpy spy2(loader2.instance(), SIGNAL(destroyed())); - if (pass == 0) { - QCOMPARE(loader2.unload(), false); // refcount not reached 0, not really unloaded - QCOMPARE(spy1.count(), 0); - QCOMPARE(spy2.count(), 0); - } + + // refcount not reached 0, not really unloaded + if (pass % 2) + QCOMPARE(loader1.unload(), false); + else + QCOMPARE(loader2.unload(), false); + + QCOMPARE(spy1.count(), 0); + QCOMPARE(spy2.count(), 0); + QCOMPARE(instance1->pluginName(), QLatin1String("Plugin ok")); QCOMPARE(instance2->pluginName(), QLatin1String("Plugin ok")); - QVERIFY(loader1.unload()); // refcount reached 0, did really unload + + // refcount reached 0, did really unload + if (pass % 2) + QVERIFY(loader2.unload()); + else + QVERIFY(loader1.unload()); + QCOMPARE(spy1.count(), 1); QCOMPARE(spy2.count(), 1); } diff --git a/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp index f4249ab..336dc71 100644 --- a/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -2320,10 +2320,6 @@ void tst_QtConcurrentMap::stlContainers() { #ifdef QT_NO_STL QSKIP("Qt compiled without STL support", SkipAll); -#elif defined(Q_COMPILER_RVALUE_REFS) - //mapped uses &Container::push_back, but in c++0x, std::vector has two overload of it - // meaning it is not possible to take the address of that function anymore. - QSKIP("mapped do not work with c++0x stl vector", SkipAll); #else std::vector<int> vector; vector.push_back(1); diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp index 42ea3b1..73d09f4 100644 --- a/tests/auto/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/qtextedit/tst_qtextedit.cpp @@ -138,6 +138,8 @@ private slots: void textSemantics(); #endif void cursorPositionChanged(); + void mouseSelection(); + void mouseSelectionDClick(); void setTextCursor(); #ifndef QT_NO_CLIPBOARD void undoAvailableAfterPaste(); @@ -785,6 +787,45 @@ void tst_QTextEdit::cursorPositionChanged() QCOMPARE(ed->textCursor().position(), 0); } +void tst_QTextEdit::mouseSelection() +{ + ed->show(); + ed->setPlainText(("Hello World")); + QTextCursor cursor = ed->textCursor(); + cursor.setPosition(1); + QPoint p1 = ed->cursorRect(cursor).center(); + cursor.setPosition(10); + QPoint p2 = ed->cursorRect(cursor).center(); + QTest::mousePress(ed->viewport(), Qt::LeftButton, 0, p1); + { QMouseEvent ev(QEvent::MouseMove, p2, Qt::LeftButton, Qt::LeftButton, 0); + QCoreApplication::sendEvent(ed->viewport(), &ev); } + QTest::mouseRelease(ed->viewport(), Qt::LeftButton, 0, p2); + QVERIFY(ed->textCursor().hasSelection()); + QCOMPARE(ed->textCursor().selectedText(), QString("ello Worl")); + +} + +void tst_QTextEdit::mouseSelectionDClick() +{ + ed->show(); + ed->setPlainText(("Hello World")); + QTextCursor cursor = ed->textCursor(); + cursor.setPosition(1); + QPoint p1 = ed->cursorRect(cursor).center(); + cursor.setPosition(10); + QPoint p2 = ed->cursorRect(cursor).center(); + QTest::mousePress(ed->viewport(), Qt::LeftButton, 0, p1); + QTest::mouseRelease(ed->viewport(), Qt::LeftButton, 0, p1); + QTest::mouseDClick(ed->viewport(), Qt::LeftButton, 0, p1); + QVERIFY(ed->textCursor().hasSelection()); + QCOMPARE(ed->textCursor().selectedText(), QString("Hello")); + { QMouseEvent ev(QEvent::MouseMove, p2, Qt::LeftButton, Qt::LeftButton, 0); + QCoreApplication::sendEvent(ed->viewport(), &ev); } + QTest::mouseRelease(ed->viewport(), Qt::LeftButton, 0, p2); + QVERIFY(ed->textCursor().hasSelection()); + QCOMPARE(ed->textCursor().selectedText(), QString("Hello World")); +} + void tst_QTextEdit::setTextCursor() { QSignalSpy spy(ed, SIGNAL(cursorPositionChanged())); diff --git a/tests/auto/qtextlayout/tst_qtextlayout.cpp b/tests/auto/qtextlayout/tst_qtextlayout.cpp index 2414ab3..67d8269 100644 --- a/tests/auto/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/qtextlayout/tst_qtextlayout.cpp @@ -129,6 +129,7 @@ private slots: void textWidthWithLineSeparator(); void cursorInLigatureWithMultipleLines(); void xToCursorForLigatures(); + void cursorInNonStopChars(); private: QFont testFont; @@ -1465,7 +1466,7 @@ void tst_QTextLayout::textWidthWithLineSeparator() void tst_QTextLayout::cursorInLigatureWithMultipleLines() { #if !defined(Q_WS_MAC) - QSKIP("This test can not be run on Mac", SkipAll); + QSKIP("This test can only be run on Mac", SkipAll); #endif QTextLayout layout("first line finish", QFont("Times", 20)); layout.beginLayout(); @@ -1481,7 +1482,7 @@ void tst_QTextLayout::cursorInLigatureWithMultipleLines() void tst_QTextLayout::xToCursorForLigatures() { #if !defined(Q_WS_MAC) - QSKIP("This test can not be run on Mac", SkipAll); + QSKIP("This test can only be run on Mac", SkipAll); #endif QTextLayout layout("fi", QFont("Times", 20)); layout.beginLayout(); @@ -1502,5 +1503,19 @@ void tst_QTextLayout::xToCursorForLigatures() line.xToCursor(width) == line.xToCursor(width / 2)); } +void tst_QTextLayout::cursorInNonStopChars() +{ +#if defined(Q_WS_MAC) + QSKIP("This test can not be run on Mac", SkipAll); +#endif + QTextLayout layout(QString::fromUtf8("\xE0\xA4\xA4\xE0\xA5\x8D\xE0\xA4\xA8")); + layout.beginLayout(); + QTextLine line = layout.createLine(); + layout.endLayout(); + + QVERIFY(line.cursorToX(1) == line.cursorToX(3)); + QVERIFY(line.cursorToX(2) == line.cursorToX(3)); +} + QTEST_MAIN(tst_QTextLayout) #include "tst_qtextlayout.moc" diff --git a/tests/auto/xmlpatternsschemats/TESTSUITE/updateSuite.sh b/tests/auto/xmlpatternsschemats/TESTSUITE/updateSuite.sh index a61f0a1..894fa5a 100755 --- a/tests/auto/xmlpatternsschemats/TESTSUITE/updateSuite.sh +++ b/tests/auto/xmlpatternsschemats/TESTSUITE/updateSuite.sh @@ -47,6 +47,8 @@ # # To run the script, Saxon package version 9 and above shall be installed # +# Installation instruction +# http://johnbokma.com/mexit/2011/07/04/installing-saxon-he-ubuntu.html DIRECTORY_NAME="xmlschema2006-11-06" ARCHIVE_NAME="xsts-2007-06-20.tar.gz" @@ -62,5 +64,6 @@ rm $ARCHIVE_NAME #CVSROOT=:pserver:anonymous@dev.w3.org:/sources/public cvs checkout -d xmlschema2006-11-06-new XML/xml-schema-test-suite/2004-01-14/xmlschema2006-11-06 #Saxon need to be installed before the following command works. -java -jar /usr/share/java/saxon.jar -xsl:unifyCatalog.xsl -s:$DIRECTORY_NAME/suite.xml > testSuites.xml +#java -jar /usr/share/java/saxonb.jar -xsl:unifyCatalog.xsl -s:$DIRECTORY_NAME/suite.xml > testSuites.xml +saxon9he-xslt -xsl:unifyCatalog.xsl -s:$DIRECTORY_NAME/suite.xml > testSuites.xml diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 31c359e..e6d8526 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3599,17 +3599,21 @@ void Configure::displayConfig() #if !defined(EVAL) void Configure::generateHeaders() { - if (dictionary["SYNCQT"] == "yes" - && findFile("perl.exe")) { - cout << "Running syncqt..." << endl; - QStringList args; - args += buildPath + "/bin/syncqt.bat"; - QStringList env; - env += QString("QTDIR=" + sourcePath); - env += QString("PATH=" + buildPath + "/bin/;" + qgetenv("PATH")); - int retc = Environment::execute(args, env, QStringList()); - if (retc) { - cout << "syncqt failed, return code " << retc << endl << endl; + if (dictionary["SYNCQT"] == "yes") { + if (findFile("perl.exe")) { + cout << "Running syncqt..." << endl; + QStringList args; + args += buildPath + "/bin/syncqt.bat"; + QStringList env; + env += QString("QTDIR=" + sourcePath); + env += QString("PATH=" + buildPath + "/bin/;" + qgetenv("PATH")); + int retc = Environment::execute(args, env, QStringList()); + if (retc) { + cout << "syncqt failed, return code " << retc << endl << endl; + dictionary["DONE"] = "error"; + } + } else { + cout << "Perl not found in environment - cannot run syncqt." << endl; dictionary["DONE"] = "error"; } } diff --git a/tools/qdoc3/cppcodemarker.cpp b/tools/qdoc3/cppcodemarker.cpp index 37c2c3a..743688f 100644 --- a/tools/qdoc3/cppcodemarker.cpp +++ b/tools/qdoc3/cppcodemarker.cpp @@ -919,7 +919,7 @@ QString CppCodeMarker::addMarkUp(const QString &in, int i = 0; int start = 0; int finish = 0; - char ch; + QChar ch; QRegExp classRegExp("Qt?(?:[A-Z3]+[a-z][A-Za-z]*|t)"); QRegExp functionRegExp("q([A-Z][a-z]+)+"); @@ -929,13 +929,13 @@ QString CppCodeMarker::addMarkUp(const QString &in, QString tag; bool target = false; - if (isalpha(ch) || ch == '_') { + if (ch.isLetter() || ch == '_') { QString ident; do { - ident += ch; - finish = i; - readChar(); - } while (ch >= 0 && isalnum(ch) || ch == '_'); + ident += ch; + finish = i; + readChar(); + } while (ch.isLetterOrNumber() || ch == '_'); if (classRegExp.exactMatch(ident)) { tag = QLatin1String("type"); @@ -952,14 +952,14 @@ QString CppCodeMarker::addMarkUp(const QString &in, tag = QLatin1String("func"); target = true; } - } else if (isdigit(ch)) { + } else if (ch.isDigit()) { do { finish = i; readChar(); - } while (isalnum(ch) || ch == '.'); + } while (ch.isLetterOrNumber() || ch == '.'); tag = QLatin1String("number"); } else { - switch (ch) { + switch (ch.unicode()) { case '+': case '-': case '!': diff --git a/tools/qvfb/qvfb.pro b/tools/qvfb/qvfb.pro index df68c97..ca8f4f4 100644 --- a/tools/qvfb/qvfb.pro +++ b/tools/qvfb/qvfb.pro @@ -19,7 +19,10 @@ HEADERS = qvfb.h \ gammaview.h \ qvfbprotocol.h \ qvfbshmem.h \ - qvfbmmap.h + qvfbmmap.h \ + ../../src/gui/embedded/qlock_p.h \ + ../../src/gui/embedded/qwslock_p.h \ + ../../src/gui/embedded/qwssignalhandler_p.h SOURCES = qvfb.cpp \ qvfbview.cpp \ @@ -28,7 +31,10 @@ SOURCES = qvfb.cpp \ qanimationwriter.cpp \ qvfbprotocol.cpp \ qvfbshmem.cpp \ - qvfbmmap.cpp + qvfbmmap.cpp \ + ../../src/gui/embedded/qlock.cpp \ + ../../src/gui/embedded/qwslock.cpp \ + ../../src/gui/embedded/qwssignalhandler.cpp !embedded { DEFINES += QT_NO_QWS_SIGNALHANDLER diff --git a/tools/runonphone/codasignalhandler.cpp b/tools/runonphone/codasignalhandler.cpp index 0d086b5..2de6fbc 100644 --- a/tools/runonphone/codasignalhandler.cpp +++ b/tools/runonphone/codasignalhandler.cpp @@ -46,6 +46,7 @@ #include <QObject> #include <QTimer> #include "codasignalhandler.h" +#include "texttracehandler.h" static const quint64 DEFAULT_CHUNK_SIZE = 40000; @@ -168,11 +169,14 @@ int CodaSignalHandler::run() QString deviceError = "No such port"; if (d->codaDevice) deviceError = d->codaDevice->device()->errorString(); - reportError(tr("Could not open serial device: ").arg(deviceError)); + reportError(tr("Could not open serial device: %1").arg(deviceError)); SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(d->codaDevice); return 1; } + TextTraceHandler *traceHandler = new TextTraceHandler( + SymbianUtils::SymbianDeviceManager::instance()->getOstChannel(d->serialPortName, 2), this); + if (d->loglevel > 1) { d->codaDevice->setVerbose(1); } @@ -190,6 +194,8 @@ int CodaSignalHandler::run() d->eventLoop->exec(); int result = d->result; reportMessage(tr("Done.")); + + delete traceHandler; disconnect(d->codaDevice.data(), 0, this, 0); SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(d->codaDevice); diff --git a/tools/runonphone/runonphone.pro b/tools/runonphone/runonphone.pro index d006a05..3d6a995 100644 --- a/tools/runonphone/runonphone.pro +++ b/tools/runonphone/runonphone.pro @@ -9,13 +9,15 @@ include(symbianutils/symbianutils.pri) SOURCES += main.cpp \ trksignalhandler.cpp \ ossignalconverter.cpp \ - codasignalhandler.cpp + codasignalhandler.cpp \ + texttracehandler.cpp HEADERS += trksignalhandler.h \ serenum.h \ ossignalconverter.h \ ossignalconverter_p.h \ - codasignalhandler.h + codasignalhandler.h \ + texttracehandler.h DEFINES += SYMBIANUTILS_INCLUDE_PRI diff --git a/tools/runonphone/symbianutils/codadevice.cpp b/tools/runonphone/symbianutils/codadevice.cpp index 751f84e..f1f5db5 100644 --- a/tools/runonphone/symbianutils/codadevice.cpp +++ b/tools/runonphone/symbianutils/codadevice.cpp @@ -71,6 +71,7 @@ static const int maxSerialMessageLength = 0x10000; // given chunking scheme static const char validProtocolIdStart = (char)0x90; static const char validProtocolIdEnd = (char)0x95; static const char codaProtocolId = (char)0x92; +static const char textTraceProtocolId = (char)0x02; static const unsigned char serialChunkingStart = 0xfe; static const unsigned char serialChunkingContinuation = 0x0; enum { SerialChunkHeaderSize = 2 }; @@ -495,7 +496,9 @@ QPair<int, int> CodaDevice::findSerialHeader(QByteArray &in) // Good packet const int length = trk::extractShort(in.constData() + 2); return QPair<int, int>(4, length); - } else if (in.at(0) == header1 && in.at(1) >= validProtocolIdStart && in.at(1) <= validProtocolIdEnd) { + } else if (in.at(0) == header1 + && (in.at(1) == textTraceProtocolId + || (in.at(1) >= validProtocolIdStart && in.at(1) <= validProtocolIdEnd))) { // We recognise it but it's not a TCF message - emit it for any interested party to handle const int length = trk::extractShort(in.constData() + 2); if (4 + length <= in.size()) { diff --git a/tools/runonphone/symbianutils/symbiandevicemanager.cpp b/tools/runonphone/symbianutils/symbiandevicemanager.cpp index 23f5348..e8d0b5e 100644 --- a/tools/runonphone/symbianutils/symbiandevicemanager.cpp +++ b/tools/runonphone/symbianutils/symbiandevicemanager.cpp @@ -57,6 +57,7 @@ #include <QtCore/QThread> #include <QtCore/QWaitCondition> #include <QtCore/QTimer> +#include <QtCore/QDir> namespace SymbianUtils { @@ -622,6 +623,20 @@ SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::blueToothDevices() } } #endif +#if defined(Q_OS_MAC) + QDir dir("/dev"); + QStringList filters; + filters << "cu.usbmodem*"; + dir.setNameFilters(filters); + QStringList entries = dir.entryList(QDir::System, QDir::Name); + foreach (const QString &dev, entries) { + SymbianDeviceData *device = new SymbianDeviceData; + device->type = SerialPortCommunication; + device->portName = dir.filePath(dev); + device->friendlyName = tr("USB/Serial device (%1)").arg(device->portName); + rc.push_back(SymbianDevice(device)); + } +#endif return rc; } diff --git a/tools/runonphone/texttracehandler.cpp b/tools/runonphone/texttracehandler.cpp new file mode 100644 index 0000000..fff02e9 --- /dev/null +++ b/tools/runonphone/texttracehandler.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QTextStream> +#include "texttracehandler.h" +#include "trkutils.h" + +class TextTraceHandlerPrivate +{ +public: + TextTraceHandlerPrivate(); + ~TextTraceHandlerPrivate(); + QIODevice *device; + QTextStream out; +}; + +TextTraceHandlerPrivate::TextTraceHandlerPrivate() +: out(stdout) +{ +} + +TextTraceHandlerPrivate::~TextTraceHandlerPrivate() +{ + delete device; +} + +TextTraceHandler::TextTraceHandler(QIODevice *device, QObject *parent) +: QObject(parent) +{ + d = new TextTraceHandlerPrivate; + d->device = device; + connect(device, SIGNAL(readyRead()), this, SLOT(dataAvailable())); +} + +TextTraceHandler::~TextTraceHandler() +{ + delete d; +} + +void TextTraceHandler::dataAvailable() +{ + QByteArray result = d->device->readAll(); + quint64 secs = 0; + quint64 ns = 0; + if (result.length() >= 8) { + quint64 timestamp = trk::extractInt64(result.constData()) & 0x0FFFFFFFFFFFFFFFULL; + secs = timestamp / 1000000000; + ns = timestamp % 1000000000; + } + d->out << QString("[%1.%2] %3").arg(secs).arg(ns).arg(QString(result.mid(8))) << endl; +} diff --git a/tools/runonphone/texttracehandler.h b/tools/runonphone/texttracehandler.h new file mode 100644 index 0000000..2b9359c --- /dev/null +++ b/tools/runonphone/texttracehandler.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QObject> +#include <QIODevice> + +class TextTraceHandlerPrivate; +class TextTraceHandler : public QObject +{ + Q_OBJECT +public: + TextTraceHandler(QIODevice *device, QObject *parent = 0); + ~TextTraceHandler(); + +public slots: + void dataAvailable(); +private: + TextTraceHandlerPrivate *d; +}; |